Commit d14eada2 authored by guruhegde's avatar guruhegde

Fix issues with LoopSplitter

* Pass simple test case.
parent b387af83
......@@ -19,7 +19,7 @@ namespace tas {
void LoopSplitter::addAdapterBasicBlocks(Instruction * SP, Value * Idx) {
auto TopHalf = SP->getParent();
auto BottomHalf = TopHalf->splitBasicBlock(SP->getNextNode());
auto BottomHalf = TopHalf->splitBasicBlock(SP);
auto CollectBB = BasicBlock::Create(F->getContext(), "collector", F, BottomHalf);
auto DistBB = BasicBlock::Create(F->getContext(), "distributor", F, BottomHalf);
......@@ -37,7 +37,7 @@ void LoopSplitter::addAdapterBasicBlocks(Instruction * SP, Value * Idx) {
Builder.SetInsertPoint(DistBB);
auto IdxVal = Builder.CreateLoad(Idx);
auto IdxVal64 = Builder.CreateBitCast(IdxVal, Builder.getInt64Ty());
auto IdxVal64 = Builder.CreateSExtOrBitCast(IdxVal, Builder.getInt64Ty());
auto BrValPtr = Builder.CreateGEP(BrTgtArray, {Builder.getInt64(0), IdxVal64});
auto BrVal = Builder.CreateLoad(BrValPtr);
auto SwitchI = Builder.CreateSwitch(BrVal, BottomHalf);
......@@ -53,18 +53,23 @@ void LoopSplitter::addAdapterBasicBlocks(Instruction * SP, Value * Idx) {
auto Cond = TermI->getCondition();
Builder.SetInsertPoint(TermI);
auto TgtBB = TermI->getSuccessor(1);
auto TgtBBVal = BBToId[TgtBB];
auto IdxVal64 = Builder.CreateBitCast(IdxVal, Builder.getInt64Ty());
auto FalseBB = TermI->getSuccessor(1);
auto TgtBBVal = Builder.CreateSelect(Cond,
BBToId[TermI->getSuccessor(0)],
BBToId[FalseBB]);
auto IdxVal = Builder.CreateLoad(Idx);
auto IdxVal64 = Builder.CreateSExtOrBitCast(IdxVal, Builder.getInt64Ty());
auto BrValPtr = Builder.CreateGEP(BrTgtArray, {Builder.getInt64(0), IdxVal64});
Builder.CreateStore(TgtBBVal, BrValPtr);
TermI->setSuccessor(1, CollectBB);
SwitchI->addCase(TgtBBVal, TgtBB);
SwitchI->addCase(BBToId[FalseBB], FalseBB);
}
}
bool LoopSplitter::prepareForLoopSplit(Function *F, Stats & stat, Value * Idx) {
bool LoopSplitter::prepareForLoopSplit(Function *F, Loop * L0, Stats & stat) {
auto Idx = getLoopIndexVar(L0);
auto AnnotatedVars = detectExpPtrVars(F);
auto VarUsePoints = detectExpPtrUses(AnnotatedVars);
......@@ -76,12 +81,12 @@ bool LoopSplitter::prepareForLoopSplit(Function *F, Stats & stat, Value * Idx) {
BBToId.insert(std::make_pair(&BB, Builder.getInt32(++i)));
});
for_each(VarUsePoints,
[&] (auto & VarUse) { addAdapterBasicBlocks(VarUse, Idx); });
for_each(VarUsePoints,
[&] (auto & VarUse) { insertLLVMPrefetchIntrinsic(F, VarUse); });
for_each(VarUsePoints,
[&] (auto & VarUse) { addAdapterBasicBlocks(VarUse, Idx); });
stat.AnnotatedVarsSize = AnnotatedVars.size();
stat.VarUsePointsSize = VarUsePoints.size();
return VarUsePoints.size() != 0;
......@@ -93,9 +98,8 @@ Value * getLoopTripCount(Loop * L0) {
return cast<LoadInst>(cast<ICmpInst>(Cond)->getOperand(1))->getOperand(0);
}
void doLoopSplit(Function * F, Loop * L0, BasicBlock * SplitBlock) {
void LoopSplitter::doLoopSplit(Function * F, Loop * L0, BasicBlock * SplitBlock) {
auto OldHeader = L0->getHeader();
auto ExitBlock = OldHeader->getTerminator()->getSuccessor(1);
auto DistBB = SplitBlock->getUniqueSuccessor();
BasicBlock * EntryBlock = nullptr;
......@@ -104,13 +108,13 @@ void doLoopSplit(Function * F, Loop * L0, BasicBlock * SplitBlock) {
EntryBlock = BB;
}
auto OldPreHeader = BasicBlock::Create(F->getContext(), "oldpreheader", F);
auto NewPreHeader = BasicBlock::Create(F->getContext(), "preheader", F);
auto NewHeader = BasicBlock::Create(F->getContext(), "header", F);
auto NewLatch = BasicBlock::Create(F->getContext(), "latch", F);
auto IndexVar = getLoopIndexVar(L0);
auto TripCount = cast<AllocaInst>(getLoopTripCount(L0));
errs() << *IndexVar << " " << *TripCount << "\n";
IRBuilder<> Builder(NewPreHeader);
Builder.CreateStore(Builder.getInt32(0), IndexVar);
......@@ -126,12 +130,17 @@ void doLoopSplit(Function * F, Loop * L0, BasicBlock * SplitBlock) {
auto * icmp = Builder.CreateICmpSLT(IndexVarVal, TripCountVal,
"loop-predicate");
auto NewEntryBB = cast<BranchInst>(OldHeader->getTerminator())->getSuccessor(0);
Builder.CreateCondBr(icmp, NewEntryBB, L0->getHeader());
Builder.CreateCondBr(icmp, NewEntryBB, OldPreHeader);
SplitBlock->getTerminator()->setSuccessor(0, NewLatch);
OldHeader->getTerminator()->setSuccessor(0, DistBB);
OldHeader->getTerminator()->setSuccessor(1, ExitBlock);
setSuccessor(EntryBlock, NewPreHeader);
Builder.SetInsertPoint(OldPreHeader);
errs() << *IndexVar << "\n";
Builder.CreateStore(Builder.getInt32(0), IndexVar);
Builder.CreateBr(OldHeader);
}
bool LoopSplitter::run() {
......@@ -140,15 +149,15 @@ bool LoopSplitter::run() {
// XXX Assume only one loop for now.
auto L0 = *LI->begin();
auto IndexVar = getLoopIndexVar(L0);
bool changed = prepareForLoopSplit(F, stat, IndexVar);
ExitBlock = L0->getExitBlock();
assert (ExitBlock && "Loop must have a single exit block!");
bool changed = prepareForLoopSplit(F, L0, stat);
if (!changed) return false;
auto & SplitBB = LoopSplitEdgeBlocks.front();
//doLoopSplit(F, L0, SplitBB);
F->print(errs());
doLoopSplit(F, L0, SplitBB);
return true;
}
......
......@@ -35,16 +35,18 @@ class LoopSplitter {
llvm::LoopInfo * LI;
Stats stat;
llvm::BasicBlock * ExitBlock;
llvm::DenseMap<const llvm::BasicBlock *, llvm::ConstantInt *> BBToId;
llvm::SmallVector<llvm::BasicBlock *, 4> LoopSplitEdgeBlocks;
bool prepareForLoopSplit(llvm::Function * F, Stats & stat, llvm::Value * Idx);
public:
bool prepareForLoopSplit(llvm::Function * F, llvm::Loop * L0, Stats & stat);
public:
LoopSplitter(llvm::Function * F_, llvm::LoopInfo * LI_)
: F(F_), LI(LI_) {}
bool run();
Stats & getStats() { return stat; }
void addAdapterBasicBlocks(llvm::Instruction * SP, llvm::Value * Idx);
void doLoopSplit(llvm::Function * F, llvm::Loop * L0, llvm::BasicBlock * SplitBlock);
};
} // tas namespace
......
......@@ -32,7 +32,6 @@ string generateIR(string InFile, string Input_dir, bool isTas = false) {
string GenerateIRCmd = string("clang ") + tags + string("-o") +
Input_dir + OutFile + " " + Input_dir + InFile;
cout << GenerateIRCmd << "\n";
auto ret = system(GenerateIRCmd.c_str());
if (ret != 0) {
cerr << "clang:IR generation failed with error code " << ret << "\n";
......
#include <stdlib.h>
#include <stdio.h>
#define EXPENSIVE __attribute__((annotate("expensive")))
......@@ -32,7 +33,8 @@ int main() {
int * in = (int *) malloc(sizeof(int) * N);
int * ref_in = (int *) malloc(sizeof(int) * N);
int ret = fn(in, N);
if (ret != fn_ref(ref_in, N))
int ret_ref = fn_ref(ref_in, N);
if (ret != ret_ref)
rc--;
free(in);
......
......@@ -64,4 +64,15 @@ TEST_CASE("fn with single loop") {
auto Stats = LS.getStats();
REQUIRE(Stats.AnnotatedVarsSize == 1);
REQUIRE(Stats.VarUsePointsSize == 1);
//F->print(errs());
auto asmFile = writeToAsmFile(*M);
auto TestObject = generateObject(asmFile);
auto binary = linkObjects(vector<string>{TestObject}, string("loopSplitter_test11"));
// Run the binary
binary.insert(0, "./");
auto ret = system(binary.c_str());
REQUIRE(ret == 0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment