void SparseSolver::Print(Function &F, raw_ostream &OS) const { OS << "\nFUNCTION: " << F.getName() << "\n"; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { if (!BBExecutable.count(BB)) OS << "INFEASIBLE: "; OS << "\t"; if (BB->hasName()) OS << BB->getName() << ":\n"; else OS << "; anon bb\n"; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { LatticeFunc->PrintValue(getLatticeState(I), OS); OS << *I << "\n"; } OS << "\n"; } }
bool mssa::runOnFunction(Function &F) { MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA(); //MemorySSAWalker MAW = new MemorySSAWalker(MSSA); errs()<<"\n"; for (Function::iterator BB = F.begin(); BB != F.end(); BB++){ errs() << "Basic block (name=" << BB->getName() << ")\n"; //Get MemoryPhi and print it out MemoryPhi* MP = MSSA->getMemoryAccess(dyn_cast<BasicBlock>(BB)); if (MP != NULL) MP->dump(); for (BasicBlock::iterator itrIns = (*BB).begin(); itrIns != (*BB).end(); itrIns++) { //MemoryAccess* MA = MAW.getClobberingMemoryAccess(itrIns); //MemoryLocation Location; //MemoryAccess* MAR = MAW.getClobberingMemoryAccess(MA,&Location); //MAR->dump(); errs()<<"Instruction: "<< *itrIns <<"\n"; //Get MemoryDef or MemoryUse and print it out MemoryAccess *MA = MSSA->getMemoryAccess(dyn_cast<Value>(itrIns)); if (MA != NULL) { MA->dump(); //if(MSSA->isLiveOnEntryDef(MA)) //Get immediate MemoryDef of the instruction annotated MemoryDef/MemoryUse for (memoryaccess_def_iterator MAitr = MA->defs_begin(); MAitr != MA->defs_end(); MAitr++) { errs()<<"Def: "<<**MAitr<<"\n"; //Get the instruction the immediate Memory Def annotation represent Instruction* u = cast<MemoryUseOrDef>(*MAitr)->getMemoryInst(); if (u != NULL) errs()<<" Def Inst: "<<*u<<"\n"; } } } } return 0; }
bool TraceBasicBlocks::runOnModule(Module &M) { Context =&M.getContext(); Function *Main = M.getFunction("main"); if (Main == 0) { errs() << "WARNING: cannot insert basic-block trace instrumentation" << " into a module with no main function!\n"; return false; // No main, no instrumentation! } const char* FnName="llvm_trace_basic_block"; Constant *InstrFn = M.getOrInsertFunction (FnName, Type::getVoidTy(*Context), Type::getInt64Ty(*Context), NULL); unsigned BBNumber = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if(F->empty()) { continue; } //We insert instrumentation calls in reverse order, because insertion puts them before previous instructions for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { dbgs() << "InsertInstrumentationCall (\"" << BB->getName () << "\", \"" << F->getName() << "\", " << BBNumber << ")\n"; //On Exit we emit the FunRet block TerminatorInst* TI=BB->getTerminator(); if(TI->getNumSuccessors()==0) { InsertRetInstrumentationCall(TI,InstrFn); } InsertInstrumentationCall (BB, InstrFn, BBNumber); if(TraceMemory) { InsertMemoryTracingCall (BB,InstrFn); } ++BBNumber; } //on Entry we emit the FunCall block. BasicBlock* EntryBlock=&F->getEntryBlock(); InsertInstrumentationCall (EntryBlock, InstrFn, BBTraceStream::FunCallID); } // Add the initialization call to main. InsertProfilingInitCall(Main, "llvm_start_basic_block_tracing"); return true; }
void RocketShip::processFunction(Function &F) { // Everything is reset per function. Ideally we would just make // this a per-function pass, but extended feature plans make // applying this at the module level a better idea. _nodeId = 0; _blockId = 0; _blocks.clear(); _pnodes.clear(); std::vector<BasicBlock*> blockList; std::string functionLabel = F.getName(); std::string demangledLabel = getDemangledName(functionLabel); if (demangledLabel == functionLabel || demangledLabel.length() == 0) { functionLabel = F.getReturnType()->getDescription() + " " + functionLabel; functionLabel = functionLabel + "("; for (Function::arg_iterator arg = F.arg_begin(); arg != F.arg_end(); arg++) { if (arg != F.arg_begin()) { functionLabel = functionLabel + ", "; } functionLabel = functionLabel + arg->getType()->getDescription() + " " + std::string(arg->getName()); } functionLabel = functionLabel + ")"; } else { functionLabel = demangledLabel; } // Each block in the function needs to be processed and added to // the mapping. for (Function::iterator bblock = F.begin(); bblock != F.end(); bblock++) { pBlock block(new Block(_nodeId++, bblock->getName())); _blocks.insert(std::pair<BasicBlock*, pBlock>(bblock, block)); blockList.push_back(bblock); if (bblock == F.begin()) { pNode node(new Node(_nodeId++)); block->appendNode(node); node->setNodeLabel(functionLabel); node->setNodeType(Node::START); } processBlock(bblock, block); } // Each block needs to process its contained nodes and we need to // keep a local copy of each node for later processing. for (std::map<BasicBlock*, pBlock>::iterator it = _blocks.begin(); it != _blocks.end(); it++) { it->second->processNodes(_blocks); Nodes nodes = it->second->getNodes(); for (Nodes::iterator node = nodes.begin(); node != nodes.end(); node++) { _pnodes.push_back(*node); } } // Generates the function name and filename/output stream. std::string functionIdentifier = F.getName(); char* result = cplus_demangle(functionIdentifier.c_str(), DMGL_ANSI|DMGL_PARAMS); std::replace(functionIdentifier.begin(), functionIdentifier.end(), '.', '_'); _outputFile.open(std::string(functionIdentifier + ".dot").c_str()); _outputFile << "digraph " << functionIdentifier << " {\n"; // Emit each node to the output stream. This should be modified // to have the node print itself out by passing in the output // stream rather than calling a separate function for (Nodes::iterator it = _pnodes.begin(); it != _pnodes.end(); it++) { if ((*it) == NULL) { continue; } // We only care about nodes with labels since they are what is // actually presented. if ((*it)->getNodeLabel().length() > 0) { emitNode(&(*(*it))); } } _outputFile << "}"; _outputFile.close(); }
TEST(LoopInfoTest, PreorderTraversals) { const char *ModuleStr = "define void @f() {\n" "entry:\n" " br label %loop.0\n" "loop.0:\n" " br i1 undef, label %loop.0.0, label %loop.1\n" "loop.0.0:\n" " br i1 undef, label %loop.0.0, label %loop.0.1\n" "loop.0.1:\n" " br i1 undef, label %loop.0.1, label %loop.0.2\n" "loop.0.2:\n" " br i1 undef, label %loop.0.2, label %loop.0\n" "loop.1:\n" " br i1 undef, label %loop.1.0, label %end\n" "loop.1.0:\n" " br i1 undef, label %loop.1.0, label %loop.1.1\n" "loop.1.1:\n" " br i1 undef, label %loop.1.1, label %loop.1.2\n" "loop.1.2:\n" " br i1 undef, label %loop.1.2, label %loop.1\n" "end:\n" " ret void\n" "}\n"; // Parse the module. LLVMContext Context; std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr); Function &F = *M->begin(); DominatorTree DT(F); LoopInfo LI; LI.analyze(DT); Function::iterator I = F.begin(); ASSERT_EQ("entry", I->getName()); ++I; Loop &L_0 = *LI.getLoopFor(&*I++); ASSERT_EQ("loop.0", L_0.getHeader()->getName()); Loop &L_0_0 = *LI.getLoopFor(&*I++); ASSERT_EQ("loop.0.0", L_0_0.getHeader()->getName()); Loop &L_0_1 = *LI.getLoopFor(&*I++); ASSERT_EQ("loop.0.1", L_0_1.getHeader()->getName()); Loop &L_0_2 = *LI.getLoopFor(&*I++); ASSERT_EQ("loop.0.2", L_0_2.getHeader()->getName()); Loop &L_1 = *LI.getLoopFor(&*I++); ASSERT_EQ("loop.1", L_1.getHeader()->getName()); Loop &L_1_0 = *LI.getLoopFor(&*I++); ASSERT_EQ("loop.1.0", L_1_0.getHeader()->getName()); Loop &L_1_1 = *LI.getLoopFor(&*I++); ASSERT_EQ("loop.1.1", L_1_1.getHeader()->getName()); Loop &L_1_2 = *LI.getLoopFor(&*I++); ASSERT_EQ("loop.1.2", L_1_2.getHeader()->getName()); auto Preorder = LI.getLoopsInPreorder(); ASSERT_EQ(8u, Preorder.size()); EXPECT_EQ(&L_0, Preorder[0]); EXPECT_EQ(&L_0_0, Preorder[1]); EXPECT_EQ(&L_0_1, Preorder[2]); EXPECT_EQ(&L_0_2, Preorder[3]); EXPECT_EQ(&L_1, Preorder[4]); EXPECT_EQ(&L_1_0, Preorder[5]); EXPECT_EQ(&L_1_1, Preorder[6]); EXPECT_EQ(&L_1_2, Preorder[7]); auto ReverseSiblingPreorder = LI.getLoopsInReverseSiblingPreorder(); ASSERT_EQ(8u, ReverseSiblingPreorder.size()); EXPECT_EQ(&L_1, ReverseSiblingPreorder[0]); EXPECT_EQ(&L_1_2, ReverseSiblingPreorder[1]); EXPECT_EQ(&L_1_1, ReverseSiblingPreorder[2]); EXPECT_EQ(&L_1_0, ReverseSiblingPreorder[3]); EXPECT_EQ(&L_0, ReverseSiblingPreorder[4]); EXPECT_EQ(&L_0_2, ReverseSiblingPreorder[5]); EXPECT_EQ(&L_0_1, ReverseSiblingPreorder[6]); EXPECT_EQ(&L_0_0, ReverseSiblingPreorder[7]); }
// Note: branch conditions, by definition, only have a chain user. // This is why it should not be saved in a map for recall. Value* ARMIREmitter::visitBRCOND(const SDNode *N) { // Get the address const ConstantSDNode *DestNode = dyn_cast<ConstantSDNode>(N->getOperand(0)); if (!DestNode) { printError("visitBRCOND: Not a constant integer for branch!"); return NULL; } uint64_t DestInt = DestNode->getSExtValue(); uint64_t PC = Dec->getDisassembler()->getDebugOffset(N->getDebugLoc()); // Note: pipeline is 8 bytes uint64_t Tgt = PC + 8 + DestInt; Function *F = IRB->GetInsertBlock()->getParent(); BasicBlock *CurBB = IRB->GetInsertBlock(); BasicBlock *BBTgt = Dec->getOrCreateBasicBlock(Tgt, F); // Parse the branch condition code const ConstantSDNode *CCNode = dyn_cast<ConstantSDNode>(N->getOperand(1)); if (!CCNode) { printError("visitBRCOND: Condition code is not a constant integer!"); return NULL; } ARMCC::CondCodes ARMcc = ARMCC::CondCodes(CCNode->getZExtValue()); // Unconditional branch if (ARMcc == ARMCC::AL) { Instruction *Br = IRB->CreateBr(BBTgt); Br->setDebugLoc(N->getDebugLoc()); return Br; } // If not a conditional branch, find the successor block and look at CC BasicBlock *NextBB = NULL; Function::iterator BI = F->begin(), BE= F->end(); while (BI != BE && BI->getName() != CurBB->getName()) ++BI; ++BI; if (BI == BE) { // NOTE: This should never happen... NextBB = Dec->getOrCreateBasicBlock("end", F); } else { NextBB = &(*BI); } SDNode *CPSR = N->getOperand(2)->getOperand(1).getNode(); SDNode *CMPNode = NULL; for (SDNode::use_iterator I = CPSR->use_begin(), E = CPSR->use_end(); I != E; ++I) { if (I->getOpcode() == ISD::CopyToReg) { CMPNode = I->getOperand(2).getNode(); } } if (CMPNode == NULL) { errs() << "ARMIREmitter ERROR: Could not find CMP SDNode for ARMBRCond!\n"; return NULL; } Value *Cmp = NULL; Value *LHS = visit(CMPNode->getOperand(0).getNode()); Value *RHS = visit(CMPNode->getOperand(1).getNode()); // See ARMCC::CondCodes IntCCToARMCC(ISD::CondCode CC); in ARMISelLowering.cpp // TODO: Add support for conditions that handle floating point switch(ARMcc) { default: printError("Unknown condition code"); return NULL; case ARMCC::EQ: Cmp = IRB->CreateICmpEQ(LHS, RHS); break; case ARMCC::NE: Cmp = IRB->CreateICmpNE(LHS, RHS); break; case ARMCC::HS: // HS - unsigned higher or same (or carry set) Cmp = IRB->CreateICmpUGE(LHS, RHS); break; case ARMCC::LO: // LO - unsigned lower (or carry clear) Cmp = IRB->CreateICmpULT(LHS, RHS); break; case ARMCC::MI: // MI - minus (negative) printError("Condition code MI is not handled at this time!"); return NULL; // break; case ARMCC::PL: // PL - plus (positive or zero) printError("Condition code PL is not handled at this time!"); return NULL; // break; case ARMCC::VS: // VS - V Set (signed overflow) printError("Condition code VS is not handled at this time!"); return NULL; // break; case ARMCC::VC: // VC - V clear (no signed overflow) printError("Condition code VC is not handled at this time!"); return NULL; // break; case ARMCC::HI: // HI - unsigned higher Cmp = IRB->CreateICmpUGT(LHS, RHS); break; case ARMCC::LS: // LS - unsigned lower or same Cmp = IRB->CreateICmpULE(LHS, RHS); break; case ARMCC::GE: // GE - signed greater or equal Cmp = IRB->CreateICmpSGE(LHS, RHS); break; case ARMCC::LT: // LT - signed less than Cmp = IRB->CreateICmpSLT(LHS, RHS); break; case ARMCC::GT: // GT - signed greater than Cmp = IRB->CreateICmpSGT(LHS, RHS); break; case ARMCC::LE: // LE - signed less than or equal Cmp = IRB->CreateICmpSLE(LHS, RHS); break; } (dyn_cast<Instruction>(Cmp))->setDebugLoc(N->getOperand(2)->getDebugLoc()); // Conditional branch Instruction *Br = IRB->CreateCondBr(Cmp, BBTgt, NextBB); Br->setDebugLoc(N->getDebugLoc()); return Br; }
int runOnEachFunctions(Function &F) { functionCount++; if(functionCount>1) return -1; for (Function::iterator b = F.begin(), be = F.end(); b != be; ++b) { { errs()<<"\n"<<b->getName()<<"\n"; runOnEachBlocks(b); } } Function::iterator tempBB=F.begin(); LatticeSize=exprsnNo; //errs()<<"\nLatticeSize="<<LatticeSize; //Function::iterator b = F.begin(); //errs()<<"Result = "<<transferFunction(b,0); /**************************************** *** creating the control flow graph *** ****************************************/ errs()<<"\nBasic block = "<<blockCount<<"\n"; Function::iterator temp2 = F.begin(); Function::iterator basicBlockList[blockCount]; BasicBlock* tempbb = dyn_cast<BasicBlock>(&*temp2); succ_iterator successor_begin_array[MAXBB]=succ_begin(tempbb); succ_iterator successor_end_array[MAXBB]=succ_begin(tempbb); /************************************** *** Finding Succ and pred of each *** *** basic blocks *** **************************************/ int bblockno=0; for (Function::iterator b = F.begin(), be = F.end(); b != be; ++b) //no of blocks CFG succ gen { basicBlockList[bblockno]=b; BasicBlock* bb = dyn_cast<BasicBlock>(&*b); successor_begin_array[bblockno] = succ_begin(bb); successor_end_array[bblockno] = succ_end(bb); bblockno++; } /*int** ary = new int*[rowCount]; for(int i = 0; i < rowCount; ++i) ary[i] = new int[colCount];*/ /************************************** *** Initialize Control flow graph *** **************************************/ int cfg_graph_visited[blockCount]; int cfg_rep[blockCount][blockCount]; for(int fori=0;fori<blockCount;fori++) { cfg_graph_visited[fori]=0; for(int forj=0;forj<blockCount;forj++) cfg_rep[fori][forj]=0; } int index1=0; while(index1<blockCount) { cfg_graph_visited[index1]=1; loopy: if(successor_begin_array[index1]==successor_end_array[index1]) { index1++; continue; } else { BasicBlock *TheSucc = *successor_begin_array[index1]; for(int index2=0; index2<blockCount;index2++) { BasicBlock* bb = dyn_cast<BasicBlock>(&*basicBlockList[index2]); if(TheSucc == bb) cfg_rep[index1][index2]=1; } ++successor_begin_array[index1]; goto loopy; } index1++; } for(int index1=0;index1<blockCount;index1++) { errs()<<"\n"<<index1<<" "<<basicBlockList[index1]->getName()<<"\n"; } /************************************** *** Printing the Control Flow *** **************************************/ errs()<<"\n CFG \n"; for(int index1=0;index1<blockCount;index1++) { for(int index2=0;index2<blockCount;index2++) errs()<<cfg_rep[index1][index2]<<" "; errs()<<"\n"; } unsigned long long int ch = (LatticeSize)*2*blockCount; errs()<<"\nValue of ch = "<<ch<<"\n"; int **final_graph; int **dist; final_graph = new int*[ch]; dist = new int*[ch]; for (int i = 0; i < ch; i++){ final_graph[i] = new int[ch]; dist[i]=new int[ch]; } for(long long int fori=0;fori<ch;fori++) for(long long int forj=0;forj<ch;forj++) { if(fori!=forj) final_graph[fori][forj]=INF; else final_graph[fori][forj]=0; } for(int bbNum=0;bbNum<blockCount;bbNum++) { for(unsigned long long int latticeNum=0;latticeNum<LatticeSize;latticeNum++) { errs()<<"\nBBNUM "<<bbNum<<" lattice "<<latticeNum; unsigned long long int result=transferFunction(basicBlockList[bbNum],latticeNum); errs()<<" result "<<result; unsigned long long int start=(bbNum*2*LatticeSize)+latticeNum; unsigned long long int end=(bbNum*2*LatticeSize)+LatticeSize+result; //if(start==8 && end==12) errs()<<" bb no "<<bbNum<<" "<<latticeNum<<" "<<result<<" "<<start<<" "<<end; final_graph[start][end]=1; } for(int rbbNum=0;rbbNum<blockCount;rbbNum++) { if(cfg_rep[bbNum][rbbNum]==1) { for(int latticeNum=0;latticeNum<LatticeSize;latticeNum++) { unsigned long long int start=(bbNum*2*LatticeSize)+LatticeSize+latticeNum; unsigned long long int end=(rbbNum*2*LatticeSize)+latticeNum; final_graph[start][end]=1; } } } } /************* printing matrix to file *****************/ /* PPPPPPPPPPPPP errs()<<ch; ofstream myfile; myfile.open ("example.txt"); errs()<<"\n\n\n"; for(long long int fori=0;fori<ch;fori++){ for(long long int forj=0;forj<ch;forj++) { if(final_graph[fori][forj]>10) myfile<<0<<" "; else myfile<<final_graph[fori][forj]<<" "; } myfile<<"\n"; } myfile.close(); /************* printing matrix to file *****************/ floydWarshell(final_graph,dist,ch); unsigned long long int out[blockCount]; for(int bbNum=0;bbNum<blockCount;bbNum++) { unsigned long long int res=0; for(unsigned long long int latticeNum=0;latticeNum<LatticeSize;latticeNum++) { unsigned long long int start=LatticeSize+(2*bbNum*LatticeSize)+latticeNum; if(dist[0][start]<INF) { //errs()<<"\nOK "<<bbNum<<" start="<<start<<" latt="<<latticeNum; if(res==0) res=latticeNum; else res=res & latticeNum; } } errs()<<"\n\n"<<bbNum<<" "<<basicBlockList[bbNum]->getName()<<"\n"; errs()<<" res = "<<res; out[bbNum]=res; } unsigned long long int in[blockCount]; unsigned long long int zero=0; errs()<<"Available Expressions Per Block"; for(int bbNum=0;bbNum<blockCount;bbNum++) { in[bbNum]=0; for(int bbNum2=0;bbNum2<blockCount;bbNum2++) { if(cfg_rep[bbNum2][bbNum]==1) { if(in[bbNum]==0) in[bbNum]=out[bbNum2]; else in[bbNum] = in[bbNum] & out[bbNum2]; } } errs()<<"\n\n"<<bbNum<<" "<<basicBlockList[bbNum]->getName()<<" "<<in[bbNum]; } return 0; }
bool ProfileTimingPrint::runOnModule(Module &M) { ProfileInfo& PI = getAnalysis<ProfileInfo>(); double AbsoluteTiming = 0.0, BlockTiming = 0.0, MpiTiming = 0.0, CallTiming = 0.0; for(TimingSource* S : Sources){ if (isa<BBlockTiming>(S) && BlockTiming < DBL_EPSILON) { // BlockTiming is Zero auto BT = cast<BBlockTiming>(S); for(Module::iterator F = M.begin(), FE = M.end(); F != FE; ++F){ if(Ignore.count(F->getName())) continue; #ifndef NDEBUG double FuncTiming = 0.; size_t MaxTimes = 0; double MaxCount = 0.; double MaxProd = 0.; StringRef MaxName; for(Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB){ size_t exec_times = PI.getExecutionCount(BB); double exec_count = BT->count(*BB); double timing = exec_times * exec_count; if(timing > MaxProd){ MaxProd = timing; MaxCount = exec_count; MaxTimes = exec_times; MaxName = BB->getName(); } FuncTiming += timing; // 基本块频率×基本块时间 } if (TimingDebug) outs() << FuncTiming << "\t" << "max=" << MaxTimes << "*" << MaxCount << "\t" << MaxName << "\t" << F->getName() << "\n"; BlockTiming += FuncTiming; #else for(Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB){ BlockTiming += PI.getExecutionCount(BB) * S->count(*BB); } #endif } } if(isa<MPITiming>(S) && MpiTiming < DBL_EPSILON){ // MpiTiming is Zero auto MT = cast<MPITiming>(S); auto S = PI.getAllTrapedValues(MPIFullInfo); auto U = PI.getAllTrapedValues(MPInfo); if(U.size()>0) outs()<<"Notice: Old Mpi Profiling Format\n"; S.insert(S.end(), U.begin(), U.end()); for(auto I : S){ const CallInst* CI = cast<CallInst>(I); const BasicBlock* BB = CI->getParent(); if(Ignore.count(BB->getParent()->getName())) continue; double timing = MT->count(*I, PI.getExecutionCount(BB), PI.getExecutionCount(CI)); // IO 模型 #ifndef NDEBUG if(TimingDebug) outs() << " " << PI.getTrapedIndex(I) << "\tBB:" << PI.getExecutionCount(BB) << "\tT:" << timing << "N:" << BB->getParent()->getName() << ":" << BB->getName() << "\n"; #endif MpiTiming += timing; } } if(isa<LibCallTiming>(S) && CallTiming < DBL_EPSILON){ auto CT = cast<LibCallTiming>(S); for(auto& F : M){ for(auto& BB : F){ for(auto& I : BB){ if(CallInst* CI = dyn_cast<CallInst>(&I)){ CallTiming += CT->count(*CI, PI.getExecutionCount(&BB)); } } } } } } AbsoluteTiming = BlockTiming + MpiTiming + CallTiming; outs()<<"Block Timing: "<<BlockTiming<<" ns\n"; outs()<<"MPI Timing: "<<MpiTiming<<" ns\n"; outs()<<"Call Timing: "<<CallTiming<<" ns\n"; outs()<<"Timing: "<<AbsoluteTiming<<" ns\n"; return false; }
Function* Decompiler::decompileFunction(unsigned Address) { // Check that Address is inside the current section. // TODO: Find a better way to do this check. What we really care about is // avoiding reads to library calls and areas of memory we can't "see". const object::SectionRef Sect = Dis->getCurrentSection(); uint64_t SectStart, SectEnd; Sect.getAddress(SectStart); Sect.getSize(SectEnd); SectEnd += SectStart; if (Address < SectStart || Address > SectEnd) { errs() << "Address out of bounds for section (is this a library call?): " << format("%1" PRIx64, Address) << "\n"; return NULL; } MachineFunction *MF = Dis->disassemble(Address); // Get Function Name // TODO: Determine Function Type FunctionType *FType = FunctionType::get(Type::getPrimitiveType(*Context, Type::VoidTyID), false); Function *F = cast<Function>(Mod->getOrInsertFunction(MF->getName(), FType)); if (!F->empty()) { return F; } // Create a basic block to hold entry point (alloca) information BasicBlock *entry = getOrCreateBasicBlock("entry", F); // For each basic block MachineFunction::iterator BI = MF->begin(), BE = MF->end(); while (BI != BE) { // Add branch from "entry" if (BI == MF->begin()) { entry->getInstList().push_back( BranchInst::Create(getOrCreateBasicBlock(BI->getName(), F))); } else { getOrCreateBasicBlock(BI->getName(), F); } ++BI; } BI = MF->begin(); while (BI != BE) { if (decompileBasicBlock(BI, F) == NULL) { printError("Unable to decompile basic block!"); } ++BI; } // During Decompilation, did any "in-between" basic blocks get created? // Nothing ever splits the entry block, so we skip it. for (Function::iterator I = ++F->begin(), E = F->end(); I != E; ++I) { if (!(I->empty())) { continue; } // Right now, the only way to get the right offset is to parse its name // it sucks, but it works. StringRef Name = I->getName(); if (Name == "end" || Name == "entry") continue; // these can be empty size_t Off = F->getName().size() + 1; size_t Size = Name.size() - Off; StringRef BBAddrStr = Name.substr(Off, Size); unsigned long long BBAddr; getAsUnsignedInteger(BBAddrStr, 10, BBAddr); BBAddr += Address; DEBUG(errs() << "Split Target: " << Name << "\t Address: " << BBAddr << "\n"); // split Block at AddrStr Function::iterator SB; // Split basic block BasicBlock::iterator SI, SE; // Split instruction // Note the ++, nothing ever splits the entry block. for (SB = ++F->begin(); SB != E; ++SB) { DEBUG(outs() << "SB: " << SB->getName() << "\tRange: " << Dis->getDebugOffset(SB->begin()->getDebugLoc()) << " " << Dis->getDebugOffset(SB->getTerminator()->getDebugLoc()) << "\n"); if (SB->empty() || BBAddr < getBasicBlockAddress(SB) || BBAddr > Dis->getDebugOffset(SB->getTerminator()->getDebugLoc())) { continue; } // Reorder instructions based on Debug Location sortBasicBlock(SB); DEBUG(errs() << "Found Split Block: " << SB->getName() << "\n"); // Find iterator to split on. for (SI = SB->begin(), SE = SB->end(); SI != SE; ++SI) { // outs() << "SI: " << SI->getDebugLoc().getLine() << "\n"; if (Dis->getDebugOffset(SI->getDebugLoc()) == BBAddr) break; if (Dis->getDebugOffset(SI->getDebugLoc()) > BBAddr) { errs() << "Could not find address inside basic block!\n" << "SI: " << Dis->getDebugOffset(SI->getDebugLoc()) << "\n" << "BBAddr: " << BBAddr << "\n"; break; } } break; } if (!SB || SI == SE || SB == E) { errs() << "Decompiler: Failed to find instruction offset in function!\n"; continue; } // outs() << SB->getName() << " " << SI->getName() << "\n"; // outs() << "Creating Block..."; splitBasicBlockIntoBlock(SB, SI, I); } // Clean up unnecessary stores and loads FunctionPassManager FPM(Mod); // FPM.add(createPromoteMemoryToRegisterPass()); // See Scalar.h for more. FPM.add(createTypeRecoveryPass()); FPM.run(*F); return F; }
bool llvm::InputValues::runOnModule(Module& M) { module = &M; initializeWhiteList(); collectMainArguments(); int one=0; errs()<<"\n------------------------------------------------\n"; for(Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; Fit++){ for (Function::iterator BBit = Fit->begin(), BBend = Fit->end(); BBit != BBend; BBit++) { for (BasicBlock::iterator Iit = BBit->begin(), Iend = BBit->end(); Iit != Iend; Iit++) { if(one<2) { Value* V_in; //FIXME: Temporary assignment of the tainted source for testing... if(BBit->getName()=="BB_146") { // errs() << "Inside BB_0"; if(LoadInst *LI = dyn_cast<LoadInst>(Iit)) { // LI->dump(); V_in = LI->getPointerOperand(); errs() <<"\ntaint source " << LI->getName() << " "; errs() << V_in; insertInInputDepValues(V_in); //NumInputValues++; one++; } } } if (CallInst *CI = dyn_cast<CallInst>(Iit)) { if (isMarkedCallInst(CI)){ //Values returned by marked instructions insertInInputDepValues(CI); for(unsigned int i = 0; i < CI->getNumOperands(); i++){ if (CI->getOperand(i)->getType()->isPointerTy()){ //Arguments with pointer type of marked functions // insertInInputDepValues(CI->getOperand(i)); } } } } } } } errs()<<"\n------------------------------------------------\n"; NumInputValues = inputValues.size(); //We don't modify anything, so we must return false; return false; }
bool InstructionGraph::runOnFunction(Function &M) { errs()<<"ins grph "; // if the function dppcreated, then we skip if(M.hasFnAttribute(GENERATEDATTR)) return false; errs()<<"skip check"; Func = &M; ExternalInsNode = getOrInsertInstruction(0); //assert(!CallsExternalNode); //CallsExternalNode = new CallGraphNode(0); Root = ExternalInsNode; for(Function::iterator BB=M.begin(), BBE = M.end(); BB != BBE; ++BB) { TerminatorInst* curBBTerm = BB->getTerminator(); unsigned numSuc = curBBTerm->getNumSuccessors(); for(unsigned sucInd=0; sucInd < numSuc; sucInd++) { BasicBlock* curSuc = curBBTerm->getSuccessor(sucInd); std::vector<BasicBlock*>* curSucPredecessors; if(BasicBlock2Predecessors.find(curSuc)==BasicBlock2Predecessors.end()) { curSucPredecessors = new std::vector<BasicBlock*>(); BasicBlock2Predecessors[curSuc] = curSucPredecessors; } else curSucPredecessors = BasicBlock2Predecessors[curSuc]; curSucPredecessors->push_back(&(*BB)); } } PostDominatorTree* PDT = getAnalysisIfAvailable<PostDominatorTree>(); LoopInfo* LI = getAnalysisIfAvailable<LoopInfo>(); for (Function::iterator BB = M.begin(), BBE = M.end(); BB != BBE; ++BB) { BasicBlock* curBBPtr = &(*BB); std::vector<BasicBlock*>* earliestPred=0; if(BasicBlock2Predecessors.find(curBBPtr)==BasicBlock2Predecessors.end()) { assert (&(M.getEntryBlock()) == curBBPtr); } else { // now we shall search for the actual predicate instruction earliestPred = searchEarliestPredicate(curBBPtr, PDT, BasicBlock2Predecessors,LI); } /*errs()<<"bb:"<<BB->getName() << " has "<<" pred \n"; for(unsigned k = 0;k < earliestPred->size(); k++) { errs()<< earliestPred->at(k)->getName()<<"\n"; }*/ for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) { addToInstructionGraph(BI, earliestPred); } delete earliestPred; errs()<<BB->getName()<<"\t" <<ExternalInsNode->DependentInstructions.size()<<" root dep\n"; } // we should have all the node errs()<<InstructionMap.size()<< " instructions added as graph nodes\n"; return false; }
void WorklessInstrument::InstrumentWorkless0Or1Star(Module * pModule, Loop * pLoop, set<string> & setWorkingBlocks) { LoadInst * pLoad0 = NULL; LoadInst * pLoad1 = NULL; //BinaryOperator* pAdd = NULL; StoreInst * pStore = NULL; CallInst * pCall = NULL; Function * pMain = NULL; if(strMainName != "" ) { pMain = pModule->getFunction(strMainName.c_str()); } else { pMain = pModule->getFunction("main"); } for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) { if(BB->getName().equals("entry")) { CallInst * pCall; StoreInst * pStore; Instruction * II = BB->begin(); pCall = CallInst::Create(this->InitHooks, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet emptySet; pCall->setAttributes(emptySet); pCall = CallInst::Create(this->getenv, this->SAMPLE_RATE_ptr, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet AS; { SmallVector<AttributeSet, 4> Attrs; AttributeSet PAS; { AttrBuilder B; B.addAttribute(Attribute::NoUnwind); PAS = AttributeSet::get(pModule->getContext(), ~0U, B); } Attrs.push_back(PAS); AS = AttributeSet::get(pModule->getContext(), Attrs); } pCall->setAttributes(AS); pCall = CallInst::Create(this->function_atoi, pCall, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); { SmallVector<AttributeSet, 4> Attrs; AttributeSet PAS; { AttrBuilder B; B.addAttribute(Attribute::NoUnwind); B.addAttribute(Attribute::ReadOnly); PAS = AttributeSet::get(pModule->getContext(), ~0U, B); } Attrs.push_back(PAS); AS = AttributeSet::get(pModule->getContext(), Attrs); } pCall->setAttributes(AS); pStore = new StoreInst(pCall, this->SAMPLE_RATE, false, II); pStore->setAlignment(4); pCall = CallInst::Create(this->geo, pCall, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(emptySet); CastInst * pCast = CastInst::CreateIntegerCast(pCall, this->LongType, true, "", II); pStore = new StoreInst(pCast, this->CURRENT_SAMPLE, false, II); pStore->setAlignment(8); vector<Value *> vecParam; vecParam.push_back(this->Output_Format_String); vecParam.push_back(pCall); pCall = CallInst::Create(this->printf, vecParam, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(emptySet); break; } } for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) { for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) { if (isa<ReturnInst>(Ins) || isa<ResumeInst>(Ins)) { vector<Value*> vecParams; pLoad0 = new LoadInst(numIterations, "", false, Ins); pLoad0->setAlignment(8); vecParams.push_back(pLoad0); pLoad1 = new LoadInst(numInstances, "", false, Ins); pLoad1->setAlignment(8); vecParams.push_back(pLoad1); pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet aSet; pCall->setAttributes(aSet); vecParams.clear(); pLoad0 = new LoadInst(numIterations, "", false, Ins); pLoad0->setAlignment(8); vecParams.push_back(pLoad0); pLoad1 = new LoadInst(numWorkingIterations, "", false, Ins); pLoad1->setAlignment(8); vecParams.push_back(pLoad1); pCall = CallInst::Create(PrintWorkingRatio, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(aSet); } else if(isa<CallInst>(Ins) || isa<InvokeInst>(Ins)) { CallSite cs(Ins); Function * pCalled = cs.getCalledFunction(); if(pCalled == NULL) { continue; } if(pCalled->getName() == "exit" || pCalled->getName() == "_ZL9mysql_endi") { vector<Value*> vecParams; pLoad0 = new LoadInst(numIterations, "", false, Ins); pLoad0->setAlignment(8); vecParams.push_back(pLoad0); pLoad1 = new LoadInst(numInstances, "", false, Ins); pLoad1->setAlignment(8); vecParams.push_back(pLoad1); pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet aSet; pCall->setAttributes(aSet); vecParams.clear(); pLoad0 = new LoadInst(numIterations, "", false, Ins); pLoad0->setAlignment(8); vecParams.push_back(pLoad0); pLoad1 = new LoadInst(numWorkingIterations, "", false, Ins); pLoad1->setAlignment(8); vecParams.push_back(pLoad1); pCall = CallInst::Create(PrintWorkingRatio, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(aSet); } } } } Function * pFunction = pLoop->getHeader()->getParent(); BasicBlock * pEntry = &(pFunction->getEntryBlock()); AllocaInst * pAlloc = new AllocaInst(this->LongType, "bWorkingIteration.local", pEntry->getFirstInsertionPt()); vector<BasicBlock *> vecWorkingBlock; for(Function::iterator BB = pFunction->begin(); BB != pFunction->end(); ++ BB) { if(setWorkingBlocks.find(BB->getName()) != setWorkingBlocks.end() ) { vecWorkingBlock.push_back(BB); } } errs() << "working block number: " << vecWorkingBlock.size() << "\n"; BasicBlock * pHeader = pLoop->getHeader(); set<BasicBlock *> setExitBlock; CollectExitBlock(pLoop, setExitBlock); vector<BasicBlock *> vecAdded; CreateIfElseBlock(pLoop, vecAdded); ValueToValueMapTy VMap; set<BasicBlock *> setCloned; CloneInnerLoop(pLoop, vecAdded, VMap, setCloned); //BasicBlock * pPreHeader = vecAdded[0]; BasicBlock * pElseBody = vecAdded[1]; vector<BasicBlock *>::iterator itVecBegin = vecWorkingBlock.begin(); vector<BasicBlock *>::iterator itVecEnd = vecWorkingBlock.end(); for(; itVecBegin != itVecEnd; itVecBegin++ ) { BasicBlock * pClonedBlock = cast<BasicBlock>(VMap[*itVecBegin]); pStore = new StoreInst(this->ConstantLong1, pAlloc, false, pClonedBlock->getFirstInsertionPt()); pStore->setAlignment(8); pClonedBlock->dump(); } pStore = new StoreInst(this->ConstantLong0, pAlloc, false, pElseBody->getTerminator()); pStore->setAlignment(8); pLoad0 = new LoadInst(this->numIterations, "", false, pElseBody->getTerminator()); pLoad0->setAlignment(8); pLoad1 = new LoadInst(this->numWorkingIterations, "", false, pElseBody->getTerminator()); pLoad1->setAlignment(8); BasicBlock * pClonedHeader = cast<BasicBlock>(VMap[pHeader]); set<BasicBlock *> setPredBlocks; for(pred_iterator PI = pred_begin(pClonedHeader), E = pred_end(pClonedHeader); PI != E; ++PI) { setPredBlocks.insert(*PI); } BasicBlock::iterator itInsert = pClonedHeader->getFirstInsertionPt(); PHINode * pNewIterations = PHINode::Create(pLoad0->getType(), setPredBlocks.size(), "numIterations.2", itInsert); PHINode * pNewWorkingIterations = PHINode::Create(pLoad1->getType(), setPredBlocks.size(), "WorkingIterations.2", itInsert); BinaryOperator * pIterationAdd = BinaryOperator::Create(Instruction::Add, pNewIterations, this->ConstantLong1, "Iterations.add.2", itInsert); set<BasicBlock *>::iterator itSetBegin = setPredBlocks.begin(); set<BasicBlock *>::iterator itSetEnd = setPredBlocks.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { if((*itSetBegin) == pElseBody) { pNewIterations->addIncoming(pLoad0, pElseBody); } else { pNewIterations->addIncoming(pIterationAdd, *itSetBegin); } } pLoad0 = new LoadInst(pAlloc, "", false, itInsert); BinaryOperator * pWorkingAdd = BinaryOperator::Create(Instruction::Add, pNewWorkingIterations, pLoad0, "Working.add.2", itInsert); itSetBegin = setPredBlocks.begin(); itSetEnd = setPredBlocks.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { if((*itSetBegin) == pElseBody) { pNewWorkingIterations->addIncoming(pLoad1, pElseBody); } else { pNewWorkingIterations->addIncoming(pWorkingAdd, *itSetBegin); } } pStore = new StoreInst(this->ConstantLong0, pAlloc, false, itInsert); pStore->setAlignment(8); itSetBegin = setExitBlock.begin(); itSetEnd = setExitBlock.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { SmallVector<BasicBlock*, 8> LoopBlocks; for(pred_iterator PI = pred_begin(*itSetBegin), E = pred_end(*itSetBegin); PI != E; ++PI) { if(setCloned.find(*PI) != setCloned.end()) { LoopBlocks.push_back(*PI); } } BasicBlock * NewExitBB = SplitBlockPredecessors(*itSetBegin, LoopBlocks, ".WL.loopexit", this); pStore = new StoreInst(pIterationAdd, this->numIterations, false, NewExitBB->getFirstInsertionPt()); pStore->setAlignment(8); pStore = new StoreInst(pWorkingAdd, this->numWorkingIterations, false, NewExitBB->getFirstInsertionPt()); pStore->setAlignment(8); } //pFunction->dump(); DominatorTree * DT = &(getAnalysis<DominatorTree>(*pFunction)); vector<AllocaInst *> vecAlloc; vecAlloc.push_back(pAlloc); PromoteMemToReg(vecAlloc, *DT); pFunction->dump(); }
void WorklessInstrument::InstrumentWorkless0Star1(Module * pModule, Loop * pLoop) { Function * pMain = NULL; if(strMainName != "" ) { pMain = pModule->getFunction(strMainName.c_str()); } else { pMain = pModule->getFunction("main"); } LoadInst * pLoad; BinaryOperator* pAdd = NULL; StoreInst * pStore = NULL; for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) { if(BB->getName().equals("entry")) { CallInst * pCall; StoreInst * pStore; Instruction * II = BB->begin(); pCall = CallInst::Create(this->InitHooks, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet emptySet; pCall->setAttributes(emptySet); pCall = CallInst::Create(this->getenv, this->SAMPLE_RATE_ptr, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet AS; { SmallVector<AttributeSet, 4> Attrs; AttributeSet PAS; { AttrBuilder B; B.addAttribute(Attribute::NoUnwind); PAS = AttributeSet::get(pModule->getContext(), ~0U, B); } Attrs.push_back(PAS); AS = AttributeSet::get(pModule->getContext(), Attrs); } pCall->setAttributes(AS); pCall = CallInst::Create(this->function_atoi, pCall, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); { SmallVector<AttributeSet, 4> Attrs; AttributeSet PAS; { AttrBuilder B; B.addAttribute(Attribute::NoUnwind); B.addAttribute(Attribute::ReadOnly); PAS = AttributeSet::get(pModule->getContext(), ~0U, B); } Attrs.push_back(PAS); AS = AttributeSet::get(pModule->getContext(), Attrs); } pCall->setAttributes(AS); pStore = new StoreInst(pCall, this->SAMPLE_RATE, false, II); pStore->setAlignment(4); pCall = CallInst::Create(this->geo, pCall, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(emptySet); CastInst * pCast = CastInst::CreateIntegerCast(pCall, this->LongType, true, "", II); pStore = new StoreInst(pCast, this->CURRENT_SAMPLE, false, II); pStore->setAlignment(8); vector<Value *> vecParam; vecParam.push_back(this->Output_Format_String); vecParam.push_back(pCall); pCall = CallInst::Create(this->printf, vecParam, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(emptySet); break; } } for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) { for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) { if (isa<ReturnInst>(Ins) || isa<ResumeInst>(Ins)) { vector<Value*> vecParams; pLoad = new LoadInst(numIterations, "", false, Ins); pLoad->setAlignment(8); vecParams.push_back(pLoad); pLoad = new LoadInst(numInstances, "", false, Ins); pLoad->setAlignment(8); vecParams.push_back(pLoad); CallInst* pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet aSet; pCall->setAttributes(aSet); } else if(isa<CallInst>(Ins) || isa<InvokeInst>(Ins)) { CallSite cs(Ins); Function * pCalled = cs.getCalledFunction(); if(pCalled == NULL) { continue; } if(pCalled->getName() == "exit" || pCalled->getName() == "_ZL9mysql_endi") { vector<Value*> vecParams; pLoad = new LoadInst(numIterations, "", false, Ins); pLoad->setAlignment(8); vecParams.push_back(pLoad); pLoad = new LoadInst(numInstances, "", false, Ins); pLoad->setAlignment(8); vecParams.push_back(pLoad); CallInst* pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet aSet; pCall->setAttributes(aSet); } } } } BasicBlock * pHeader = pLoop->getHeader(); set<BasicBlock *> setExitBlock; CollectExitBlock(pLoop, setExitBlock); vector<BasicBlock *> vecAdded; CreateIfElseBlock(pLoop, vecAdded); ValueToValueMapTy VMap; set<BasicBlock *> setCloned; CloneInnerLoop(pLoop, vecAdded, VMap, setCloned); BasicBlock * pPreHeader = vecAdded[1]; pLoad = new LoadInst(this->numIterations, "", false, pPreHeader->getTerminator()); pLoad->setAlignment(8); BasicBlock * pClonedHeader = cast<BasicBlock>(VMap[pHeader]); set<BasicBlock *> setPredBlocks; for(pred_iterator PI = pred_begin(pClonedHeader), E = pred_end(pClonedHeader); PI != E; ++PI) { setPredBlocks.insert(*PI); } PHINode * pNew = PHINode::Create(pLoad->getType(), setPredBlocks.size(), "numIterations", pClonedHeader->getFirstInsertionPt()); pAdd = BinaryOperator::Create(Instruction::Add, pNew, this->ConstantLong1, "add", pClonedHeader->getFirstInsertionPt()); set<BasicBlock *>::iterator itSetBegin = setPredBlocks.begin(); set<BasicBlock *>::iterator itSetEnd = setPredBlocks.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { if((*itSetBegin) == pPreHeader) { pNew->addIncoming(pLoad, pPreHeader); } else { pNew->addIncoming(pAdd, *itSetBegin); } } itSetBegin = setExitBlock.begin(); itSetEnd = setExitBlock.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { SmallVector<BasicBlock*, 8> LoopBlocks; for(pred_iterator PI = pred_begin(*itSetBegin), E = pred_end(*itSetBegin); PI != E; ++PI) { if(setCloned.find(*PI) != setCloned.end()) { LoopBlocks.push_back(*PI); } } BasicBlock * NewExitBB = SplitBlockPredecessors(*itSetBegin, LoopBlocks, ".WL.loopexit", this); pStore = new StoreInst(pAdd, this->numIterations, false, NewExitBB->getFirstInsertionPt()); pStore->setAlignment(8); } pPreHeader->getParent()->dump(); }
bool partition::runOnLoop(Loop* L, LPPassManager &LPM) { errs() << "*************************** Loop encountered: ************************" << '\n' << L->getHeader()->getName() << '\n'; if (function->getName() != "main") return false; IntegerType* int32Ty = Type::getInt32Ty(*context); IntegerType* int64Ty = Type::getInt64Ty(*context); PointerType* voidPtrTy = Type::getInt8PtrTy(*context); FunctionType* funcTy = FunctionType::get(int32Ty, false); Constant* func1_c; Function* func1; func1_c = module->getOrInsertFunction("func1", funcTy); func1 = cast<Function>(func1_c); Function* pro = module->getFunction("produce"); Function* con = module->getFunction("consume"); BasicBlock* func1EntryBlock = BasicBlock::Create(*context, "entry.func1", func1); AllocaInst* i_var = new AllocaInst(int32Ty, NULL, 4, "i", func1EntryBlock); Value* liveIn; BasicBlock *forCond, *forBody, *forInc; ValueToValueMapTy VMap; std::map<BasicBlock *, BasicBlock *> BlockMap; for (Loop::block_iterator BB = L->block_begin(), BBe = L->block_end(); BB != BBe; ++BB) { BasicBlock* func1Block = CloneBasicBlock(*BB, VMap, ".func1", func1); BlockMap[*BB] = func1Block; if ((*BB)->getName() == "for.cond") forCond = func1Block; if ((*BB)->getName() == "for.body") forBody = func1Block; if ((*BB)->getName() == "for.inc") forInc = func1Block; for (BasicBlock::iterator it = func1Block->begin(), ite = func1Block->end(); it != ite; ++it) { for (User::op_iterator oit = it->op_begin(), oite = it->op_end(); oit != oite; ++oit) { if (VMap[*oit] != NULL) { *oit = VMap[*oit]; } else { Constant* cons = dyn_cast<Constant>(*oit); BranchInst* br = dyn_cast<BranchInst>(it); if (cons == NULL && br == NULL) { liveIn = *oit; *oit = i_var; } } } } if ((*BB)->getName() == "for.body") { Instruction* term = (*BB)->getTerminator(); term->removeFromParent(); for (int i = 0; i < 7; i++) { (*BB)->back().eraseFromParent(); } term->insertAfter(&(*BB)->back()); (*BB)->front().eraseFromParent(); LoadInst* load = new LoadInst(liveIn, "", false, 4, term); std::vector<Value *> produce_args; CastInst* cast = CastInst::CreateIntegerCast(load, int64Ty, true); cast->insertAfter(load); produce_args.push_back(cast); ConstantInt* val = ConstantInt::get(int32Ty, (uint32_t) 3); produce_args.push_back(val); CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", term); produce_args.pop_back(); val = ConstantInt::get(int32Ty, (uint32_t) 2); produce_args.push_back(val); CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", term); } } // set branch instructions to restructure the CFG in created function BasicBlock* func1EndBlock = BasicBlock::Create(*context, "if.end.func1", func1); BasicBlock* garbageBB = BasicBlock::Create(*context, "garbage", func1); ConstantInt* retVal_g = ConstantInt::get(int32Ty, (uint32_t) 0); ReturnInst* ret_g = ReturnInst::Create(*context, retVal_g, garbageBB); for (Function::iterator fit = func1->begin(), fite = func1->end(); fit != fite; ++fit) { if (fit->getTerminator() == NULL || fit->getName() == "garbage") continue; BranchInst* br = dyn_cast<BranchInst>(fit->getTerminator()); int numSuccessors = br->getNumSuccessors(); for (int i = 0; i < numSuccessors; i++) { BasicBlock* successor = br->getSuccessor(i); if (BlockMap[successor] != NULL) { br->setSuccessor(i, BlockMap[successor]); } else { br->setSuccessor(i, func1EndBlock); } } /* if (fit->getName() == "for.body.func1") { for (int i = 0; i < 4; i++) { BasicBlock::iterator it = fit->begin(); it->moveBefore(ret_g); } } */ } garbageBB->eraseFromParent(); BranchInst* br = dyn_cast<BranchInst>(forBody->getTerminator()); br->setSuccessor(0, forCond); forInc->eraseFromParent(); // Create return instruction for func1EndBlock and set a branch from loop header to func1EndBlock ConstantInt* retVal = ConstantInt::get(int32Ty, (uint32_t) 0); ReturnInst* ret1 = ReturnInst::Create(*context, retVal, func1EndBlock); BasicBlock* loopHeader = BlockMap.at(L->getHeader()); BranchInst* brInst = BranchInst::Create(loopHeader, func1EntryBlock); // add produce function call std::vector<Value *> produce_args; ConstantInt* val = ConstantInt::get(int64Ty, (uint64_t) 0); produce_args.push_back(val); val = ConstantInt::get(int32Ty, (uint32_t) 5); produce_args.push_back(val); CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", func1EndBlock->getTerminator()); // add consume function call int q_id = 2; for (Value::use_iterator uit = i_var->use_begin(), uite = i_var->use_end(); uit != uite; ++uit) { std::vector<Value *> consume_args; ConstantInt* val = ConstantInt::get(int32Ty, (uint32_t) q_id); consume_args.push_back(val); CallInst* call = CallInst::Create(con, ArrayRef<Value*>(consume_args)); Instruction* inst = dyn_cast<Instruction>(*uit); call->insertAfter(inst); CastInst* cast = CastInst::CreateIntegerCast(call, int32Ty, true); cast->insertAfter(call); (*uit)->replaceAllUsesWith(cast); inst->eraseFromParent(); q_id++; } i_var->eraseFromParent(); // add produce and consume function calls to main thread // transmit the function pointer to created function by a produce call BasicBlock* loopPreheader = L->getLoopPreheader(); produce_args.clear(); CastInst* cast = CastInst::CreatePointerCast(func1, int64Ty); cast->insertBefore(loopPreheader->getTerminator()); produce_args.push_back(cast); val = ConstantInt::get(int32Ty, (uint32_t) 0); produce_args.push_back(val); CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", loopPreheader->getTerminator()); // transmit induction variable to created function by a produce call Instruction* load = &L->getHeader()->front(); produce_args.clear(); cast = CastInst::CreateIntegerCast(load, int64Ty, true); cast->insertAfter(load); produce_args.push_back(cast); val = ConstantInt::get(int32Ty, (uint32_t) 4); produce_args.push_back(val); CallInst::Create(pro, ArrayRef<Value*>(produce_args))->insertAfter(cast); return true; }
void ComputeSSO::HandleQueries(Module& M) { for(set<QueryInput*>::iterator qit = queryinputs.begin();qit!=queryinputs.end();++qit) { bool constCheck; errs()<<"\n\n\n\n*******************************************************Query "; errs()<<"\nOperation : "<<(*qit)->operation; errs()<<"\nConstCheck : "<<(*qit)->constcheck; string operation = (*qit)->operation; set<string> labels = (*qit)->labels; set<Value*> vals = (*qit)->labVals; std::set<GraphNode*> taintedA; std::set<GraphNode*> taintedB; std::set<GraphNode*> intersectGraph; for(set<string>::iterator label = labels.begin();label != labels.end();++label) errs()<<" - "<<*label; errs()<<"\n*******************************************************\n "; constCheck = (*qit)->constcheck; if(constCheck) { for(set<Value*>::iterator val = vals.begin();val != vals.end();++val) { taintedA = taintGraphMap[*val]; } intersectGraph = taintedA; } else { for(set<Value*>::iterator val = vals.begin();val != vals.end();++val) { taintedA = taintGraphMap[*val]; ++val; if(val!=vals.end()) taintedB = taintGraphMap[*val]; } if(strcmp(operation.c_str(),"intersect")==0) { // intersectGraph = getIntersect(taintedA,taintedB); for(set<GraphNode*>::iterator gnode = taintedA.begin();gnode != taintedA.end();++gnode) { if(taintedB.count(*gnode) > 0) { GraphNode* interNode = (*gnode)->clone(); intersectGraph.insert(interNode); } } } } int branches =0; errs()<<"\n Intersect graph size :"<<intersectGraph.size(); //print intersect graph nodes: // PrintTainted(intersectGraph); // for(set<GraphNode*>::iterator gnode = intersectGraph.begin();gnode != intersectGraph.end();++gnode) // { // errs()<<"\n Node: "<<(*gnode)->getLabel(); // } //Print appropriate vals....: for (Module::iterator F = M.begin(), endF = M.end(); F != endF; ++F) { string funcName = F->getName(); // errs()<<"\nTaints in function: "<<funcName; for (Function::iterator BB = F->begin(), endBB = F->end(); BB != endBB; ++BB) { string bbName ="noName"; if(BB->hasName()) { bbName = BB->getName(); } // errs()<<" - block: "<<bbName; for (BasicBlock::iterator I = BB->begin(), endI = BB->end(); I != endI; ++I) { GraphNode* g = depGraph->findNode(I); if (intersectGraph.count(g)) { errs()<<"\n Node found..:"; I->dump(); errs()<<"Taint in function : "<<funcName<<" :"; I->dump(); if (BranchInst *BI = dyn_cast<BranchInst>(I)) { if(constCheck) { Value* conditional = BI->getCondition(); for (unsigned int i = 0; i < cast<User> (conditional)->getNumOperands(); i++) { Value *v1 = cast<User> (conditional)->getOperand(i); if(isa<ConstantInt>(v1)) { errs()<<"Branch Inst tainted in func : "<<funcName<<" :"; BI->dump(); branches++; } } } else { // BI->getCondition()->dump(); errs()<<"Branch Inst tainted : "; BI->dump(); branches++; } } } } } } errs()<<"\n Number of conditionals tainted : " <<branches; } errs()<<"\n*******************************************************\n "; }