From d00a3cee80b34e9c8ebbe18ef4ae95ab4cd369d0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 24 Oct 2005 02:32:41 +0000 Subject: Remove some beta code that no longer has an owner. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23944 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Instrumentation/ProfilePaths/CombineBranch.cpp | 189 ------ .../Instrumentation/ProfilePaths/EdgeCode.cpp | 368 ----------- .../Instrumentation/ProfilePaths/Graph.cpp | 569 ----------------- .../Instrumentation/ProfilePaths/Graph.h | 480 --------------- .../ProfilePaths/GraphAuxiliary.cpp | 679 --------------------- .../Instrumentation/ProfilePaths/InstLoops.cpp | 185 ------ .../Instrumentation/ProfilePaths/Makefile | 13 - .../Instrumentation/ProfilePaths/ProfilePaths.cpp | 252 -------- .../Instrumentation/ProfilePaths/RetracePath.cpp | 308 ---------- 9 files changed, 3043 deletions(-) delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/CombineBranch.cpp delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/Graph.cpp delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/Graph.h delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/GraphAuxiliary.cpp delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/Makefile delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp delete mode 100644 lib/Transforms/Instrumentation/ProfilePaths/RetracePath.cpp diff --git a/lib/Transforms/Instrumentation/ProfilePaths/CombineBranch.cpp b/lib/Transforms/Instrumentation/ProfilePaths/CombineBranch.cpp deleted file mode 100644 index 5e4264ebfd..0000000000 --- a/lib/Transforms/Instrumentation/ProfilePaths/CombineBranch.cpp +++ /dev/null @@ -1,189 +0,0 @@ -//===-- CombineBranch.cpp -------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Combine multiple back-edges going to the same sink into a single -// back-edge. This introduces a new basic block and back-edge branch for each -// such sink. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/CFG.h" -#include "llvm/Instructions.h" -#include "llvm/Function.h" -#include "llvm/Pass.h" -#include "llvm/Type.h" - -namespace llvm { - -namespace { - struct CombineBranches : public FunctionPass { - private: - /// Possible colors that a vertex can have during depth-first search for - /// back-edges. - /// - enum Color { WHITE, GREY, BLACK }; - - void getBackEdgesVisit(BasicBlock *u, - std::map &color, - std::map &d, - int &time, - std::map &be); - void removeRedundant(std::map &be); - public: - bool runOnFunction(Function &F); - }; - - RegisterOpt - X("branch-combine", "Multiple backedges going to same target are merged"); -} - -/// getBackEdgesVisit - Get the back-edges of the control-flow graph for this -/// function. We proceed recursively using depth-first search. We get -/// back-edges by associating a time and a color with each vertex. The time of a -/// vertex is the time when it was first visited. The color of a vertex is -/// initially WHITE, changes to GREY when it is first visited, and changes to -/// BLACK when ALL its neighbors have been visited. So we have a back edge when -/// we meet a successor of a node with smaller time, and GREY color. -/// -void CombineBranches::getBackEdgesVisit(BasicBlock *u, - std::map &color, - std::map &d, - int &time, - std::map &be) { - - color[u]=GREY; - time++; - d[u]=time; - - for (succ_iterator vl = succ_begin(u), ve = succ_end(u); vl != ve; ++vl){ - BasicBlock *BB = *vl; - - if(color[BB]!=GREY && color[BB]!=BLACK) - getBackEdgesVisit(BB, color, d, time, be); - - //now checking for d and f vals - else if(color[BB]==GREY){ - //so v is ancestor of u if time of u > time of v - if(d[u] >= d[BB]) // u->BB is a backedge - be[u] = BB; - } - } - color[u]=BLACK;//done with visiting the node and its neighbors -} - -/// removeRedundant - Remove all back-edges that are dominated by other -/// back-edges in the set. -/// -void CombineBranches::removeRedundant(std::map &be){ - std::vector toDelete; - std::map seenBB; - - for(std::map::iterator MI = be.begin(), - ME = be.end(); MI != ME; ++MI){ - - if(seenBB[MI->second]) - continue; - - seenBB[MI->second] = 1; - - std::vector sameTarget; - sameTarget.clear(); - - for(std::map::iterator MMI = be.begin(), - MME = be.end(); MMI != MME; ++MMI){ - - if(MMI->first == MI->first) - continue; - - if(MMI->second == MI->second) - sameTarget.push_back(MMI->first); - - } - - //so more than one branch to same target - if(sameTarget.size()){ - - sameTarget.push_back(MI->first); - - BasicBlock *newBB = new BasicBlock("newCommon", MI->first->getParent()); - BranchInst *newBranch = new BranchInst(MI->second, newBB); - - std::map > phiMap; - - for(std::vector::iterator VBI = sameTarget.begin(), - VBE = sameTarget.end(); VBI != VBE; ++VBI){ - - BranchInst *ti = cast((*VBI)->getTerminator()); - unsigned char index = 1; - if(ti->getSuccessor(0) == MI->second) - index = 0; - - ti->setSuccessor(index, newBB); - - for(BasicBlock::iterator BB2Inst = MI->second->begin(), - BBend = MI->second->end(); BB2Inst != BBend; ++BB2Inst){ - - if (PHINode *phiInst = dyn_cast(BB2Inst)){ - int bbIndex; - bbIndex = phiInst->getBasicBlockIndex(*VBI); - if(bbIndex>=0) - phiMap[phiInst].push_back(bbIndex); - } - } - } - - for(std::map >::iterator - PI = phiMap.begin(), PE = phiMap.end(); PI != PE; ++PI){ - - PHINode *phiNode = new PHINode(PI->first->getType(), "phi", newBranch); - for(std::vector::iterator II = PI->second.begin(), - IE = PI->second.end(); II != IE; ++II){ - phiNode->addIncoming(PI->first->getIncomingValue(*II), - PI->first->getIncomingBlock(*II)); - } - - std::vector tempBB; - for(std::vector::iterator II = PI->second.begin(), - IE = PI->second.end(); II != IE; ++II){ - tempBB.push_back(PI->first->getIncomingBlock(*II)); - } - - for(std::vector::iterator II = tempBB.begin(), - IE = tempBB.end(); II != IE; ++II){ - PI->first->removeIncomingValue(*II); - } - - PI->first->addIncoming(phiNode, newBB); - } - } - } -} - -/// runOnFunction - Per function pass for combining branches. -/// -bool CombineBranches::runOnFunction(Function &F){ - if (F.isExternal ()) - return false; - - // Find and remove "redundant" back-edges. - std::map color; - std::map d; - std::map be; - int time = 0; - getBackEdgesVisit (F.begin (), color, d, time, be); - removeRedundant (be); - - return true; // FIXME: assumes a modification was always made. -} - -FunctionPass *createCombineBranchesPass () { - return new CombineBranches(); -} - -} // End llvm namespace diff --git a/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp b/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp deleted file mode 100644 index bf94943788..0000000000 --- a/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp +++ /dev/null @@ -1,368 +0,0 @@ -//===-- EdgeCode.cpp - generate LLVM instrumentation code -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -//It implements the class EdgeCode: which provides -//support for inserting "appropriate" instrumentation at -//designated points in the graph -// -//It also has methods to insert initialization code in -//top block of cfg -//===----------------------------------------------------------------------===// - -#include "Graph.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" - -#define INSERT_LOAD_COUNT -#define INSERT_STORE - - -using std::vector; - -namespace llvm { - -static void getTriggerCode(Module *M, BasicBlock *BB, int MethNo, Value *pathNo, - Value *cnt, Instruction *rInst){ - - vector tmpVec; - tmpVec.push_back(Constant::getNullValue(Type::LongTy)); - tmpVec.push_back(Constant::getNullValue(Type::LongTy)); - Instruction *Idx = new GetElementPtrInst(cnt, tmpVec, "");//, - BB->getInstList().push_back(Idx); - - const Type *PIntTy = PointerType::get(Type::IntTy); - Function *trigMeth = M->getOrInsertFunction("trigger", Type::VoidTy, - Type::IntTy, Type::IntTy, - PIntTy, PIntTy, (Type *)0); - assert(trigMeth && "trigger method could not be inserted!"); - - vector trargs; - - trargs.push_back(ConstantSInt::get(Type::IntTy,MethNo)); - trargs.push_back(pathNo); - trargs.push_back(Idx); - trargs.push_back(rInst); - - Instruction *callInst=new CallInst(trigMeth, trargs, "");//, BB->begin()); - BB->getInstList().push_back(callInst); - //triggerInst = new CallInst(trigMeth, trargs, "");//, InsertPos); -} - - -//get the code to be inserted on the edge -//This is determined from cond (1-6) -void getEdgeCode::getCode(Instruction *rInst, Value *countInst, - Function *M, BasicBlock *BB, - vector &retVec){ - - //Instruction *InsertPos = BB->getInstList().begin(); - - //now check for cdIn and cdOut - //first put cdOut - if(cdOut!=NULL){ - cdOut->getCode(rInst, countInst, M, BB, retVec); - } - - if(cdIn!=NULL){ - cdIn->getCode(rInst, countInst, M, BB, retVec); - } - - //case: r=k code to be inserted - switch(cond){ - case 1:{ - Value *val=ConstantSInt::get(Type::IntTy,inc); -#ifdef INSERT_STORE - Instruction *stInst=new StoreInst(val, rInst);//, InsertPos); - BB->getInstList().push_back(stInst); -#endif - break; - } - - //case: r=0 to be inserted - case 2:{ -#ifdef INSERT_STORE - Instruction *stInst = new StoreInst(ConstantSInt::getNullValue(Type::IntTy), rInst);//, InsertPos); - BB->getInstList().push_back(stInst); -#endif - break; - } - - //r+=k - case 3:{ - Instruction *ldInst = new LoadInst(rInst, "ti1");//, InsertPos); - BB->getInstList().push_back(ldInst); - Value *val = ConstantSInt::get(Type::IntTy,inc); - Instruction *addIn = BinaryOperator::create(Instruction::Add, ldInst, val, - "ti2");//, InsertPos); - BB->getInstList().push_back(addIn); -#ifdef INSERT_STORE - Instruction *stInst = new StoreInst(addIn, rInst);//, InsertPos); - BB->getInstList().push_back(stInst); -#endif - break; - } - - //count[inc]++ - case 4:{ - vector tmpVec; - tmpVec.push_back(Constant::getNullValue(Type::LongTy)); - tmpVec.push_back(ConstantSInt::get(Type::LongTy, inc)); - Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//, - - //Instruction *Idx = new GetElementPtrInst(countInst, - // vector(1,ConstantSInt::get(Type::LongTy, inc)), - // "");//, InsertPos); - BB->getInstList().push_back(Idx); - - Instruction *ldInst=new LoadInst(Idx, "ti1");//, InsertPos); - BB->getInstList().push_back(ldInst); - - Value *val = ConstantSInt::get(Type::IntTy, 1); - //Instruction *addIn = - Instruction *newCount = - BinaryOperator::create(Instruction::Add, ldInst, val,"ti2"); - BB->getInstList().push_back(newCount); - - -#ifdef INSERT_STORE - //Instruction *stInst=new StoreInst(addIn, Idx, InsertPos); - Instruction *stInst=new StoreInst(newCount, Idx);//, InsertPos); - BB->getInstList().push_back(stInst); -#endif - - Value *trAddIndex = ConstantSInt::get(Type::IntTy,inc); - - retVec.push_back(newCount); - retVec.push_back(trAddIndex); - //insert trigger - //getTriggerCode(M->getParent(), BB, MethNo, - // ConstantSInt::get(Type::IntTy,inc), newCount, triggerInst); - //end trigger code - - assert(inc>=0 && "IT MUST BE POSITIVE NOW"); - break; - } - - //case: count[r+inc]++ - case 5:{ - - //ti1=inc+r - Instruction *ldIndex=new LoadInst(rInst, "ti1");//, InsertPos); - BB->getInstList().push_back(ldIndex); - - Value *val=ConstantSInt::get(Type::IntTy,inc); - Instruction *addIndex=BinaryOperator:: - create(Instruction::Add, ldIndex, val,"ti2");//, InsertPos); - BB->getInstList().push_back(addIndex); - - //now load count[addIndex] - Instruction *castInst=new CastInst(addIndex, - Type::LongTy,"ctin");//, InsertPos); - BB->getInstList().push_back(castInst); - - vector tmpVec; - tmpVec.push_back(Constant::getNullValue(Type::LongTy)); - tmpVec.push_back(castInst); - Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//, - // InsertPos); - BB->getInstList().push_back(Idx); - - Instruction *ldInst=new LoadInst(Idx, "ti3");//, InsertPos); - BB->getInstList().push_back(ldInst); - - Value *cons=ConstantSInt::get(Type::IntTy,1); - //count[addIndex]++ - //std::cerr<<"Type ldInst:"<getType()<<"\t cons:"<getType()<<"\n"; - Instruction *newCount = BinaryOperator::create(Instruction::Add, ldInst, - cons,""); - BB->getInstList().push_back(newCount); - -#ifdef INSERT_STORE - Instruction *stInst = new StoreInst(newCount, Idx);//, InsertPos); - BB->getInstList().push_back(stInst); -#endif - - retVec.push_back(newCount); - retVec.push_back(addIndex); - //insert trigger - //getTriggerCode(M->getParent(), BB, MethNo, addIndex, newCount, triggerInst); - //end trigger code - - break; - } - - //case: count[r]+ - case 6:{ - //ti1=inc+r - Instruction *ldIndex=new LoadInst(rInst, "ti1");//, InsertPos); - BB->getInstList().push_back(ldIndex); - - //now load count[addIndex] - Instruction *castInst2=new CastInst(ldIndex, Type::LongTy,"ctin"); - BB->getInstList().push_back(castInst2); - - vector tmpVec; - tmpVec.push_back(Constant::getNullValue(Type::LongTy)); - tmpVec.push_back(castInst2); - Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//, - - //Instruction *Idx = new GetElementPtrInst(countInst, - // vector(1,castInst2), ""); - - BB->getInstList().push_back(Idx); - - Instruction *ldInst=new LoadInst(Idx, "ti2");//, InsertPos); - BB->getInstList().push_back(ldInst); - - Value *cons=ConstantSInt::get(Type::IntTy,1); - - //count[addIndex]++ - Instruction *newCount = BinaryOperator::create(Instruction::Add, ldInst, - cons,"ti3"); - BB->getInstList().push_back(newCount); - -#ifdef INSERT_STORE - Instruction *stInst = new StoreInst(newCount, Idx);//, InsertPos); - BB->getInstList().push_back(stInst); -#endif - - retVec.push_back(newCount); - retVec.push_back(ldIndex); - break; - } - - } -} - - - -//Insert the initialization code in the top BB -//this includes initializing r, and count -//r is like an accumulator, that -//keeps on adding increments as we traverse along a path -//and at the end of the path, r contains the path -//number of that path -//Count is an array, where Count[k] represents -//the number of executions of path k -void insertInTopBB(BasicBlock *front, - int k, - Instruction *rVar, Value *threshold){ - //rVar is variable r, - //countVar is count[] - - Value *Int0 = ConstantInt::get(Type::IntTy, 0); - - //now push all instructions in front of the BB - BasicBlock::iterator here=front->begin(); - front->getInstList().insert(here, rVar); - //front->getInstList().insert(here,countVar); - - //Initialize Count[...] with 0 - - //for (int i=0;i(1,ConstantSInt::get(Type::LongTy, i)), - // "", here); - //new StoreInst(Int0, GEP2, here); - //} - - //store uint 0, uint *%R - new StoreInst(Int0, rVar, here); -} - - -//insert a basic block with appropriate code -//along a given edge -void insertBB(Edge ed, - getEdgeCode *edgeCode, - Instruction *rInst, - Value *countInst, - int numPaths, int Methno, Value *threshold){ - - BasicBlock* BB1=ed.getFirst()->getElement(); - BasicBlock* BB2=ed.getSecond()->getElement(); - -#ifdef DEBUG_PATH_PROFILES - //debugging info - cerr<<"Edges with codes ######################\n"; - cerr<getName()<<"->"<getName()<<"\n"; - cerr<<"########################\n"; -#endif - - //We need to insert a BB between BB1 and BB2 - TerminatorInst *TI=BB1->getTerminator(); - BasicBlock *newBB=new BasicBlock("counter", BB1->getParent()); - - //get code for the new BB - vector retVec; - - edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB, retVec); - - BranchInst *BI = cast(TI); - - //Is terminator a branch instruction? - //then we need to change branch destinations to include new BB - - if(BI->isUnconditional()){ - BI->setUnconditionalDest(newBB); - } - else{ - if(BI->getSuccessor(0)==BB2) - BI->setSuccessor(0, newBB); - - if(BI->getSuccessor(1)==BB2) - BI->setSuccessor(1, newBB); - } - - BasicBlock *triggerBB = NULL; - if(retVec.size()>0){ - triggerBB = new BasicBlock("trigger", BB1->getParent()); - getTriggerCode(BB1->getParent()->getParent(), triggerBB, Methno, - retVec[1], countInst, rInst);//retVec[0]); - - //Instruction *castInst = new CastInst(retVec[0], Type::IntTy, ""); - Instruction *etr = new LoadInst(threshold, "threshold"); - - //std::cerr<<"type1: "<getType()<<" type2: "<getType()<<"\n"; - Instruction *cmpInst = new SetCondInst(Instruction::SetLE, etr, - retVec[0], ""); - Instruction *newBI2 = new BranchInst(triggerBB, BB2, cmpInst); - //newBB->getInstList().push_back(castInst); - newBB->getInstList().push_back(etr); - newBB->getInstList().push_back(cmpInst); - newBB->getInstList().push_back(newBI2); - - //triggerBB->getInstList().push_back(triggerInst); - new BranchInst(BB2, 0, 0, triggerBB); - } - else{ - new BranchInst(BB2, 0, 0, newBB); - } - - //now iterate over BB2, and set its Phi nodes right - for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end(); - BB2Inst != BBend; ++BB2Inst){ - - if(PHINode *phiInst=dyn_cast(BB2Inst)){ - int bbIndex=phiInst->getBasicBlockIndex(BB1); - assert(bbIndex>=0); - phiInst->setIncomingBlock(bbIndex, newBB); - - ///check if trigger!=null, then add value corresponding to it too! - if(retVec.size()>0){ - assert(triggerBB && "BasicBlock with trigger should not be null!"); - Value *vl = phiInst->getIncomingValue((unsigned int)bbIndex); - phiInst->addIncoming(vl, triggerBB); - } - } - } -} - -} // End llvm namespace diff --git a/lib/Transforms/Instrumentation/ProfilePaths/Graph.cpp b/lib/Transforms/Instrumentation/ProfilePaths/Graph.cpp deleted file mode 100644 index c8b1a0dfce..0000000000 --- a/lib/Transforms/Instrumentation/ProfilePaths/Graph.cpp +++ /dev/null @@ -1,569 +0,0 @@ -//===-- Graph.cpp - Implements Graph class --------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This implements Graph for helping in trace generation This graph gets used by -// "ProfilePaths" class. -// -//===----------------------------------------------------------------------===// - -#include "Graph.h" -#include "llvm/Instructions.h" -#include "llvm/Support/Debug.h" -#include - -using std::vector; - -namespace llvm { - -const graphListElement *findNodeInList(const Graph::nodeList &NL, - Node *N) { - for(Graph::nodeList::const_iterator NI = NL.begin(), NE=NL.end(); NI != NE; - ++NI) - if (*NI->element== *N) - return &*NI; - return 0; -} - -graphListElement *findNodeInList(Graph::nodeList &NL, Node *N) { - for(Graph::nodeList::iterator NI = NL.begin(), NE=NL.end(); NI != NE; ++NI) - if (*NI->element== *N) - return &*NI; - return 0; -} - -//graph constructor with root and exit specified -Graph::Graph(std::vector n, std::vector e, - Node *rt, Node *lt){ - strt=rt; - ext=lt; - for(vector::iterator x=n.begin(), en=n.end(); x!=en; ++x) - //nodes[*x] = list(); - nodes[*x] = vector(); - - for(vector::iterator x=e.begin(), en=e.end(); x!=en; ++x){ - Edge ee=*x; - int w=ee.getWeight(); - //nodes[ee.getFirst()].push_front(graphListElement(ee.getSecond(),w, ee.getRandId())); - nodes[ee.getFirst()].push_back(graphListElement(ee.getSecond(),w, ee.getRandId())); - } - -} - -//sorting edgelist, called by backEdgeVist ONLY!!! -Graph::nodeList &Graph::sortNodeList(Node *par, nodeList &nl, vector &be){ - assert(par && "null node pointer"); - BasicBlock *bbPar = par->getElement(); - - if(nl.size()<=1) return nl; - if(getExit() == par) return nl; - - for(nodeList::iterator NLI = nl.begin(), NLE = nl.end()-1; NLI != NLE; ++NLI){ - nodeList::iterator min = NLI; - for(nodeList::iterator LI = NLI+1, LE = nl.end(); LI!=LE; ++LI){ - //if LI < min, min = LI - if(min->element->getElement() == LI->element->getElement() && - min->element == getExit()){ - - //same successors: so might be exit??? - //if it is exit, then see which is backedge - //check if LI is a left back edge! - - TerminatorInst *tti = par->getElement()->getTerminator(); - BranchInst *ti = cast(tti); - - assert(ti && "not a branch"); - assert(ti->getNumSuccessors()==2 && "less successors!"); - - BasicBlock *tB = ti->getSuccessor(0); - BasicBlock *fB = ti->getSuccessor(1); - //so one of LI or min must be back edge! - //Algo: if succ(0)!=LI (and so !=min) then succ(0) is backedge - //and then see which of min or LI is backedge - //THEN if LI is in be, then min=LI - if(LI->element->getElement() != tB){//so backedge must be made min! - for(vector::iterator VBEI = be.begin(), VBEE = be.end(); - VBEI != VBEE; ++VBEI){ - if(VBEI->getRandId() == LI->randId){ - min = LI; - break; - } - else if(VBEI->getRandId() == min->randId) - break; - } - } - else{// if(LI->element->getElement() != fB) - for(vector::iterator VBEI = be.begin(), VBEE = be.end(); - VBEI != VBEE; ++VBEI){ - if(VBEI->getRandId() == min->randId){ - min = LI; - break; - } - else if(VBEI->getRandId() == LI->randId) - break; - } - } - } - - else if (min->element->getElement() != LI->element->getElement()){ - TerminatorInst *tti = par->getElement()->getTerminator(); - BranchInst *ti = cast(tti); - assert(ti && "not a branch"); - - if(ti->getNumSuccessors()<=1) continue; - - assert(ti->getNumSuccessors()==2 && "less successors!"); - - BasicBlock *tB = ti->getSuccessor(0); - BasicBlock *fB = ti->getSuccessor(1); - - if(tB == LI->element->getElement() || fB == min->element->getElement()) - min = LI; - } - } - - graphListElement tmpElmnt = *min; - *min = *NLI; - *NLI = tmpElmnt; - } - return nl; -} - -//check whether graph has an edge -//having an edge simply means that there is an edge in the graph -//which has same endpoints as the given edge -bool Graph::hasEdge(Edge ed){ - if(ed.isNull()) - return false; - - nodeList &nli= nodes[ed.getFirst()]; //getNodeList(ed.getFirst()); - Node *nd2=ed.getSecond(); - - return (findNodeInList(nli,nd2)!=NULL); - -} - - -//check whether graph has an edge, with a given wt -//having an edge simply means that there is an edge in the graph -//which has same endpoints as the given edge -//This function checks, moreover, that the wt of edge matches too -bool Graph::hasEdgeAndWt(Edge ed){ - if(ed.isNull()) - return false; - - Node *nd2=ed.getSecond(); - nodeList &nli = nodes[ed.getFirst()];//getNodeList(ed.getFirst()); - - for(nodeList::iterator NI=nli.begin(), NE=nli.end(); NI!=NE; ++NI) - if(*NI->element == *nd2 && ed.getWeight()==NI->weight) - return true; - - return false; -} - -//add a node -void Graph::addNode(Node *nd){ - vector lt=getAllNodes(); - - for(vector::iterator LI=lt.begin(), LE=lt.end(); LI!=LE;++LI){ - if(**LI==*nd) - return; - } - //chng - nodes[nd] =vector(); //list(); -} - -//add an edge -//this adds an edge ONLY when -//the edge to be added does not already exist -//we "equate" two edges here only with their -//end points -void Graph::addEdge(Edge ed, int w){ - nodeList &ndList = nodes[ed.getFirst()]; - Node *nd2=ed.getSecond(); - - if(findNodeInList(nodes[ed.getFirst()], nd2)) - return; - - //ndList.push_front(graphListElement(nd2,w, ed.getRandId())); - ndList.push_back(graphListElement(nd2,w, ed.getRandId()));//chng - //sortNodeList(ed.getFirst(), ndList); - - //sort(ndList.begin(), ndList.end(), NodeListSort()); -} - -//add an edge EVEN IF such an edge already exists -//this may make a multi-graph -//which does happen when we add dummy edges -//to the graph, for compensating for back-edges -void Graph::addEdgeForce(Edge ed){ - //nodes[ed.getFirst()].push_front(graphListElement(ed.getSecond(), - //ed.getWeight(), ed.getRandId())); - nodes[ed.getFirst()].push_back - (graphListElement(ed.getSecond(), ed.getWeight(), ed.getRandId())); - - //sortNodeList(ed.getFirst(), nodes[ed.getFirst()]); - //sort(nodes[ed.getFirst()].begin(), nodes[ed.getFirst()].end(), NodeListSort()); -} - -//remove an edge -//Note that it removes just one edge, -//the first edge that is encountered -void Graph::removeEdge(Edge ed){ - nodeList &ndList = nodes[ed.getFirst()]; - Node &nd2 = *ed.getSecond(); - - for(nodeList::iterator NI=ndList.begin(), NE=ndList.end(); NI!=NE ;++NI) { - if(*NI->element == nd2) { - ndList.erase(NI); - break; - } - } -} - -//remove an edge with a given wt -//Note that it removes just one edge, -//the first edge that is encountered -void Graph::removeEdgeWithWt(Edge ed){ - nodeList &ndList = nodes[ed.getFirst()]; - Node &nd2 = *ed.getSecond(); - - for(nodeList::iterator NI=ndList.begin(), NE=ndList.end(); NI!=NE ;++NI) { - if(*NI->element == nd2 && NI->weight==ed.getWeight()) { - ndList.erase(NI); - break; - } - } -} - -//set the weight of an edge -void Graph::setWeight(Edge ed){ - graphListElement *El = findNodeInList(nodes[ed.getFirst()], ed.getSecond()); - if (El) - El->weight=ed.getWeight(); -} - - - -//get the list of successor nodes -vector Graph::getSuccNodes(Node *nd){ - nodeMapTy::const_iterator nli = nodes.find(nd); - assert(nli != nodes.end() && "Node must be in nodes map"); - const nodeList &nl = getNodeList(nd);//getSortedNodeList(nd); - - vector lt; - for(nodeList::const_iterator NI=nl.begin(), NE=nl.end(); NI!=NE; ++NI) - lt.push_back(NI->element); - - return lt; -} - -//get the number of outgoing edges -int Graph::getNumberOfOutgoingEdges(Node *nd) const { - nodeMapTy::const_iterator nli = nodes.find(nd); - assert(nli != nodes.end() && "Node must be in nodes map"); - const nodeList &nl = nli->second; - - int count=0; - for(nodeList::const_iterator NI=nl.begin(), NE=nl.end(); NI!=NE; ++NI) - count++; - - return count; -} - -//get the list of predecessor nodes -vector Graph::getPredNodes(Node *nd){ - vector lt; - for(nodeMapTy::const_iterator EI=nodes.begin(), EE=nodes.end(); EI!=EE ;++EI){ - Node *lnode=EI->first; - const nodeList &nl = getNodeList(lnode); - - const graphListElement *N = findNodeInList(nl, nd); - if (N) lt.push_back(lnode); - } - return lt; -} - -//get the number of predecessor nodes -int Graph::getNumberOfIncomingEdges(Node *nd){ - int count=0; - for(nodeMapTy::const_iterator EI=nodes.begin(), EE=nodes.end(); EI!=EE ;++EI){ - Node *lnode=EI->first; - const nodeList &nl = getNodeList(lnode); - for(Graph::nodeList::const_iterator NI = nl.begin(), NE=nl.end(); NI != NE; - ++NI) - if (*NI->element== *nd) - count++; - } - return count; -} - -//get the list of all the vertices in graph -vector Graph::getAllNodes() const{ - vector lt; - for(nodeMapTy::const_iterator x=nodes.begin(), en=nodes.end(); x != en; ++x) - lt.push_back(x->first); - - return lt; -} - -//get the list of all the vertices in graph -vector Graph::getAllNodes(){ - vector lt; - for(nodeMapTy::const_iterator x=nodes.begin(), en=nodes.end(); x != en; ++x) - lt.push_back(x->first); - - return lt; -} - -//class to compare two nodes in graph -//based on their wt: this is used in -//finding the maximal spanning tree -struct compare_nodes { - bool operator()(Node *n1, Node *n2){ - return n1->getWeight() < n2->getWeight(); - } -}; - - -static void printNode(Node *nd){ - std::cerr<<"Node:"<getElement()->getName()<<"\n"; -} - -//Get the Maximal spanning tree (also a graph) -//of the graph -Graph* Graph::getMaxSpanningTree(){ - //assume connected graph - - Graph *st=new Graph();//max spanning tree, undirected edges - int inf=9999999;//largest key - vector lt = getAllNodes(); - - //initially put all vertices in vector vt - //assign wt(root)=0 - //wt(others)=infinity - // - //now: - //pull out u: a vertex frm vt of min wt - //for all vertices w in vt, - //if wt(w) greater than - //the wt(u->w), then assign - //wt(w) to be wt(u->w). - // - //make parent(u)=w in the spanning tree - //keep pulling out vertices from vt till it is empty - - vector vt; - - std::map parent; - std::map ed_weight; - - //initialize: wt(root)=0, wt(others)=infinity - //parent(root)=NULL, parent(others) not defined (but not null) - for(vector::iterator LI=lt.begin(), LE=lt.end(); LI!=LE; ++LI){ - Node *thisNode=*LI; - if(*thisNode == *getRoot()){ - thisNode->setWeight(0); - parent[thisNode]=NULL; - ed_weight[thisNode]=0; - } - else{ - thisNode->setWeight(inf); - } - st->addNode(thisNode);//add all nodes to spanning tree - //we later need to assign edges in the tree - vt.push_back(thisNode); //pushed all nodes in vt - } - - //keep pulling out vertex of min wt from vt - while(!vt.empty()){ - Node *u=*(std::min_element(vt.begin(), vt.end(), compare_nodes())); - DEBUG(std::cerr<<"popped wt"<<(u)->getWeight()<<"\n"; - printNode(u)); - - if(parent[u]!=NULL){ //so not root - Edge edge(parent[u],u, ed_weight[u]); //assign edge in spanning tree - st->addEdge(edge,ed_weight[u]); - - DEBUG(std::cerr<<"added:\n"; - printEdge(edge)); - } - - //vt.erase(u); - - //remove u frm vt - for(vector::iterator VI=vt.begin(), VE=vt.end(); VI!=VE; ++VI){ - if(**VI==*u){ - vt.erase(VI); - break; - } - } - - //assign wt(v) to all adjacent vertices v of u - //only if v is in vt - Graph::nodeList &nl = getNodeList(u); - for(nodeList::iterator NI=nl.begin(), NE=nl.end(); NI!=NE; ++NI){ - Node *v=NI->element; - int weight=-NI->weight; - //check if v is in vt - bool contains=false; - for(vector::iterator VI=vt.begin(), VE=vt.end(); VI!=VE; ++VI){ - if(**VI==*v){ - contains=true; - break; - } - } - DEBUG(std::cerr<<"wt:v->wt"<getWeight()<<"\n"; - printNode(v);std::cerr<<"node wt:"<<(*v).weight<<"\n"); - - //so if v in in vt, change wt(v) to wt(u->v) - //only if wt(u->v)getWeight()){ - parent[v]=u; - ed_weight[v]=weight; - v->setWeight(weight); - - DEBUG(std::cerr<getWeight()<<":Set weight------\n"; - printGraph(); - printEdge(Edge(u,v,weight))); - } - } - } - return st; -} - -//print the graph (for debugging) -void Graph::printGraph(){ - vector lt=getAllNodes(); - std::cerr<<"Graph---------------------\n"; - for(vector::iterator LI=lt.begin(), LE=lt.end(); LI!=LE; ++LI){ - std::cerr<<((*LI)->getElement())->getName()<<"->"; - Graph::nodeList &nl = getNodeList(*LI); - for(Graph::nodeList::iterator NI=nl.begin(), NE=nl.end(); NI!=NE; ++NI){ - std::cerr<<":"<<"("<<(NI->element->getElement()) - ->getName()<<":"<element->getWeight()<<","<weight<<")"; - } - std::cerr<<"--------\n"; - } -} - - -//get a list of nodes in the graph -//in r-topological sorted order -//note that we assumed graph to be connected -vector Graph::reverseTopologicalSort(){ - vector toReturn; - vector lt=getAllNodes(); - for(vector::iterator LI=lt.begin(), LE=lt.end(); LI!=LE; ++LI){ - if((*LI)->getWeight()!=GREY && (*LI)->getWeight()!=BLACK) - DFS_Visit(*LI, toReturn); - } - - return toReturn; -} - -//a private method for doing DFS traversal of graph -//this is used in determining the reverse topological sort -//of the graph -void Graph::DFS_Visit(Node *nd, vector &toReturn){ - nd->setWeight(GREY); - vector lt=getSuccNodes(nd); - for(vector::iterator LI=lt.begin(), LE=lt.end(); LI!=LE; ++LI){ - if((*LI)->getWeight()!=GREY && (*LI)->getWeight()!=BLACK) - DFS_Visit(*LI, toReturn); - } - toReturn.push_back(nd); -} - -//Ordinarily, the graph is directional -//this converts the graph into an -//undirectional graph -//This is done by adding an edge -//v->u for all existing edges u->v -void Graph::makeUnDirectional(){ - vector allNodes=getAllNodes(); - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI) { - nodeList &nl = getNodeList(*NI); - for(nodeList::iterator NLI=nl.begin(), NLE=nl.end(); NLI!=NLE; ++NLI){ - Edge ed(NLI->element, *NI, NLI->weight); - if(!hasEdgeAndWt(ed)){ - DEBUG(std::cerr<<"######doesn't hv\n"; - printEdge(ed)); - addEdgeForce(ed); - } - } - } -} - -//reverse the sign of weights on edges -//this way, max-spanning tree could be obtained -//using min-spanning tree, and vice versa -void Graph::reverseWts(){ - vector allNodes=getAllNodes(); - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI) { - nodeList &node_list = getNodeList(*NI); - for(nodeList::iterator NLI=nodes[*NI].begin(), NLE=nodes[*NI].end(); - NLI!=NLE; ++NLI) - NLI->weight=-NLI->weight; - } -} - - -//getting the backedges in a graph -//Its a variation of DFS to get the backedges in the graph -//We get back edges by associating a time -//and a color with each vertex. -//The time of a vertex is the time when it was first visited -//The color of a vertex is initially WHITE, -//Changes to GREY when it is first visited, -//and changes to BLACK when ALL its neighbors -//have been visited -//So we have a back edge when we meet a successor of -//a node with smaller time, and GREY color -void Graph::getBackEdges(vector &be, std::map &d){ - std::map color; - int time=0; - - getBackEdgesVisit(getRoot(), be, color, d, time); -} - -//helper function to get back edges: it is called by -//the "getBackEdges" function above -void Graph::getBackEdgesVisit(Node *u, vector &be, - std::map &color, - std::map &d, int &time) { - color[u]=GREY; - time++; - d[u]=time; - - vector &succ_list = getNodeList(u); - - for(vector::iterator vl=succ_list.begin(), - ve=succ_list.end(); vl!=ve; ++vl){ - Node *v=vl->element; - if(color[v]!=GREY && color[v]!=BLACK){ - getBackEdgesVisit(v, be, color, d, time); - } - - //now checking for d and f vals - if(color[v]==GREY){ - //so v is ancestor of u if time of u > time of v - if(d[u] >= d[v]){ - Edge *ed=new Edge(u, v,vl->weight, vl->randId); - if (!(*u == *getExit() && *v == *getRoot())) - be.push_back(*ed); // choose the forward edges - } - } - } - color[u]=BLACK;//done with visiting the node and its neighbors -} - -} // End llvm namespace diff --git a/lib/Transforms/Instrumentation/ProfilePaths/Graph.h b/lib/Transforms/Instrumentation/ProfilePaths/Graph.h deleted file mode 100644 index 9782ab4917..0000000000 --- a/lib/Transforms/Instrumentation/ProfilePaths/Graph.h +++ /dev/null @@ -1,480 +0,0 @@ -//===-- Graph.h -------------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Header file for Graph: This Graph is used by PathProfiles class, and is used -// for detecting proper points in cfg for code insertion -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_GRAPH_H -#define LLVM_GRAPH_H - -#include "llvm/BasicBlock.h" -#include -#include - -namespace llvm { - -class Module; -class Function; - -//Class Node -//It forms the vertex for the graph -class Node{ -public: - BasicBlock* element; - int weight; -public: - inline Node(BasicBlock* x) { element=x; weight=0; } - inline BasicBlock* &getElement() { return element; } - inline BasicBlock* const &getElement() const { return element; } - inline int getWeight() { return weight; } - inline void setElement(BasicBlock* e) { element=e; } - inline void setWeight(int w) { weight=w;} - inline bool operator<(Node& nd) const { return element - struct less : public binary_function { - bool operator()(Node *n1, Node *n2) const { - return n1->getElement() < n2->getElement(); - } - }; - - template<> - struct less : public binary_function { - bool operator()(Edge e1, Edge e2) const { - assert(!e1.isNull() && !e2.isNull()); - - Node *x1=e1.getFirst(); - Node *x2=e1.getSecond(); - Node *y1=e2.getFirst(); - Node *y2=e2.getSecond(); - return (*x1<*y1 ||(*x1==*y1 && *x2<*y2)); - } - }; -} - -namespace llvm { - -struct BBSort{ - bool operator()(BasicBlock *BB1, BasicBlock *BB2) const{ - std::string name1=BB1->getName(); - std::string name2=BB2->getName(); - return name1getElement()->getName(); - std::string name2=BB2.element->getElement()->getName(); - return name1 > nodeMapTy; - typedef std::map > nodeMapTy;//chng -private: - //the adjacency list of a vertex or node - nodeMapTy nodes; - - //the start or root node - Node *strt; - - //the exit node - Node *ext; - - //a private method for doing DFS traversal of graph - //this is used in determining the reverse topological sort - //of the graph - void DFS_Visit(Node *nd, std::vector &toReturn); - - //Its a variation of DFS to get the backedges in the graph - //We get back edges by associating a time - //and a color with each vertex. - //The time of a vertex is the time when it was first visited - //The color of a vertex is initially WHITE, - //Changes to GREY when it is first visited, - //and changes to BLACK when ALL its neighbors - //have been visited - //So we have a back edge when we meet a successor of - //a node with smaller time, and GREY color - void getBackEdgesVisit(Node *u, - std::vector &be, - std::map &clr, - std::map &d, - int &time); - -public: - typedef nodeMapTy::iterator elementIterator; - typedef nodeMapTy::const_iterator constElementIterator; - typedef std::vector nodeList;//chng - //typedef std::vector nodeList; - - //graph constructors - - //empty constructor: then add edges and nodes later on - Graph() {} - - //constructor with root and exit node specified - Graph(std::vector n, - std::vector e, Node *rt, Node *lt); - - //add a node - void addNode(Node *nd); - - //add an edge - //this adds an edge ONLY when - //the edge to be added doesn not already exist - //we "equate" two edges here only with their - //end points - void addEdge(Edge ed, int w); - - //add an edge EVEN IF such an edge already exists - //this may make a multi-graph - //which does happen when we add dummy edges - //to the graph, for compensating for back-edges - void addEdgeForce(Edge ed); - - //set the weight of an edge - void setWeight(Edge ed); - - //remove an edge - //Note that it removes just one edge, - //the first edge that is encountered - void removeEdge(Edge ed); - - //remove edge with given wt - void removeEdgeWithWt(Edge ed); - - //check whether graph has an edge - //having an edge simply means that there is an edge in the graph - //which has same endpoints as the given edge - //it may possibly have different weight though - bool hasEdge(Edge ed); - - //check whether graph has an edge, with a given wt - bool hasEdgeAndWt(Edge ed); - - //get the list of successor nodes - std::vector getSuccNodes(Node *nd); - - //get the number of outgoing edges - int getNumberOfOutgoingEdges(Node *nd) const; - - //get the list of predecessor nodes - std::vector getPredNodes(Node *nd); - - - //to get the no of incoming edges - int getNumberOfIncomingEdges(Node *nd); - - //get the list of all the vertices in graph - std::vector getAllNodes() const; - std::vector getAllNodes(); - - //get a list of nodes in the graph - //in r-topological sorted order - //note that we assumed graph to be connected - std::vector reverseTopologicalSort(); - - //reverse the sign of weights on edges - //this way, max-spanning tree could be obtained - //usin min-spanning tree, and vice versa - void reverseWts(); - - //Ordinarily, the graph is directional - //this converts the graph into an - //undirectional graph - //This is done by adding an edge - //v->u for all existing edges u->v - void makeUnDirectional(); - - //print graph: for debugging - void printGraph(); - - //get a vector of back edges in the graph - void getBackEdges(std::vector &be, std::map &d); - - nodeList &sortNodeList(Node *par, nodeList &nl, std::vector &be); - - //Get the Maximal spanning tree (also a graph) - //of the graph - Graph* getMaxSpanningTree(); - - //get the nodeList adjacent to a node - //a nodeList element contains a node, and the weight - //corresponding to the edge for that element - inline nodeList &getNodeList(Node *nd) { - elementIterator nli = nodes.find(nd); - assert(nli != nodes.end() && "Node must be in nodes map"); - return nodes[nd];//sortNodeList(nd, nli->second); - } - - nodeList &getSortedNodeList(Node *nd, std::vector &be) { - elementIterator nli = nodes.find(nd); - assert(nli != nodes.end() && "Node must be in nodes map"); - return sortNodeList(nd, nodes[nd], be); - } - - //get the root of the graph - inline Node *getRoot() {return strt; } - inline Node * const getRoot() const {return strt; } - - //get exit: we assumed there IS a unique exit :) - inline Node *getExit() {return ext; } - inline Node * const getExit() const {return ext; } - //Check if a given node is the root - inline bool isRoot(Node *n) const {return (*n==*strt); } - - //check if a given node is leaf node - //here we hv only 1 leaf: which is the exit node - inline bool isLeaf(Node *n) const {return (*n==*ext); } -}; - -//This class is used to generate -//"appropriate" code to be inserted -//along an edge -//The code to be inserted can be of six different types -//as given below -//1: r=k (where k is some constant) -//2: r=0 -//3: r+=k -//4: count[k]++ -//5: Count[r+k]++ -//6: Count[r]++ -class getEdgeCode{ - private: - //cond implies which - //"kind" of code is to be inserted - //(from 1-6 above) - int cond; - //inc is the increment: eg k, or 0 - int inc; - - //A backedge must carry the code - //of both incoming "dummy" edge - //and outgoing "dummy" edge - //If a->b is a backedge - //then incoming dummy edge is root->b - //and outgoing dummy edge is a->exit - - //incoming dummy edge, if any - getEdgeCode *cdIn; - - //outgoing dummy edge, if any - getEdgeCode *cdOut; - -public: - getEdgeCode(){ - cdIn=NULL; - cdOut=NULL; - inc=0; - cond=0; - } - - //set condition: 1-6 - inline void setCond(int n) {cond=n;} - - //get the condition - inline int getCond() { return cond;} - - //set increment - inline void setInc(int n) {inc=n;} - - //get increment - inline int getInc() {return inc;} - - //set CdIn (only used for backedges) - inline void setCdIn(getEdgeCode *gd){ cdIn=gd;} - - //set CdOut (only used for backedges) - inline void setCdOut(getEdgeCode *gd){ cdOut=gd;} - - //get the code to be inserted on the edge - //This is determined from cond (1-6) - void getCode(Instruction *a, Value *b, Function *M, BasicBlock *BB, - std::vector &retVec); -}; - - -//auxillary functions on graph - -//print a given edge in the form BB1Label->BB2Label -void printEdge(Edge ed); - -//Do graph processing: to determine minimal edge increments, -//appropriate code insertions etc and insert the code at -//appropriate locations -void processGraph(Graph &g, Instruction *rInst, Value *countInst, std::vector &be, std::vector &stDummy, std::vector &exDummy, int n, int MethNo, Value *threshold); - -//print the graph (for debugging) -void printGraph(Graph &g); - - -//void printGraph(const Graph g); -//insert a basic block with appropriate code -//along a given edge -void insertBB(Edge ed, getEdgeCode *edgeCode, Instruction *rInst, Value *countInst, int n, int Methno, Value *threshold); - -//Insert the initialization code in the top BB -//this includes initializing r, and count -//r is like an accumulator, that -//keeps on adding increments as we traverse along a path -//and at the end of the path, r contains the path -//number of that path -//Count is an array, where Count[k] represents -//the number of executions of path k -void insertInTopBB(BasicBlock *front, int k, Instruction *rVar, Value *threshold); - -//Add dummy edges corresponding to the back edges -//If a->b is a backedge -//then incoming dummy edge is root->b -//and outgoing dummy edge is a->exit -void addDummyEdges(std::vector &stDummy, std::vector &exDummy, Graph &g, std::vector &be); - -//Assign a value to all the edges in the graph -//such that if we traverse along any path from root to exit, and -//add up the edge values, we get a path number that uniquely -//refers to the path we travelled -int valueAssignmentToEdges(Graph& g, std::map nodePriority, - std::vector &be); - -void getBBtrace(std::vector &vBB, int pathNo, Function *M); - -} // End llvm namespace - -#endif diff --git a/lib/Transforms/Instrumentation/ProfilePaths/GraphAuxiliary.cpp b/lib/Transforms/Instrumentation/ProfilePaths/GraphAuxiliary.cpp deleted file mode 100644 index 4ca1c5b92f..0000000000 --- a/lib/Transforms/Instrumentation/ProfilePaths/GraphAuxiliary.cpp +++ /dev/null @@ -1,679 +0,0 @@ -//===- GraphAuxiliary.cpp - Auxiliary functions on graph ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// auxiliary function associated with graph: they all operate on graph, and help -// in inserting instrumentation for trace generation -// -//===----------------------------------------------------------------------===// - -#include "llvm/Pass.h" -#include "llvm/Module.h" -#include "llvm/Instructions.h" -#include "llvm/Support/Debug.h" -#include -#include "Graph.h" - -//using std::list; -using std::map; -using std::vector; -using std::cerr; - -namespace llvm { - -//check if 2 edges are equal (same endpoints and same weight) -static bool edgesEqual(Edge ed1, Edge ed2){ - return ((ed1==ed2) && ed1.getWeight()==ed2.getWeight()); -} - -//Get the vector of edges that are to be instrumented in the graph -static void getChords(vector &chords, Graph &g, Graph st){ - //make sure the spanning tree is directional - //iterate over ALL the edges of the graph - vector allNodes=g.getAllNodes(); - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI){ - Graph::nodeList node_list=g.getNodeList(*NI); - for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); - NLI!=NLE; ++NLI){ - Edge f(*NI, NLI->element,NLI->weight, NLI->randId); - if(!(st.hasEdgeAndWt(f)))//addnl - chords.push_back(f); - } - } -} - -//Given a tree t, and a "directed graph" g -//replace the edges in the tree t with edges that exist in graph -//The tree is formed from "undirectional" copy of graph -//So whatever edges the tree has, the undirectional graph -//would have too. This function corrects some of the directions in -//the tree so that now, all edge directions in the tree match -//the edge directions of corresponding edges in the directed graph -static void removeTreeEdges(Graph &g, Graph& t){ - vector allNodes=t.getAllNodes(); - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI){ - Graph::nodeList nl=t.getNodeList(*NI); - for(Graph::nodeList::iterator NLI=nl.begin(), NLE=nl.end(); NLI!=NLE;++NLI){ - Edge ed(NLI->element, *NI, NLI->weight); - if(!g.hasEdgeAndWt(ed)) t.removeEdge(ed);//tree has only one edge - //between any pair of vertices, so no need to delete by edge wt - } - } -} - -//Assign a value to all the edges in the graph -//such that if we traverse along any path from root to exit, and -//add up the edge values, we get a path number that uniquely -//refers to the path we travelled -int valueAssignmentToEdges(Graph& g, map nodePriority, - vector &be){ - vector revtop=g.reverseTopologicalSort(); - map NumPaths; - for(vector::iterator RI=revtop.begin(), RE=revtop.end(); - RI!=RE; ++RI){ - if(g.isLeaf(*RI)) - NumPaths[*RI]=1; - else{ - NumPaths[*RI]=0; - - // Modified Graph::nodeList &nlist=g.getNodeList(*RI); - Graph::nodeList &nlist=g.getSortedNodeList(*RI, be); - - //sort nodelist by increasing order of numpaths - - int sz=nlist.size(); - - for(int i=0;igetElement(); - BasicBlock *bb2 = nlist[min].element->getElement(); - - if(bb1 == bb2) continue; - - if(*RI == g.getRoot()){ - assert(nodePriority[nlist[min].element]!= - nodePriority[nlist[j].element] - && "priorities can't be same!"); - - if(nodePriority[nlist[j].element] < - nodePriority[nlist[min].element]) - min = j; - } - - else{ - TerminatorInst *tti = (*RI)->getElement()->getTerminator(); - - BranchInst *ti = cast(tti); - assert(ti && "not a branch"); - assert(ti->getNumSuccessors()==2 && "less successors!"); - - BasicBlock *tB = ti->getSuccessor(0); - BasicBlock *fB = ti->getSuccessor(1); - - if(tB == bb1 || fB == bb2) - min = j; - } - - } - graphListElement tempEl=nlist[min]; - nlist[min]=nlist[i]; - nlist[i]=tempEl; - } - - //sorted now! - for(Graph::nodeList::iterator GLI=nlist.begin(), GLE=nlist.end(); - GLI!=GLE; ++GLI){ - GLI->weight=NumPaths[*RI]; - NumPaths[*RI]+=NumPaths[GLI->element]; - } - } - } - return NumPaths[g.getRoot()]; -} - -//This is a helper function to get the edge increments -//This is used in conjunction with inc_DFS -//to get the edge increments -//Edge increment implies assigning a value to all the edges in the graph -//such that if we traverse along any path from root to exit, and -//add up the edge values, we get a path number that uniquely -//refers to the path we travelled -//inc_Dir tells whether 2 edges are in same, or in different directions -//if same direction, return 1, else -1 -static int inc_Dir(Edge e, Edge f){ - if(e.isNull()) - return 1; - - //check that the edges must have at least one common endpoint - assert(*(e.getFirst())==*(f.getFirst()) || - *(e.getFirst())==*(f.getSecond()) || - *(e.getSecond())==*(f.getFirst()) || - *(e.getSecond())==*(f.getSecond())); - - if(*(e.getFirst())==*(f.getSecond()) || - *(e.getSecond())==*(f.getFirst())) - return 1; - - return -1; -} - - -//used for getting edge increments (read comments above in inc_Dir) -//inc_DFS is a modification of DFS -static void inc_DFS(Graph& g,Graph& t,map& Increment, - int events, Node *v, Edge e){ - - vector allNodes=t.getAllNodes(); - - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI){ - Graph::nodeList node_list=t.getNodeList(*NI); - for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); - NLI!= NLE; ++NLI){ - Edge f(*NI, NLI->element,NLI->weight, NLI->randId); - if(!edgesEqual(f,e) && *v==*(f.getSecond())){ - int dir_count=inc_Dir(e,f); - int wt=1*f.getWeight(); - inc_DFS(g,t, Increment, dir_count*events+wt, f.getFirst(), f); - } - } - } - - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI){ - Graph::nodeList node_list=t.getNodeList(*NI); - for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); - NLI!=NLE; ++NLI){ - Edge f(*NI, NLI->element,NLI->weight, NLI->randId); - if(!edgesEqual(f,e) && *v==*(f.getFirst())){ - int dir_count=inc_Dir(e,f); - int wt=f.getWeight(); - inc_DFS(g,t, Increment, dir_count*events+wt, - f.getSecond(), f); - } - } - } - - allNodes=g.getAllNodes(); - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI){ - Graph::nodeList node_list=g.getNodeList(*NI); - for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); - NLI!=NLE; ++NLI){ - Edge f(*NI, NLI->element,NLI->weight, NLI->randId); - if(!(t.hasEdgeAndWt(f)) && (*v==*(f.getSecond()) || - *v==*(f.getFirst()))){ - int dir_count=inc_Dir(e,f); - Increment[f]+=dir_count*events; - } - } - } -} - -//Now we select a subset of all edges -//and assign them some values such that -//if we consider just this subset, it still represents -//the path sum along any path in the graph -static map getEdgeIncrements(Graph& g, Graph& t, - vector &be){ - //get all edges in g-t - map Increment; - - vector allNodes=g.getAllNodes(); - - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI){ - Graph::nodeList node_list=g.getSortedNodeList(*NI, be); - //modified g.getNodeList(*NI); - for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); - NLI!=NLE; ++NLI){ - Edge ed(*NI, NLI->element,NLI->weight,NLI->randId); - if(!(t.hasEdgeAndWt(ed))){ - Increment[ed]=0;; - } - } - } - - Edge *ed=new Edge(); - inc_DFS(g,t,Increment, 0, g.getRoot(), *ed); - - for(vector::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE; - ++NI){ - Graph::nodeList node_list=g.getSortedNodeList(*NI, be); - //modified g.getNodeList(*NI); - for(Graph::nodeList::iterator NLI=node_list.begin(), NLE=node_list.end(); - NLI!=NLE; ++NLI){ - Edge ed(*NI, NLI->element,NLI->weight, NLI->randId); - if(!(t.hasEdgeAndWt(ed))){ - int wt=ed.getWeight(); - Increment[ed]+=wt; - } - } - } - - return Increment; -} - -//push it up: TODO -const graphListElement *findNodeInList(const Graph::nodeList &NL, - Node *N); - -graphListElement *findNodeInList(Graph::nodeList &NL, Node *N); -//end TODO - -//Based on edgeIncrements (above), now obtain -//the kind of code to be inserted along an edge -//The idea here is to minimize the computation -//by inserting only the needed code -static void getCodeInsertions(Graph &g, map &instr, - vector &chords, - map &edIncrements){ - - //Register initialization code - vector ws; - ws.push_back(g.getRoot()); - while(ws.size()>0){ - Node *v=ws.back(); - ws.pop_back(); - //for each edge v->w - Graph::nodeList succs=g.getNodeList(v); - - for(Graph::nodeList::iterator nl=succs.begin(), ne=succs.end(); - nl!=ne; ++nl){ - int edgeWt=nl->weight; - Node *w=nl->element; - //if chords has v->w - Edge ed(v,w, edgeWt, nl->randId); - bool hasEdge=false; - for(vector::iterator CI=chords.begin(), CE=chords.end(); - CI!=CE && !hasEdge;++CI){ - if(*CI==ed && CI->getWeight()==edgeWt){//modf - hasEdge=true; - } - } - - if(hasEdge){//so its a chord edge - getEdgeCode *edCd=new getEdgeCode(); - edCd->setCond(1); - edCd->setInc(edIncrements[ed]); - instr[ed]=edCd; - } - else if(g.getNumberOfIncomingEdges(w)==1){ - ws.push_back(w); - } - else{ - getEdgeCode *edCd=new getEdgeCode(); - edCd->setCond(2); - edCd->setInc(0); - instr[ed]=edCd; - } - } - } - - /////Memory increment code - ws.push_back(g.getExit()); - - while(!ws.empty()) { - Node *w=ws.back(); - ws.pop_back(); - - - /////// - //vector lt; - vector lllt=g.getAllNodes(); - for(vector::iterator EII=lllt.begin(); EII!=lllt.end() ;++EII){ - Node *lnode=*EII; - Graph::nodeList &nl = g.getNodeList(lnode); - //graphListElement *N = findNodeInList(nl, w); - for(Graph::nodeList::const_iterator N = nl.begin(), - NNEN = nl.end(); N!= NNEN; ++N){ - if (*N->element == *w){ - Node *v=lnode; - - //if chords has v->w - Edge ed(v,w, N->weight, N->randId); - getEdgeCode *edCd=new getEdgeCode(); - bool hasEdge=false; - for(vector::iterator CI=chords.begin(), CE=chords.end(); CI!=CE; - ++CI){ - if(*CI==ed && CI->getWeight()==N->weight){ - hasEdge=true; - break; - } - } - if(hasEdge){ - //char str[100]; - if(instr[ed]!=NULL && instr[ed]->getCond()==1){ - instr[ed]->setCond(4); - } - else{ - edCd->setCond(5); - edCd->setInc(edIncrements[ed]); - instr[ed]=edCd; - } - - } - else if(g.getNumberOfOutgoingEdges(v)==1) - ws.push_back(v); - else{ - edCd->setCond(6); - instr[ed]=edCd; - } - } - } - } - } - ///// Register increment code - for(vector::iterator CI=chords.begin(), CE=chords.end(); CI!=CE; ++CI){ - getEdgeCode *edCd=new getEdgeCode(); - if(instr[*CI]==NULL){ - edCd->setCond(3); - edCd->setInc(edIncrements[*CI]); - instr[*CI]=edCd; - } - } -} - -//Add dummy edges corresponding to the back edges -//If a->b is a backedge -//then incoming dummy edge is root->b -//and outgoing dummy edge is a->exit -//changed -void addDummyEdges(vector &stDummy, - vector &exDummy, - Graph &g, vector &be){ - for(vector::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){ - Edge ed=*VI; - Node *first=ed.getFirst(); - Node *second=ed.getSecond(); - g.removeEdge(ed); - - if(!(*second==*(g.getRoot()))){ - Edge *st=new Edge(g.getRoot(), second, ed.getWeight(), ed.getRandId()); - stDummy.push_back(*st); - g.addEdgeForce(*st); - } - - if(!(*first==*(g.getExit()))){ - Edge *ex=new Edge(first, g.getExit(), ed.getWeight(), ed.getRandId()); - exDummy.push_back(*ex); - g.addEdgeForce(*ex); - } - } -} - -//print a given edge in the form BB1Label->BB2Label -void printEdge(Edge ed){ - cerr<<((ed.getFirst())->getElement()) - ->getName()<<"->"<<((ed.getSecond()) - ->getElement())->getName()<< - ":"< &stDummy, - vector &exDummy, - vector &be, - map &insertions, - Graph &g){ - typedef vector::iterator vec_iter; - - map temp; - //iterate over edges with code - std::vector toErase; - for(map::iterator MI=insertions.begin(), - ME=insertions.end(); MI!=ME; ++MI){ - Edge ed=MI->first; - getEdgeCode *edCd=MI->second; - - ///---new code - //iterate over be, and check if its starts and end vertices hv code - for(vector::iterator BEI=be.begin(), BEE=be.end(); BEI!=BEE; ++BEI){ - if(ed.getRandId()==BEI->getRandId()){ - - if(temp[*BEI]==0) - temp[*BEI]=new getEdgeCode(); - - //so ed is either in st, or ex! - if(ed.getFirst()==g.getRoot()){ - - //so its in stDummy - temp[*BEI]->setCdIn(edCd); - toErase.push_back(ed); - } - else if(ed.getSecond()==g.getExit()){ - - //so its in exDummy - toErase.push_back(ed); - temp[*BEI]->setCdOut(edCd); - } - else{ - assert(false && "Not found in either start or end! Rand failed?"); - } - } - } - } - - for(vector::iterator vmi=toErase.begin(), vme=toErase.end(); vmi!=vme; - ++vmi){ - insertions.erase(*vmi); - g.removeEdgeWithWt(*vmi); - } - - for(map::iterator MI=temp.begin(), - ME=temp.end(); MI!=ME; ++MI){ - insertions[MI->first]=MI->second; - } - -#ifdef DEBUG_PATH_PROFILES - cerr<<"size of deletions: "<& be, - vector& stDummy, - vector& exDummy, - int numPaths, int MethNo, - Value *threshold){ - - //Given a graph: with exit->root edge, do the following in seq: - //1. get back edges - //2. insert dummy edges and remove back edges - //3. get edge assignments - //4. Get Max spanning tree of graph: - // -Make graph g2=g undirectional - // -Get Max spanning tree t - // -Make t undirectional - // -remove edges from t not in graph g - //5. Get edge increments - //6. Get code insertions - //7. move code on dummy edges over to the back edges - - - //This is used as maximum "weight" for - //priority queue - //This would hold all - //right as long as number of paths in the graph - //is less than this - const int Infinity=99999999; - - - //step 1-3 are already done on the graph when this function is called - DEBUG(printGraph(g)); - - //step 4: Get Max spanning tree of graph - - //now insert exit to root edge - //if its there earlier, remove it! - //assign it weight Infinity - //so that this edge IS ALWAYS IN spanning tree - //Note than edges in spanning tree do not get - //instrumented: and we do not want the - //edge exit->root to get instrumented - //as it MAY BE a dummy edge - Edge ed(g.getExit(),g.getRoot(),Infinity); - g.addEdge(ed,Infinity); - Graph g2=g; - - //make g2 undirectional: this gives a better - //maximal spanning tree - g2.makeUnDirectional(); - DEBUG(printGraph(g2)); - - Graph *t=g2.getMaxSpanningTree(); -#ifdef DEBUG_PATH_PROFILES - std::cerr<<"Original maxspanning tree\n"; - printGraph(*t); -#endif - //now edges of tree t have weights reversed - //(negative) because the algorithm used - //to find max spanning tree is - //actually for finding min spanning tree - //so get back the original weights - t->reverseWts(); - - //Ordinarily, the graph is directional - //lets converts the graph into an - //undirectional graph - //This is done by adding an edge - //v->u for all existing edges u->v - t->makeUnDirectional(); - - //Given a tree t, and a "directed graph" g - //replace the edges in the tree t with edges that exist in graph - //The tree is formed from "undirectional" copy of graph - //So whatever edges the tree has, the undirectional graph - //would have too. This function corrects some of the directions in - //the tree so that now, all edge directions in the tree match - //the edge directions of corresponding edges in the directed graph - removeTreeEdges(g, *t); - -#ifdef DEBUG_PATH_PROFILES - cerr<<"Final Spanning tree---------\n"; - printGraph(*t); - cerr<<"-------end spanning tree\n"; -#endif - - //now remove the exit->root node - //and re-add it with weight 0 - //since infinite weight is kinda confusing - g.removeEdge(ed); - Edge edNew(g.getExit(), g.getRoot(),0); - g.addEdge(edNew,0); - if(t->hasEdge(ed)){ - t->removeEdge(ed); - t->addEdge(edNew,0); - } - - DEBUG(printGraph(g); - printGraph(*t)); - - //step 5: Get edge increments - - //Now we select a subset of all edges - //and assign them some values such that - //if we consider just this subset, it still represents - //the path sum along any path in the graph - - map increment=getEdgeIncrements(g,*t, be); -#ifdef DEBUG_PATH_PROFILES - //print edge increments for debugging - std::cerr<<"Edge Increments------\n"; - for(map::iterator MMI=increment.begin(), MME=increment.end(); MMI != MME; ++MMI){ - printEdge(MMI->first); - std::cerr<<"Increment for above:"<second<<"\n"; - } - std::cerr<<"-------end of edge increments\n"; -#endif - - - //step 6: Get code insertions - - //Based on edgeIncrements (above), now obtain - //the kind of code to be inserted along an edge - //The idea here is to minimize the computation - //by inserting only the needed code - vector chords; - getChords(chords, g, *t); - - - map codeInsertions; - getCodeInsertions(g, codeInsertions, chords,increment); - -#ifdef DEBUG_PATH_PROFILES - //print edges with code for debugging - cerr<<"Code inserted in following---------------\n"; - for(map::iterator cd_i=codeInsertions.begin(), - cd_e=codeInsertions.end(); cd_i!=cd_e; ++cd_i){ - printEdge(cd_i->first); - cerr<second->getCond()<<":"<second->getInc()<<"\n"; - } - cerr<<"-----end insertions\n"; -#endif - - //step 7: move code on dummy edges over to the back edges - - //Move the incoming dummy edge code and outgoing dummy - //edge code over to the corresponding back edge - - moveDummyCode(stDummy, exDummy, be, codeInsertions, g); - -#ifdef DEBUG_PATH_PROFILES - //debugging info - cerr<<"After moving dummy code\n"; - for(map::iterator cd_i=codeInsertions.begin(), - cd_e=codeInsertions.end(); cd_i != cd_e; ++cd_i){ - printEdge(cd_i->first); - cerr<second->getCond()<<":" - <second->getInc()<<"\n"; - } - cerr<<"Dummy end------------\n"; -#endif - - - //see what it looks like... - //now insert code along edges which have codes on them - for(map::iterator MI=codeInsertions.begin(), - ME=codeInsertions.end(); MI!=ME; ++MI){ - Edge ed=MI->first; - insertBB(ed, MI->second, rInst, countInst, numPaths, MethNo, threshold); - } -} - -//print the graph (for debugging) -void printGraph(Graph &g){ - vector lt=g.getAllNodes(); - cerr<<"Graph---------------------\n"; - for(vector::iterator LI=lt.begin(); - LI!=lt.end(); ++LI){ - cerr<<((*LI)->getElement())->getName()<<"->"; - Graph::nodeList nl=g.getNodeList(*LI); - for(Graph::nodeList::iterator NI=nl.begin(); - NI!=nl.end(); ++NI){ - cerr<<":"<<"("<<(NI->element->getElement()) - ->getName()<<":"<element->getWeight()<<","<weight<<"," - <randId<<")"; - } - cerr<<"\n"; - } - cerr<<"--------------------Graph\n"; -} - -} // End llvm namespace diff --git a/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp b/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp deleted file mode 100644 index 020388f2b6..0000000000 --- a/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp +++ /dev/null @@ -1,185 +0,0 @@ -//===-- InstLoops.cpp -----------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This is the first-level instrumentation pass for the Reoptimizer. It -// instrument the back-edges of loops by inserting a basic block -// containing a call to llvm_first_trigger (the first-level trigger function), -// and inserts an initialization call to the main() function. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/Dominators.h" -#include "llvm/Support/CFG.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Pass.h" -#include "llvm/Type.h" -#include "llvm/Support/Debug.h" -#include "llvm/Transforms/Instrumentation.h" -#include "../ProfilingUtils.h" - -namespace llvm { - -//this is used to color vertices -//during DFS - -enum Color{ - WHITE, - GREY, - BLACK -}; - -namespace { - typedef std::map BBMap; - struct InstLoops : public FunctionPass { - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - } - private: - Function *inCountMth; - DominatorSet *DS; - void getBackEdgesVisit(BasicBlock *u, - std::map &color, - std::map &d, - int &time, BBMap &be); - void removeRedundant(BBMap &be); - void findAndInstrumentBackEdges(Function &F); - public: - bool doInitialization(Module &M); - bool runOnFunction(Function &F); - }; - - RegisterOpt X("instloops", "Instrument backedges for profiling"); -} - -//helper function to get back edges: it is called by -//the "getBackEdges" function below -void InstLoops::getBackEdgesVisit(BasicBlock *u, - std::map &color, - std::map &d, - int &time, BBMap &be) { - color[u]=GREY; - time++; - d[u]=time; - - for(succ_iterator vl = succ_begin(u), ve = succ_end(u); vl != ve; ++vl){ - BasicBlock *BB = *vl; - - if(color[BB]!=GREY && color[BB]!=BLACK){ - getBackEdgesVisit(BB, color, d, time, be); - } - - //now checking for d and f vals - else if(color[BB]==GREY){ - //so v is ancestor of u if time of u > time of v - if(d[u] >= d[BB]){ - //u->BB is a backedge - be[u] = BB; - } - } - } - color[u]=BLACK;//done with visiting the node and its neighbors -} - -//look at all BEs, and remove all BEs that are dominated by other BE's in the -//set -void InstLoops::removeRedundant(BBMap &be) { - std::vector toDelete; - for(std::map::iterator MI = be.begin(), - ME = be.end(); MI != ME; ++MI) - for(BBMap::iterator MMI = be.begin(), MME = be.end(); MMI != MME; ++MMI) - if(DS->properlyDominates(MI->first, MMI->first)) - toDelete.push_back(MMI->first); - // Remove all the back-edges we found from be. - for(std::vector::iterator VI = toDelete.begin(), - VE = toDelete.end(); VI != VE; ++VI) - be.erase(*VI); -} - -//getting the backedges in a graph -//Its a variation of DFS to get the backedges in the graph -//We get back edges by associating a time -//and a color with each vertex. -//The time of a vertex is the time when it was first visited -//The color of a vertex is initially WHITE, -//Changes to GREY when it is first visited, -//and changes to BLACK when ALL its neighbors -//have been visited -//So we have a back edge when we meet a successor of -//a node with smaller time, and GREY color -void InstLoops::findAndInstrumentBackEdges(Function &F){ - std::map color; - std::map d; - BBMap be; - int time=0; - getBackEdgesVisit(F.begin(), color, d, time, be); - - removeRedundant(be); - - for(std::map::iterator MI = be.begin(), - ME = be.end(); MI != ME; ++MI){ - BasicBlock *u = MI->first; - BasicBlock *BB = MI->second; - // We have a back-edge from BB --> u. - DEBUG (std::cerr << "Instrumenting back-edge from " << BB->getName () - << "-->" << u->getName () << "\n"); - // Split the back-edge, inserting a new basic block on it, and modify the - // source BB's terminator accordingly. - BasicBlock *newBB = new BasicBlock("backEdgeInst", u->getParent()); - BranchInst *ti = cast(u->getTerminator()); - unsigned char index = ((ti->getSuccessor(0) == BB) ? 0 : 1); - - assert(ti->getNumSuccessors() > index && "Not enough successors!"); - ti->setSuccessor(index, newBB); - - BasicBlock::InstListType < = newBB->getInstList(); - lt.push_back(new CallInst(inCountMth)); - new BranchInst(BB, newBB); - - // Now, set the sources of Phi nodes corresponding to the back-edge - // in BB to come from the instrumentation block instead. - for(BasicBlock::iterator BB2Inst = BB->begin(), BBend = BB->end(); - BB2Inst != BBend; ++BB2Inst) { - if (PHINode *phiInst = dyn_cast(BB2Inst)) { - int bbIndex = phiInst->getBasicBlockIndex(u); - if (bbIndex>=0) - phiInst->setIncomingBlock(bbIndex, newBB); - } - } - } -} - -bool InstLoops::doInitialization (Module &M) { - inCountMth = M.getOrInsertFunction("llvm_first_trigger", Type::VoidTy, - (Type *)0); - return true; // Module was modified. -} - -/// runOnFunction - Entry point for FunctionPass that inserts calls to -/// trigger function. -/// -bool InstLoops::runOnFunction(Function &F){ - if (F.isExternal ()) - return false; - - DS = &getAnalysis (); - - // Add a call to reoptimizerInitialize() to beginning of function named main. - if (F.getName() == "main") - InsertProfilingInitCall (&F, "reoptimizerInitialize"); - - findAndInstrumentBackEdges(F); - return true; // Function was modified. -} - -FunctionPass *createLoopInstrumentationPass () { - return new InstLoops(); -} - -} // End llvm namespace diff --git a/lib/Transforms/Instrumentation/ProfilePaths/Makefile b/lib/Transforms/Instrumentation/ProfilePaths/Makefile deleted file mode 100644 index 5a7477caf3..0000000000 --- a/lib/Transforms/Instrumentation/ProfilePaths/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- lib/Transforms/Instrumentation/ProfilePaths/Makefile -*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file was developed by the LLVM research group and is distributed under -# the University of Illinois Open Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../../../.. -LIBRARYNAME = LLVMProfilePaths - -include $(LEVEL)/Makefile.common - diff --git a/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp b/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp deleted file mode 100644 index ce9e328c27..0000000000 --- a/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp +++ /dev/null @@ -1,252 +0,0 @@ -//===-- ProfilePaths.cpp - interface to insert instrumentation --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This inserts instrumentation for counting execution of paths though a given -// function Its implemented as a "Function" Pass, and called using opt -// -// This pass is implemented by using algorithms similar to -// 1."Efficient Path Profiling": Ball, T. and Larus, J. R., -// Proceedings of Micro-29, Dec 1996, Paris, France. -// 2."Efficiently Counting Program events with support for on-line -// "queries": Ball T., ACM Transactions on Programming Languages -// and systems, Sep 1994. -// -// The algorithms work on a Graph constructed over the nodes made from Basic -// Blocks: The transformations then take place on the constructed graph -// (implementation in Graph.cpp and GraphAuxiliary.cpp) and finally, appropriate -// instrumentation is placed over suitable edges. (code inserted through -// EdgeCode.cpp). -// -// The algorithm inserts code such that every acyclic path in the CFG of a -// function is identified through a unique number. the code insertion is optimal -// in the sense that its inserted over a minimal set of edges. Also, the -// algorithm makes sure than initialization, path increment and counter update -// can be collapsed into minimum number of edges. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Transforms/Instrumentation.h" -#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" -#include "llvm/Support/CFG.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "Graph.h" -#include -#include - -namespace llvm { - -struct ProfilePaths : public FunctionPass { - bool runOnFunction(Function &F); - - // Before this pass, make sure that there is only one - // entry and only one exit node for the function in the CFG of the function - // - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - } -}; - -static RegisterOpt X("paths", "Profile Paths"); - -FunctionPass *createProfilePathsPass() { return new ProfilePaths(); } - -static Node *findBB(std::vector &st, BasicBlock *BB){ - for(std::vector::iterator si=st.begin(); si!=st.end(); ++si){ - if(((*si)->getElement())==BB){ - return *si; - } - } - return NULL; -} - -//Per function pass for inserting counters and trigger code -bool ProfilePaths::runOnFunction(Function &F){ - - static int mn = -1; - static int CountCounter = 1; - if(F.isExternal()) { - return false; - } - - //increment counter for instrumented functions. mn is now function# - mn++; - - // Transform the cfg s.t. we have just one exit node - BasicBlock *ExitNode = - getAnalysis().getReturnBlock(); - - //iterating over BBs and making graph - std::vector nodes; - std::vector edges; - - Node *exitNode = 0, *startNode = 0; - - // The nodes must be uniquely identified: - // That is, no two nodes must hav same BB* - - for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE; ++BB) { - Node *nd=new Node(BB); - nodes.push_back(nd); - if(&*BB == ExitNode) - exitNode=nd; - if(BB==F.begin()) - startNode=nd; - } - - // now do it again to insert edges - for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE; ++BB){ - Node *nd=findBB(nodes, BB); - assert(nd && "No node for this edge!"); - - for(succ_iterator s=succ_begin(BB), se=succ_end(BB); s!=se; ++s){ - Node *nd2=findBB(nodes,*s); - assert(nd2 && "No node for this edge!"); - Edge ed(nd,nd2,0); - edges.push_back(ed); - } - } - - Graph g(nodes,edges, startNode, exitNode); - -#ifdef DEBUG_PATH_PROFILES - std::cerr<<"Original graph\n"; - printGraph(g); -#endif - - BasicBlock *fr = &F.front(); - - // The graph is made acyclic: this is done - // by removing back edges for now, and adding them later on - std::vector be; - std::map nodePriority; //it ranks nodes in depth first order traversal - g.getBackEdges(be, nodePriority); - -#ifdef DEBUG_PATH_PROFILES - std::cerr<<"BackEdges-------------\n"; - for (std::vector::iterator VI=be.begin(); VI!=be.end(); ++VI){ - printEdge(*VI); - cerr<<"\n"; - } - std::cerr<<"------\n"; -#endif - -#ifdef DEBUG_PATH_PROFILES - cerr<<"Backedges:"<b is a back edge - //Then we add 2 back edges for it: - //1. from root->b (in vector stDummy) - //and 2. from a->exit (in vector exDummy) - std::vector stDummy; - std::vector exDummy; - addDummyEdges(stDummy, exDummy, g, be); - -#ifdef DEBUG_PATH_PROFILES - std::cerr<<"After adding dummy edges\n"; - printGraph(g); -#endif - - // Now, every edge in the graph is assigned a weight - // This weight later adds on to assign path - // numbers to different paths in the graph - // All paths for now are acyclic, - // since no back edges in the graph now - // numPaths is the number of acyclic paths in the graph - int numPaths=valueAssignmentToEdges(g, nodePriority, be); - - //if(numPaths<=1) return false; - - static GlobalVariable *threshold = NULL; - static bool insertedThreshold = false; - - if(!insertedThreshold){ - threshold = new GlobalVariable(Type::IntTy, false, - GlobalValue::ExternalLinkage, 0, - "reopt_threshold"); - - F.getParent()->getGlobalList().push_back(threshold); - insertedThreshold = true; - } - - assert(threshold && "GlobalVariable threshold not defined!"); - - - if(fr->getParent()->getName() == "main"){ - //initialize threshold - - // FIXME: THIS IS HORRIBLY BROKEN. FUNCTION PASSES CANNOT DO THIS, EXCEPT - // IN THEIR INITIALIZE METHOD!! - Function *initialize = - F.getParent()->getOrInsertFunction("reoptimizerInitialize", Type::VoidTy, - PointerType::get(Type::IntTy), - (Type *)0); - - std::vector trargs; - trargs.push_back(threshold); - new CallInst(initialize, trargs, "", fr->begin()); - } - - - if(numPaths<=1 || numPaths >5000) return false; - -#ifdef DEBUG_PATH_PROFILES - printGraph(g); -#endif - - //create instruction allocation r and count - //r is the variable that'll act like an accumulator - //all along the path, we just add edge values to r - //and at the end, r reflects the path number - //count is an array: count[x] would store - //the number of executions of path numbered x - - Instruction *rVar=new - AllocaInst(Type::IntTy, - ConstantUInt::get(Type::UIntTy,1),"R"); - - //Instruction *countVar=new - //AllocaInst(Type::IntTy, - // ConstantUInt::get(Type::UIntTy, numPaths), "Count"); - - //initialize counter array! - std::vector arrayInitialize; - for(int xi=0; xi - -using std::vector; -using std::map; -using std::cerr; - -namespace llvm { - -//Routines to get the path trace! - -void getPathFrmNode(Node *n, vector &vBB, int pathNo, Graph &g, - vector &stDummy, vector &exDummy, - vector &be, - double strand){ - Graph::nodeList &nlist = g.getNodeList(n); - - //printGraph(g); - //std::cerr<<"Path No: "<weight>maxCount && NLI->weight<=pathNo){ - maxCount=NLI->weight; - nextRoot=NLI->element; - edgeRnd=NLI->randId; - if(isStart) - strand=NLI->randId; - } - } - - if(!isStart) - assert(strand!=-1 && "strand not assigned!"); - - assert(!(*nextRoot==*n && pathNo>0) && "No more BBs to go"); - assert(!(*nextRoot==*g.getExit() && pathNo-maxCount!=0) && "Reached exit"); - - vBB.push_back(n->getElement()); - - if(pathNo-maxCount==0 && *nextRoot==*g.getExit()){ - - //look for strnd and edgeRnd now: - bool has1=false, has2=false; - //check if exit has it - for(vector::iterator VI=exDummy.begin(), VE=exDummy.end(); VI!=VE; - ++VI){ - if(VI->getRandId()==edgeRnd){ - has2=true; - break; - } - } - - //check if start has it - for(vector::iterator VI=stDummy.begin(), VE=stDummy.end(); VI!=VE; - ++VI){ - if(VI->getRandId()==strand){ - has1=true; - break; - } - } - - if(has1){ - //find backedge with endpoint vBB[1] - for(vector::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){ - assert(vBB.size()>0 && "vector too small"); - if( VI->getSecond()->getElement() == vBB[1] ){ - //vBB[0]=VI->getFirst()->getElement(); - vBB.erase(vBB.begin()); - break; - } - } - } - - if(has2){ - //find backedge with startpoint vBB[vBB.size()-1] - for(vector::iterator VI=be.begin(), VE=be.end(); VI!=VE; ++VI){ - assert(vBB.size()>0 && "vector too small"); - if( VI->getFirst()->getElement() == vBB[vBB.size()-1] && - VI->getSecond()->getElement() == vBB[0]){ - //vBB.push_back(VI->getSecond()->getElement()); - break; - } - } - } - else - vBB.push_back(nextRoot->getElement()); - - return; - } - - assert(pathNo-maxCount>=0); - - return getPathFrmNode(nextRoot, vBB, pathNo-maxCount, g, stDummy, - exDummy, be, strand); -} - - -static Node *findBB(std::vector &st, BasicBlock *BB){ - for(std::vector::iterator si=st.begin(); si!=st.end(); ++si){ - if(((*si)->getElement())==BB){ - return *si; - } - } - return NULL; -} - -void getBBtrace(vector &vBB, int pathNo, Function *M){//, - // vector &instToErase){ - //step 1: create graph - //Transform the cfg s.t. we have just one exit node - - std::vector nodes; - std::vector edges; - Node *exitNode=0, *startNode=0; - - //Creat cfg just once for each function! - static std::map graphMap; - - //get backedges, exit and start edges for the graphs and store them - static std::map > stMap, exMap, beMap; - static std::map pathReg; //path register - - - if(!graphMap[M]){ - BasicBlock *ExitNode = 0; - for (Function::iterator I = M->begin(), E = M->end(); I != E; ++I){ - if (isa(I->getTerminator())) { - ExitNode = I; - break; - } - } - - assert(ExitNode!=0 && "exitnode not found"); - - //iterating over BBs and making graph - //The nodes must be uniquely identified: - //That is, no two nodes must hav same BB* - - //keep a map for trigger basicblocks! - std::map triggerBBs; - //First enter just nodes: later enter edges - for(Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){ - bool cont = false; - - if(BB->size()==3 || BB->size() ==2){ - for(BasicBlock::iterator II = BB->begin(), IE = BB->end(); - II != IE; ++II){ - if(CallInst *callInst = dyn_cast(II)){ - //std::cerr<<*callInst; - Function *calledFunction = callInst->getCalledFunction(); - if(calledFunction && calledFunction->getName() == "trigger"){ - triggerBBs[BB] = 9; - cont = true; - //std::cerr<<"Found trigger!\n"; - break; - } - } - } - } - - if(cont) - continue; - - // const Instruction *inst = BB->getInstList().begin(); - // if(isa(inst)){ - // Instruction *ii1 = BB->getInstList().begin(); - // CallInst *callInst = dyn_cast(ii1); - // if(callInst->getCalledFunction()->getName()=="trigger") - // continue; - // } - - Node *nd=new Node(BB); - nodes.push_back(nd); - if(&*BB==ExitNode) - exitNode=nd; - if(&*BB==&M->front()) - startNode=nd; - } - - assert(exitNode!=0 && startNode!=0 && "Start or exit not found!"); - - for (Function::iterator BB = M->begin(), BE=M->end(); BB != BE; ++BB){ - if(triggerBBs[BB] == 9) - continue; - - //if(BB->size()==3) - //if(CallInst *callInst = dyn_cast(BB->getInstList().begin())) - //if(callInst->getCalledFunction()->getName() == "trigger") - //continue; - - // if(BB->size()==2){ - // const Instruction *inst = BB->getInstList().begin(); - // if(isa(inst)){ - // Instruction *ii1 = BB->getInstList().begin(); - // CallInst *callInst = dyn_cast(ii1); - // if(callInst->getCalledFunction()->getName()=="trigger") - // continue; - // } - // } - - Node *nd=findBB(nodes, BB); - assert(nd && "No node for this edge!"); - - for(succ_iterator s=succ_begin(BB), se=succ_end(BB); s!=se; ++s){ - - if(triggerBBs[*s] == 9){ - //if(!pathReg[M]){ //Get the path register for this! - //if(BB->size()>8) - // if(LoadInst *ldInst = dyn_cast(BB->getInstList().begin())) - // pathReg[M] = ldInst->getPointerOperand(); - //} - continue; - } - //if((*s)->size()==3) - //if(CallInst *callInst = - // dyn_cast((*s)->getInstList().begin())) - // if(callInst->getCalledFunction()->getName() == "trigger") - // continue; - - // if((*s)->size()==2){ - // const Instruction *inst = (*s)->getInstList().begin(); - // if(isa(inst)){ - // Instruction *ii1 = (*s)->getInstList().begin(); - // CallInst *callInst = dyn_cast(ii1); - // if(callInst->getCalledFunction()->getName()=="trigger") - // continue; - // } - // } - - Node *nd2 = findBB(nodes,*s); - assert(nd2 && "No node for this edge!"); - Edge ed(nd,nd2,0); - edges.push_back(ed); - } - } - - graphMap[M]= new Graph(nodes,edges, startNode, exitNode); - - Graph *g = graphMap[M]; - - if (M->size() <= 1) return; //uninstrumented - - //step 2: getBackEdges - //vector be; - std::map nodePriority; - g->getBackEdges(beMap[M], nodePriority); - - //step 3: add dummy edges - //vector stDummy; - //vector exDummy; - addDummyEdges(stMap[M], exMap[M], *g, beMap[M]); - - //step 4: value assgn to edges - int numPaths = valueAssignmentToEdges(*g, nodePriority, beMap[M]); - } - - - //step 5: now travel from root, select max(edge) < pathNo, - //and go on until reach the exit - getPathFrmNode(graphMap[M]->getRoot(), vBB, pathNo, *graphMap[M], - stMap[M], exMap[M], beMap[M], -1); - - - //post process vBB to locate instructions to be erased - /* - if(pathReg[M]){ - for(vector::iterator VBI = vBB.begin(), VBE = vBB.end(); - VBI != VBE; ++VBI){ - for(BasicBlock::iterator BBI = (*VBI)->begin(), BBE = (*VBI)->end(); - BBI != BBE; ++BBI){ - if(LoadInst *ldInst = dyn_cast(BBI)){ - if(pathReg[M] == ldInst->getPointerOperand()) - instToErase.push_back(ldInst); - } - else if(StoreInst *stInst = dyn_cast(BBI)){ - if(pathReg[M] == stInst->getPointerOperand()) - instToErase.push_back(stInst); - } - } - } - } - */ -} - -} // End llvm namespace -- cgit v1.2.3