1 //===- PathProfiling.cpp - Inserts counters for path profiling ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass instruments functions for Ball-Larus path profiling. Ball-Larus
11 // profiling converts the CFG into a DAG by replacing backedges with edges
12 // from entry to the start block and from the end block to exit. The paths
13 // along the new DAG are enumrated, i.e. each path is given a path number.
14 // Edges are instrumented to increment the path number register, such that the
15 // path number register will equal the path number of the path taken at the
16 // exit.
17 //
18 // This file defines classes for building a CFG for use with different stages
19 // in the Ball-Larus path profiling instrumentation [Ball96]. The
20 // requirements are formatting the llvm CFG into the Ball-Larus DAG, path
21 // numbering, finding a spanning tree, moving increments from the spanning
22 // tree to chords.
23 //
24 // Terms:
25 // DAG - Directed Acyclic Graph.
26 // Ball-Larus DAG - A CFG with an entry node, an exit node, and backedges
27 // removed in the following manner. For every backedge
28 // v->w, insert edge ENTRY->w and edge v->EXIT.
29 // Path Number - The number corresponding to a specific path through a
30 // Ball-Larus DAG.
31 // Spanning Tree - A subgraph, S, is a spanning tree if S covers all
32 // vertices and is a tree.
33 // Chord - An edge not in the spanning tree.
34 //
35 // [Ball96]
36 // T. Ball and J. R. Larus. "Efficient Path Profiling."
37 // International Symposium on Microarchitecture, pages 46-57, 1996.
38 // http://portal.acm.org/citation.cfm?id=243857
39 //
40 // [Ball94]
41 // Thomas Ball. "Efficiently Counting Program Events with Support for
42 // On-line queries."
43 // ACM Transactions on Programmmg Languages and Systems, Vol 16, No 5,
44 // September 1994, Pages 1399-1410.
45 //===----------------------------------------------------------------------===//
46 #define DEBUG_TYPE "insert-path-profiling"
47
48 #include "llvm/Transforms/Instrumentation.h"
49 #include "ProfilingUtils.h"
50 #include "llvm/Analysis/PathNumbering.h"
51 #include "llvm/IR/Constants.h"
52 #include "llvm/IR/DerivedTypes.h"
53 #include "llvm/IR/InstrTypes.h"
54 #include "llvm/IR/Instructions.h"
55 #include "llvm/IR/LLVMContext.h"
56 #include "llvm/IR/Module.h"
57 #include "llvm/IR/TypeBuilder.h"
58 #include "llvm/Pass.h"
59 #include "llvm/Support/CFG.h"
60 #include "llvm/Support/CommandLine.h"
61 #include "llvm/Support/Compiler.h"
62 #include "llvm/Support/Debug.h"
63 #include "llvm/Support/raw_ostream.h"
64 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
65 #include <vector>
66
67 #define HASH_THRESHHOLD 100000
68
69 using namespace llvm;
70
71 namespace {
72 class BLInstrumentationNode;
73 class BLInstrumentationEdge;
74 class BLInstrumentationDag;
75
76 // ---------------------------------------------------------------------------
77 // BLInstrumentationNode extends BallLarusNode with member used by the
78 // instrumentation algortihms.
79 // ---------------------------------------------------------------------------
80 class BLInstrumentationNode : public BallLarusNode {
81 public:
82 // Creates a new BLInstrumentationNode from a BasicBlock.
83 BLInstrumentationNode(BasicBlock* BB);
84
85 // Get/sets the Value corresponding to the pathNumber register,
86 // constant or phinode. Used by the instrumentation code to remember
87 // path number Values.
88 Value* getStartingPathNumber();
89 void setStartingPathNumber(Value* pathNumber);
90
91 Value* getEndingPathNumber();
92 void setEndingPathNumber(Value* pathNumber);
93
94 // Get/set the PHINode Instruction for this node.
95 PHINode* getPathPHI();
96 void setPathPHI(PHINode* pathPHI);
97
98 private:
99
100 Value* _startingPathNumber; // The Value for the current pathNumber.
101 Value* _endingPathNumber; // The Value for the current pathNumber.
102 PHINode* _pathPHI; // The PHINode for current pathNumber.
103 };
104
105 // --------------------------------------------------------------------------
106 // BLInstrumentationEdge extends BallLarusEdge with data about the
107 // instrumentation that will end up on each edge.
108 // --------------------------------------------------------------------------
109 class BLInstrumentationEdge : public BallLarusEdge {
110 public:
111 BLInstrumentationEdge(BLInstrumentationNode* source,
112 BLInstrumentationNode* target);
113
114 // Sets the target node of this edge. Required to split edges.
115 void setTarget(BallLarusNode* node);
116
117 // Get/set whether edge is in the spanning tree.
118 bool isInSpanningTree() const;
119 void setIsInSpanningTree(bool isInSpanningTree);
120
121 // Get/ set whether this edge will be instrumented with a path number
122 // initialization.
123 bool isInitialization() const;
124 void setIsInitialization(bool isInitialization);
125
126 // Get/set whether this edge will be instrumented with a path counter
127 // increment. Notice this is incrementing the path counter
128 // corresponding to the path number register. The path number
129 // increment is determined by getIncrement().
130 bool isCounterIncrement() const;
131 void setIsCounterIncrement(bool isCounterIncrement);
132
133 // Get/set the path number increment that this edge will be instrumented
134 // with. This is distinct from the path counter increment and the
135 // weight. The counter increment counts the number of executions of
136 // some path, whereas the path number keeps track of which path number
137 // the program is on.
138 long getIncrement() const;
139 void setIncrement(long increment);
140
141 // Get/set whether the edge has been instrumented.
142 bool hasInstrumentation();
143 void setHasInstrumentation(bool hasInstrumentation);
144
145 // Returns the successor number of this edge in the source.
146 unsigned getSuccessorNumber();
147
148 private:
149 // The increment that the code will be instrumented with.
150 long long _increment;
151
152 // Whether this edge is in the spanning tree.
153 bool _isInSpanningTree;
154
155 // Whether this edge is an initialiation of the path number.
156 bool _isInitialization;
157
158 // Whether this edge is a path counter increment.
159 bool _isCounterIncrement;
160
161 // Whether this edge has been instrumented.
162 bool _hasInstrumentation;
163 };
164
165 // ---------------------------------------------------------------------------
166 // BLInstrumentationDag extends BallLarusDag with algorithms that
167 // determine where instrumentation should be placed.
168 // ---------------------------------------------------------------------------
169 class BLInstrumentationDag : public BallLarusDag {
170 public:
171 BLInstrumentationDag(Function &F);
172
173 // Returns the Exit->Root edge. This edge is required for creating
174 // directed cycles in the algorithm for moving instrumentation off of
175 // the spanning tree
176 BallLarusEdge* getExitRootEdge();
177
178 // Returns an array of phony edges which mark those nodes
179 // with function calls
180 BLEdgeVector getCallPhonyEdges();
181
182 // Gets/sets the path counter array
183 GlobalVariable* getCounterArray();
184 void setCounterArray(GlobalVariable* c);
185
186 // Calculates the increments for the chords, thereby removing
187 // instrumentation from the spanning tree edges. Implementation is based
188 // on the algorithm in Figure 4 of [Ball94]
189 void calculateChordIncrements();
190
191 // Updates the state when an edge has been split
192 void splitUpdate(BLInstrumentationEdge* formerEdge, BasicBlock* newBlock);
193
194 // Calculates a spanning tree of the DAG ignoring cycles. Whichever
195 // edges are in the spanning tree will not be instrumented, but this
196 // implementation does not try to minimize the instrumentation overhead
197 // by trying to find hot edges.
198 void calculateSpanningTree();
199
200 // Pushes initialization further down in order to group the first
201 // increment and initialization.
202 void pushInitialization();
203
204 // Pushes the path counter increments up in order to group the last path
205 // number increment.
206 void pushCounters();
207
208 // Removes phony edges from the successor list of the source, and the
209 // predecessor list of the target.
210 void unlinkPhony();
211
212 // Generate dot graph for the function
213 void generateDotGraph();
214
215 protected:
216 // BLInstrumentationDag creates BLInstrumentationNode objects in this
217 // method overriding the creation of BallLarusNode objects.
218 //
219 // Allows subclasses to determine which type of Node is created.
220 // Override this method to produce subclasses of BallLarusNode if
221 // necessary.
222 virtual BallLarusNode* createNode(BasicBlock* BB);
223
224 // BLInstrumentationDag create BLInstrumentationEdges.
225 //
226 // Allows subclasses to determine which type of Edge is created.
227 // Override this method to produce subclasses of BallLarusEdge if
228 // necessary. Parameters source and target will have been created by
229 // createNode and can be cast to the subclass of BallLarusNode*
230 // returned by createNode.
231 virtual BallLarusEdge* createEdge(
232 BallLarusNode* source, BallLarusNode* target, unsigned edgeNumber);
233
234 private:
235 BLEdgeVector _treeEdges; // All edges in the spanning tree.
236 BLEdgeVector _chordEdges; // All edges not in the spanning tree.
237 GlobalVariable* _counterArray; // Array to store path counters
238
239 // Removes the edge from the appropriate predecessor and successor lists.
240 void unlinkEdge(BallLarusEdge* edge);
241
242 // Makes an edge part of the spanning tree.
243 void makeEdgeSpanning(BLInstrumentationEdge* edge);
244
245 // Pushes initialization and calls itself recursively.
246 void pushInitializationFromEdge(BLInstrumentationEdge* edge);
247
248 // Pushes path counter increments up recursively.
249 void pushCountersFromEdge(BLInstrumentationEdge* edge);
250
251 // Depth first algorithm for determining the chord increments.f
252 void calculateChordIncrementsDfs(
253 long weight, BallLarusNode* v, BallLarusEdge* e);
254
255 // Determines the relative direction of two edges.
256 int calculateChordIncrementsDir(BallLarusEdge* e, BallLarusEdge* f);
257 };
258
259 // ---------------------------------------------------------------------------
260 // PathProfiler is a module pass which instruments path profiling instructions
261 // ---------------------------------------------------------------------------
262 class PathProfiler : public ModulePass {
263 private:
264 // Current context for multi threading support.
265 LLVMContext* Context;
266
267 // Which function are we currently instrumenting
268 unsigned currentFunctionNumber;
269
270 // The function prototype in the profiling runtime for incrementing a
271 // single path counter in a hash table.
272 Constant* llvmIncrementHashFunction;
273 Constant* llvmDecrementHashFunction;
274
275 // Instruments each function with path profiling. 'main' is instrumented
276 // with code to save the profile to disk.
277 bool runOnModule(Module &M);
278
279 // Analyzes the function for Ball-Larus path profiling, and inserts code.
280 void runOnFunction(std::vector<Constant*> &ftInit, Function &F, Module &M);
281
282 // Creates an increment constant representing incr.
283 ConstantInt* createIncrementConstant(long incr, int bitsize);
284
285 // Creates an increment constant representing the value in
286 // edge->getIncrement().
287 ConstantInt* createIncrementConstant(BLInstrumentationEdge* edge);
288
289 // Finds the insertion point after pathNumber in block. PathNumber may
290 // be NULL.
291 BasicBlock::iterator getInsertionPoint(
292 BasicBlock* block, Value* pathNumber);
293
294 // Inserts source's pathNumber Value* into target. Target may or may not
295 // have multiple predecessors, and may or may not have its phiNode
296 // initalized.
297 void pushValueIntoNode(
298 BLInstrumentationNode* source, BLInstrumentationNode* target);
299
300 // Inserts source's pathNumber Value* into the appropriate slot of
301 // target's phiNode.
302 void pushValueIntoPHI(
303 BLInstrumentationNode* target, BLInstrumentationNode* source);
304
305 // The Value* in node, oldVal, is updated with a Value* correspodning to
306 // oldVal + addition.
307 void insertNumberIncrement(BLInstrumentationNode* node, Value* addition,
308 bool atBeginning);
309
310 // Creates a counter increment in the given node. The Value* in node is
311 // taken as the index into a hash table.
312 void insertCounterIncrement(
313 Value* incValue,
314 BasicBlock::iterator insertPoint,
315 BLInstrumentationDag* dag,
316 bool increment = true);
317
318 // A PHINode is created in the node, and its values initialized to -1U.
319 void preparePHI(BLInstrumentationNode* node);
320
321 // Inserts instrumentation for the given edge
322 //
323 // Pre: The edge's source node has pathNumber set if edge is non zero
324 // path number increment.
325 //
326 // Post: Edge's target node has a pathNumber set to the path number Value
327 // corresponding to the value of the path register after edge's
328 // execution.
329 void insertInstrumentationStartingAt(
330 BLInstrumentationEdge* edge,
331 BLInstrumentationDag* dag);
332
333 // If this edge is a critical edge, then inserts a node at this edge.
334 // This edge becomes the first edge, and a new BallLarusEdge is created.
335 bool splitCritical(BLInstrumentationEdge* edge, BLInstrumentationDag* dag);
336
337 // Inserts instrumentation according to the marked edges in dag. Phony
338 // edges must be unlinked from the DAG, but accessible from the
339 // backedges. Dag must have initializations, path number increments, and
340 // counter increments present.
341 //
342 // Counter storage is created here.
343 void insertInstrumentation( BLInstrumentationDag& dag, Module &M);
344
345 public:
346 static char ID; // Pass identification, replacement for typeid
PathProfiler()347 PathProfiler() : ModulePass(ID) {
348 initializePathProfilerPass(*PassRegistry::getPassRegistry());
349 }
350
getPassName() const351 virtual const char *getPassName() const {
352 return "Path Profiler";
353 }
354 };
355 } // end anonymous namespace
356
357 // Should we print the dot-graphs
358 static cl::opt<bool> DotPathDag("path-profile-pathdag", cl::Hidden,
359 cl::desc("Output the path profiling DAG for each function."));
360
361 // Register the path profiler as a pass
362 char PathProfiler::ID = 0;
363 INITIALIZE_PASS(PathProfiler, "insert-path-profiling",
364 "Insert instrumentation for Ball-Larus path profiling",
365 false, false)
366
createPathProfilerPass()367 ModulePass *llvm::createPathProfilerPass() { return new PathProfiler(); }
368
369 namespace llvm {
370 class PathProfilingFunctionTable {};
371
372 // Type for global array storing references to hashes or arrays
373 template<bool xcompile> class TypeBuilder<PathProfilingFunctionTable,
374 xcompile> {
375 public:
get(LLVMContext & C)376 static StructType *get(LLVMContext& C) {
377 return( StructType::get(
378 TypeBuilder<types::i<32>, xcompile>::get(C), // type
379 TypeBuilder<types::i<32>, xcompile>::get(C), // array size
380 TypeBuilder<types::i<8>*, xcompile>::get(C), // array/hash ptr
381 NULL));
382 }
383 };
384
385 typedef TypeBuilder<PathProfilingFunctionTable, true>
386 ftEntryTypeBuilder;
387
388 // BallLarusEdge << operator overloading
389 raw_ostream& operator<<(raw_ostream& os,
390 const BLInstrumentationEdge& edge)
391 LLVM_ATTRIBUTE_USED;
operator <<(raw_ostream & os,const BLInstrumentationEdge & edge)392 raw_ostream& operator<<(raw_ostream& os,
393 const BLInstrumentationEdge& edge) {
394 os << "[" << edge.getSource()->getName() << " -> "
395 << edge.getTarget()->getName() << "] init: "
396 << (edge.isInitialization() ? "yes" : "no")
397 << " incr:" << edge.getIncrement() << " cinc: "
398 << (edge.isCounterIncrement() ? "yes" : "no");
399 return(os);
400 }
401 }
402
403 // Creates a new BLInstrumentationNode from a BasicBlock.
BLInstrumentationNode(BasicBlock * BB)404 BLInstrumentationNode::BLInstrumentationNode(BasicBlock* BB) :
405 BallLarusNode(BB),
406 _startingPathNumber(NULL), _endingPathNumber(NULL), _pathPHI(NULL) {}
407
408 // Constructor for BLInstrumentationEdge.
BLInstrumentationEdge(BLInstrumentationNode * source,BLInstrumentationNode * target)409 BLInstrumentationEdge::BLInstrumentationEdge(BLInstrumentationNode* source,
410 BLInstrumentationNode* target)
411 : BallLarusEdge(source, target, 0),
412 _increment(0), _isInSpanningTree(false), _isInitialization(false),
413 _isCounterIncrement(false), _hasInstrumentation(false) {}
414
415 // Sets the target node of this edge. Required to split edges.
setTarget(BallLarusNode * node)416 void BLInstrumentationEdge::setTarget(BallLarusNode* node) {
417 _target = node;
418 }
419
420 // Returns whether this edge is in the spanning tree.
isInSpanningTree() const421 bool BLInstrumentationEdge::isInSpanningTree() const {
422 return(_isInSpanningTree);
423 }
424
425 // Sets whether this edge is in the spanning tree.
setIsInSpanningTree(bool isInSpanningTree)426 void BLInstrumentationEdge::setIsInSpanningTree(bool isInSpanningTree) {
427 _isInSpanningTree = isInSpanningTree;
428 }
429
430 // Returns whether this edge will be instrumented with a path number
431 // initialization.
isInitialization() const432 bool BLInstrumentationEdge::isInitialization() const {
433 return(_isInitialization);
434 }
435
436 // Sets whether this edge will be instrumented with a path number
437 // initialization.
setIsInitialization(bool isInitialization)438 void BLInstrumentationEdge::setIsInitialization(bool isInitialization) {
439 _isInitialization = isInitialization;
440 }
441
442 // Returns whether this edge will be instrumented with a path counter
443 // increment. Notice this is incrementing the path counter
444 // corresponding to the path number register. The path number
445 // increment is determined by getIncrement().
isCounterIncrement() const446 bool BLInstrumentationEdge::isCounterIncrement() const {
447 return(_isCounterIncrement);
448 }
449
450 // Sets whether this edge will be instrumented with a path counter
451 // increment.
setIsCounterIncrement(bool isCounterIncrement)452 void BLInstrumentationEdge::setIsCounterIncrement(bool isCounterIncrement) {
453 _isCounterIncrement = isCounterIncrement;
454 }
455
456 // Gets the path number increment that this edge will be instrumented
457 // with. This is distinct from the path counter increment and the
458 // weight. The counter increment is counts the number of executions of
459 // some path, whereas the path number keeps track of which path number
460 // the program is on.
getIncrement() const461 long BLInstrumentationEdge::getIncrement() const {
462 return(_increment);
463 }
464
465 // Set whether this edge will be instrumented with a path number
466 // increment.
setIncrement(long increment)467 void BLInstrumentationEdge::setIncrement(long increment) {
468 _increment = increment;
469 }
470
471 // True iff the edge has already been instrumented.
hasInstrumentation()472 bool BLInstrumentationEdge::hasInstrumentation() {
473 return(_hasInstrumentation);
474 }
475
476 // Set whether this edge has been instrumented.
setHasInstrumentation(bool hasInstrumentation)477 void BLInstrumentationEdge::setHasInstrumentation(bool hasInstrumentation) {
478 _hasInstrumentation = hasInstrumentation;
479 }
480
481 // Returns the successor number of this edge in the source.
getSuccessorNumber()482 unsigned BLInstrumentationEdge::getSuccessorNumber() {
483 BallLarusNode* sourceNode = getSource();
484 BallLarusNode* targetNode = getTarget();
485 BasicBlock* source = sourceNode->getBlock();
486 BasicBlock* target = targetNode->getBlock();
487
488 if(source == NULL || target == NULL)
489 return(0);
490
491 TerminatorInst* terminator = source->getTerminator();
492
493 unsigned i;
494 for(i=0; i < terminator->getNumSuccessors(); i++) {
495 if(terminator->getSuccessor(i) == target)
496 break;
497 }
498
499 return(i);
500 }
501
502 // BLInstrumentationDag constructor initializes a DAG for the given Function.
BLInstrumentationDag(Function & F)503 BLInstrumentationDag::BLInstrumentationDag(Function &F) : BallLarusDag(F),
504 _counterArray(0) {
505 }
506
507 // Returns the Exit->Root edge. This edge is required for creating
508 // directed cycles in the algorithm for moving instrumentation off of
509 // the spanning tree
getExitRootEdge()510 BallLarusEdge* BLInstrumentationDag::getExitRootEdge() {
511 BLEdgeIterator erEdge = getExit()->succBegin();
512 return(*erEdge);
513 }
514
getCallPhonyEdges()515 BLEdgeVector BLInstrumentationDag::getCallPhonyEdges () {
516 BLEdgeVector callEdges;
517
518 for( BLEdgeIterator edge = _edges.begin(), end = _edges.end();
519 edge != end; edge++ ) {
520 if( (*edge)->getType() == BallLarusEdge::CALLEDGE_PHONY )
521 callEdges.push_back(*edge);
522 }
523
524 return callEdges;
525 }
526
527 // Gets the path counter array
getCounterArray()528 GlobalVariable* BLInstrumentationDag::getCounterArray() {
529 return _counterArray;
530 }
531
setCounterArray(GlobalVariable * c)532 void BLInstrumentationDag::setCounterArray(GlobalVariable* c) {
533 _counterArray = c;
534 }
535
536 // Calculates the increment for the chords, thereby removing
537 // instrumentation from the spanning tree edges. Implementation is based on
538 // the algorithm in Figure 4 of [Ball94]
calculateChordIncrements()539 void BLInstrumentationDag::calculateChordIncrements() {
540 calculateChordIncrementsDfs(0, getRoot(), NULL);
541
542 BLInstrumentationEdge* chord;
543 for(BLEdgeIterator chordEdge = _chordEdges.begin(),
544 end = _chordEdges.end(); chordEdge != end; chordEdge++) {
545 chord = (BLInstrumentationEdge*) *chordEdge;
546 chord->setIncrement(chord->getIncrement() + chord->getWeight());
547 }
548 }
549
550 // Updates the state when an edge has been split
splitUpdate(BLInstrumentationEdge * formerEdge,BasicBlock * newBlock)551 void BLInstrumentationDag::splitUpdate(BLInstrumentationEdge* formerEdge,
552 BasicBlock* newBlock) {
553 BallLarusNode* oldTarget = formerEdge->getTarget();
554 BallLarusNode* newNode = addNode(newBlock);
555 formerEdge->setTarget(newNode);
556 newNode->addPredEdge(formerEdge);
557
558 DEBUG(dbgs() << " Edge split: " << *formerEdge << "\n");
559
560 oldTarget->removePredEdge(formerEdge);
561 BallLarusEdge* newEdge = addEdge(newNode, oldTarget,0);
562
563 if( formerEdge->getType() == BallLarusEdge::BACKEDGE ||
564 formerEdge->getType() == BallLarusEdge::SPLITEDGE) {
565 newEdge->setType(formerEdge->getType());
566 newEdge->setPhonyRoot(formerEdge->getPhonyRoot());
567 newEdge->setPhonyExit(formerEdge->getPhonyExit());
568 formerEdge->setType(BallLarusEdge::NORMAL);
569 formerEdge->setPhonyRoot(NULL);
570 formerEdge->setPhonyExit(NULL);
571 }
572 }
573
574 // Calculates a spanning tree of the DAG ignoring cycles. Whichever
575 // edges are in the spanning tree will not be instrumented, but this
576 // implementation does not try to minimize the instrumentation overhead
577 // by trying to find hot edges.
calculateSpanningTree()578 void BLInstrumentationDag::calculateSpanningTree() {
579 std::stack<BallLarusNode*> dfsStack;
580
581 for(BLNodeIterator nodeIt = _nodes.begin(), end = _nodes.end();
582 nodeIt != end; nodeIt++) {
583 (*nodeIt)->setColor(BallLarusNode::WHITE);
584 }
585
586 dfsStack.push(getRoot());
587 while(dfsStack.size() > 0) {
588 BallLarusNode* node = dfsStack.top();
589 dfsStack.pop();
590
591 if(node->getColor() == BallLarusNode::WHITE)
592 continue;
593
594 BallLarusNode* nextNode;
595 bool forward = true;
596 BLEdgeIterator succEnd = node->succEnd();
597
598 node->setColor(BallLarusNode::WHITE);
599 // first iterate over successors then predecessors
600 for(BLEdgeIterator edge = node->succBegin(), predEnd = node->predEnd();
601 edge != predEnd; edge++) {
602 if(edge == succEnd) {
603 edge = node->predBegin();
604 forward = false;
605 }
606
607 // Ignore split edges
608 if ((*edge)->getType() == BallLarusEdge::SPLITEDGE)
609 continue;
610
611 nextNode = forward? (*edge)->getTarget(): (*edge)->getSource();
612 if(nextNode->getColor() != BallLarusNode::WHITE) {
613 nextNode->setColor(BallLarusNode::WHITE);
614 makeEdgeSpanning((BLInstrumentationEdge*)(*edge));
615 }
616 }
617 }
618
619 for(BLEdgeIterator edge = _edges.begin(), end = _edges.end();
620 edge != end; edge++) {
621 BLInstrumentationEdge* instEdge = (BLInstrumentationEdge*) (*edge);
622 // safe since createEdge is overriden
623 if(!instEdge->isInSpanningTree() && (*edge)->getType()
624 != BallLarusEdge::SPLITEDGE)
625 _chordEdges.push_back(instEdge);
626 }
627 }
628
629 // Pushes initialization further down in order to group the first
630 // increment and initialization.
pushInitialization()631 void BLInstrumentationDag::pushInitialization() {
632 BLInstrumentationEdge* exitRootEdge =
633 (BLInstrumentationEdge*) getExitRootEdge();
634 exitRootEdge->setIsInitialization(true);
635 pushInitializationFromEdge(exitRootEdge);
636 }
637
638 // Pushes the path counter increments up in order to group the last path
639 // number increment.
pushCounters()640 void BLInstrumentationDag::pushCounters() {
641 BLInstrumentationEdge* exitRootEdge =
642 (BLInstrumentationEdge*) getExitRootEdge();
643 exitRootEdge->setIsCounterIncrement(true);
644 pushCountersFromEdge(exitRootEdge);
645 }
646
647 // Removes phony edges from the successor list of the source, and the
648 // predecessor list of the target.
unlinkPhony()649 void BLInstrumentationDag::unlinkPhony() {
650 BallLarusEdge* edge;
651
652 for(BLEdgeIterator next = _edges.begin(),
653 end = _edges.end(); next != end; next++) {
654 edge = (*next);
655
656 if( edge->getType() == BallLarusEdge::BACKEDGE_PHONY ||
657 edge->getType() == BallLarusEdge::SPLITEDGE_PHONY ||
658 edge->getType() == BallLarusEdge::CALLEDGE_PHONY ) {
659 unlinkEdge(edge);
660 }
661 }
662 }
663
664 // Generate a .dot graph to represent the DAG and pathNumbers
generateDotGraph()665 void BLInstrumentationDag::generateDotGraph() {
666 std::string errorInfo;
667 std::string functionName = getFunction().getName().str();
668 std::string filename = "pathdag." + functionName + ".dot";
669
670 DEBUG (dbgs() << "Writing '" << filename << "'...\n");
671 raw_fd_ostream dotFile(filename.c_str(), errorInfo);
672
673 if (!errorInfo.empty()) {
674 errs() << "Error opening '" << filename.c_str() <<"' for writing!";
675 errs() << "\n";
676 return;
677 }
678
679 dotFile << "digraph " << functionName << " {\n";
680
681 for( BLEdgeIterator edge = _edges.begin(), end = _edges.end();
682 edge != end; edge++) {
683 std::string sourceName = (*edge)->getSource()->getName();
684 std::string targetName = (*edge)->getTarget()->getName();
685
686 dotFile << "\t\"" << sourceName.c_str() << "\" -> \""
687 << targetName.c_str() << "\" ";
688
689 long inc = ((BLInstrumentationEdge*)(*edge))->getIncrement();
690
691 switch( (*edge)->getType() ) {
692 case BallLarusEdge::NORMAL:
693 dotFile << "[label=" << inc << "] [color=black];\n";
694 break;
695
696 case BallLarusEdge::BACKEDGE:
697 dotFile << "[color=cyan];\n";
698 break;
699
700 case BallLarusEdge::BACKEDGE_PHONY:
701 dotFile << "[label=" << inc
702 << "] [color=blue];\n";
703 break;
704
705 case BallLarusEdge::SPLITEDGE:
706 dotFile << "[color=violet];\n";
707 break;
708
709 case BallLarusEdge::SPLITEDGE_PHONY:
710 dotFile << "[label=" << inc << "] [color=red];\n";
711 break;
712
713 case BallLarusEdge::CALLEDGE_PHONY:
714 dotFile << "[label=" << inc << "] [color=green];\n";
715 break;
716 }
717 }
718
719 dotFile << "}\n";
720 }
721
722 // Allows subclasses to determine which type of Node is created.
723 // Override this method to produce subclasses of BallLarusNode if
724 // necessary. The destructor of BallLarusDag will call free on each pointer
725 // created.
createNode(BasicBlock * BB)726 BallLarusNode* BLInstrumentationDag::createNode(BasicBlock* BB) {
727 return( new BLInstrumentationNode(BB) );
728 }
729
730 // Allows subclasses to determine which type of Edge is created.
731 // Override this method to produce subclasses of BallLarusEdge if
732 // necessary. The destructor of BallLarusDag will call free on each pointer
733 // created.
createEdge(BallLarusNode * source,BallLarusNode * target,unsigned edgeNumber)734 BallLarusEdge* BLInstrumentationDag::createEdge(BallLarusNode* source,
735 BallLarusNode* target, unsigned edgeNumber) {
736 // One can cast from BallLarusNode to BLInstrumentationNode since createNode
737 // is overriden to produce BLInstrumentationNode.
738 return( new BLInstrumentationEdge((BLInstrumentationNode*)source,
739 (BLInstrumentationNode*)target) );
740 }
741
742 // Sets the Value corresponding to the pathNumber register, constant,
743 // or phinode. Used by the instrumentation code to remember path
744 // number Values.
getStartingPathNumber()745 Value* BLInstrumentationNode::getStartingPathNumber(){
746 return(_startingPathNumber);
747 }
748
749 // Sets the Value of the pathNumber. Used by the instrumentation code.
setStartingPathNumber(Value * pathNumber)750 void BLInstrumentationNode::setStartingPathNumber(Value* pathNumber) {
751 DEBUG(dbgs() << " SPN-" << getName() << " <-- " << (pathNumber ?
752 pathNumber->getName() :
753 "unused") << "\n");
754 _startingPathNumber = pathNumber;
755 }
756
getEndingPathNumber()757 Value* BLInstrumentationNode::getEndingPathNumber(){
758 return(_endingPathNumber);
759 }
760
setEndingPathNumber(Value * pathNumber)761 void BLInstrumentationNode::setEndingPathNumber(Value* pathNumber) {
762 DEBUG(dbgs() << " EPN-" << getName() << " <-- "
763 << (pathNumber ? pathNumber->getName() : "unused") << "\n");
764 _endingPathNumber = pathNumber;
765 }
766
767 // Get the PHINode Instruction for this node. Used by instrumentation
768 // code.
getPathPHI()769 PHINode* BLInstrumentationNode::getPathPHI() {
770 return(_pathPHI);
771 }
772
773 // Set the PHINode Instruction for this node. Used by instrumentation
774 // code.
setPathPHI(PHINode * pathPHI)775 void BLInstrumentationNode::setPathPHI(PHINode* pathPHI) {
776 _pathPHI = pathPHI;
777 }
778
779 // Removes the edge from the appropriate predecessor and successor
780 // lists.
unlinkEdge(BallLarusEdge * edge)781 void BLInstrumentationDag::unlinkEdge(BallLarusEdge* edge) {
782 if(edge == getExitRootEdge())
783 DEBUG(dbgs() << " Removing exit->root edge\n");
784
785 edge->getSource()->removeSuccEdge(edge);
786 edge->getTarget()->removePredEdge(edge);
787 }
788
789 // Makes an edge part of the spanning tree.
makeEdgeSpanning(BLInstrumentationEdge * edge)790 void BLInstrumentationDag::makeEdgeSpanning(BLInstrumentationEdge* edge) {
791 edge->setIsInSpanningTree(true);
792 _treeEdges.push_back(edge);
793 }
794
795 // Pushes initialization and calls itself recursively.
pushInitializationFromEdge(BLInstrumentationEdge * edge)796 void BLInstrumentationDag::pushInitializationFromEdge(
797 BLInstrumentationEdge* edge) {
798 BallLarusNode* target;
799
800 target = edge->getTarget();
801 if( target->getNumberPredEdges() > 1 || target == getExit() ) {
802 return;
803 } else {
804 for(BLEdgeIterator next = target->succBegin(),
805 end = target->succEnd(); next != end; next++) {
806 BLInstrumentationEdge* intoEdge = (BLInstrumentationEdge*) *next;
807
808 // Skip split edges
809 if (intoEdge->getType() == BallLarusEdge::SPLITEDGE)
810 continue;
811
812 intoEdge->setIncrement(intoEdge->getIncrement() +
813 edge->getIncrement());
814 intoEdge->setIsInitialization(true);
815 pushInitializationFromEdge(intoEdge);
816 }
817
818 edge->setIncrement(0);
819 edge->setIsInitialization(false);
820 }
821 }
822
823 // Pushes path counter increments up recursively.
pushCountersFromEdge(BLInstrumentationEdge * edge)824 void BLInstrumentationDag::pushCountersFromEdge(BLInstrumentationEdge* edge) {
825 BallLarusNode* source;
826
827 source = edge->getSource();
828 if(source->getNumberSuccEdges() > 1 || source == getRoot()
829 || edge->isInitialization()) {
830 return;
831 } else {
832 for(BLEdgeIterator previous = source->predBegin(),
833 end = source->predEnd(); previous != end; previous++) {
834 BLInstrumentationEdge* fromEdge = (BLInstrumentationEdge*) *previous;
835
836 // Skip split edges
837 if (fromEdge->getType() == BallLarusEdge::SPLITEDGE)
838 continue;
839
840 fromEdge->setIncrement(fromEdge->getIncrement() +
841 edge->getIncrement());
842 fromEdge->setIsCounterIncrement(true);
843 pushCountersFromEdge(fromEdge);
844 }
845
846 edge->setIncrement(0);
847 edge->setIsCounterIncrement(false);
848 }
849 }
850
851 // Depth first algorithm for determining the chord increments.
calculateChordIncrementsDfs(long weight,BallLarusNode * v,BallLarusEdge * e)852 void BLInstrumentationDag::calculateChordIncrementsDfs(long weight,
853 BallLarusNode* v, BallLarusEdge* e) {
854 BLInstrumentationEdge* f;
855
856 for(BLEdgeIterator treeEdge = _treeEdges.begin(),
857 end = _treeEdges.end(); treeEdge != end; treeEdge++) {
858 f = (BLInstrumentationEdge*) *treeEdge;
859 if(e != f && v == f->getTarget()) {
860 calculateChordIncrementsDfs(
861 calculateChordIncrementsDir(e,f)*(weight) +
862 f->getWeight(), f->getSource(), f);
863 }
864 if(e != f && v == f->getSource()) {
865 calculateChordIncrementsDfs(
866 calculateChordIncrementsDir(e,f)*(weight) +
867 f->getWeight(), f->getTarget(), f);
868 }
869 }
870
871 for(BLEdgeIterator chordEdge = _chordEdges.begin(),
872 end = _chordEdges.end(); chordEdge != end; chordEdge++) {
873 f = (BLInstrumentationEdge*) *chordEdge;
874 if(v == f->getSource() || v == f->getTarget()) {
875 f->setIncrement(f->getIncrement() +
876 calculateChordIncrementsDir(e,f)*weight);
877 }
878 }
879 }
880
881 // Determines the relative direction of two edges.
calculateChordIncrementsDir(BallLarusEdge * e,BallLarusEdge * f)882 int BLInstrumentationDag::calculateChordIncrementsDir(BallLarusEdge* e,
883 BallLarusEdge* f) {
884 if( e == NULL)
885 return(1);
886 else if(e->getSource() == f->getTarget()
887 || e->getTarget() == f->getSource())
888 return(1);
889
890 return(-1);
891 }
892
893 // Creates an increment constant representing incr.
createIncrementConstant(long incr,int bitsize)894 ConstantInt* PathProfiler::createIncrementConstant(long incr,
895 int bitsize) {
896 return(ConstantInt::get(IntegerType::get(*Context, 32), incr));
897 }
898
899 // Creates an increment constant representing the value in
900 // edge->getIncrement().
createIncrementConstant(BLInstrumentationEdge * edge)901 ConstantInt* PathProfiler::createIncrementConstant(
902 BLInstrumentationEdge* edge) {
903 return(createIncrementConstant(edge->getIncrement(), 32));
904 }
905
906 // Finds the insertion point after pathNumber in block. PathNumber may
907 // be NULL.
getInsertionPoint(BasicBlock * block,Value * pathNumber)908 BasicBlock::iterator PathProfiler::getInsertionPoint(BasicBlock* block, Value*
909 pathNumber) {
910 if(pathNumber == NULL || isa<ConstantInt>(pathNumber)
911 || (((Instruction*)(pathNumber))->getParent()) != block) {
912 return(block->getFirstInsertionPt());
913 } else {
914 Instruction* pathNumberInst = (Instruction*) (pathNumber);
915 BasicBlock::iterator insertPoint;
916 BasicBlock::iterator end = block->end();
917
918 for(insertPoint = block->begin();
919 insertPoint != end; insertPoint++) {
920 Instruction* insertInst = &(*insertPoint);
921
922 if(insertInst == pathNumberInst)
923 return(++insertPoint);
924 }
925
926 return(insertPoint);
927 }
928 }
929
930 // A PHINode is created in the node, and its values initialized to -1U.
preparePHI(BLInstrumentationNode * node)931 void PathProfiler::preparePHI(BLInstrumentationNode* node) {
932 BasicBlock* block = node->getBlock();
933 BasicBlock::iterator insertPoint = block->getFirstInsertionPt();
934 pred_iterator PB = pred_begin(node->getBlock()),
935 PE = pred_end(node->getBlock());
936 PHINode* phi = PHINode::Create(Type::getInt32Ty(*Context),
937 std::distance(PB, PE), "pathNumber",
938 insertPoint );
939 node->setPathPHI(phi);
940 node->setStartingPathNumber(phi);
941 node->setEndingPathNumber(phi);
942
943 for(pred_iterator predIt = PB; predIt != PE; predIt++) {
944 BasicBlock* pred = (*predIt);
945
946 if(pred != NULL)
947 phi->addIncoming(createIncrementConstant((long)-1, 32), pred);
948 }
949 }
950
951 // Inserts source's pathNumber Value* into target. Target may or may not
952 // have multiple predecessors, and may or may not have its phiNode
953 // initalized.
pushValueIntoNode(BLInstrumentationNode * source,BLInstrumentationNode * target)954 void PathProfiler::pushValueIntoNode(BLInstrumentationNode* source,
955 BLInstrumentationNode* target) {
956 if(target->getBlock() == NULL)
957 return;
958
959
960 if(target->getNumberPredEdges() <= 1) {
961 assert(target->getStartingPathNumber() == NULL &&
962 "Target already has path number");
963 target->setStartingPathNumber(source->getEndingPathNumber());
964 target->setEndingPathNumber(source->getEndingPathNumber());
965 DEBUG(dbgs() << " Passing path number"
966 << (source->getEndingPathNumber() ? "" : " (null)")
967 << " value through.\n");
968 } else {
969 if(target->getPathPHI() == NULL) {
970 DEBUG(dbgs() << " Initializing PHI node for block '"
971 << target->getName() << "'\n");
972 preparePHI(target);
973 }
974 pushValueIntoPHI(target, source);
975 DEBUG(dbgs() << " Passing number value into PHI for block '"
976 << target->getName() << "'\n");
977 }
978 }
979
980 // Inserts source's pathNumber Value* into the appropriate slot of
981 // target's phiNode.
pushValueIntoPHI(BLInstrumentationNode * target,BLInstrumentationNode * source)982 void PathProfiler::pushValueIntoPHI(BLInstrumentationNode* target,
983 BLInstrumentationNode* source) {
984 PHINode* phi = target->getPathPHI();
985 assert(phi != NULL && " Tried to push value into node with PHI, but node"
986 " actually had no PHI.");
987 phi->removeIncomingValue(source->getBlock(), false);
988 phi->addIncoming(source->getEndingPathNumber(), source->getBlock());
989 }
990
991 // The Value* in node, oldVal, is updated with a Value* correspodning to
992 // oldVal + addition.
insertNumberIncrement(BLInstrumentationNode * node,Value * addition,bool atBeginning)993 void PathProfiler::insertNumberIncrement(BLInstrumentationNode* node,
994 Value* addition, bool atBeginning) {
995 BasicBlock* block = node->getBlock();
996 assert(node->getStartingPathNumber() != NULL);
997 assert(node->getEndingPathNumber() != NULL);
998
999 BasicBlock::iterator insertPoint;
1000
1001 if( atBeginning )
1002 insertPoint = block->getFirstInsertionPt();
1003 else
1004 insertPoint = block->getTerminator();
1005
1006 DEBUG(errs() << " Creating addition instruction.\n");
1007 Value* newpn = BinaryOperator::Create(Instruction::Add,
1008 node->getStartingPathNumber(),
1009 addition, "pathNumber", insertPoint);
1010
1011 node->setEndingPathNumber(newpn);
1012
1013 if( atBeginning )
1014 node->setStartingPathNumber(newpn);
1015 }
1016
1017 // Creates a counter increment in the given node. The Value* in node is
1018 // taken as the index into an array or hash table. The hash table access
1019 // is a call to the runtime.
insertCounterIncrement(Value * incValue,BasicBlock::iterator insertPoint,BLInstrumentationDag * dag,bool increment)1020 void PathProfiler::insertCounterIncrement(Value* incValue,
1021 BasicBlock::iterator insertPoint,
1022 BLInstrumentationDag* dag,
1023 bool increment) {
1024 // Counter increment for array
1025 if( dag->getNumberOfPaths() <= HASH_THRESHHOLD ) {
1026 // Get pointer to the array location
1027 std::vector<Value*> gepIndices(2);
1028 gepIndices[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
1029 gepIndices[1] = incValue;
1030
1031 GetElementPtrInst* pcPointer =
1032 GetElementPtrInst::Create(dag->getCounterArray(), gepIndices,
1033 "counterInc", insertPoint);
1034
1035 // Load from the array - call it oldPC
1036 LoadInst* oldPc = new LoadInst(pcPointer, "oldPC", insertPoint);
1037
1038 // Test to see whether adding 1 will overflow the counter
1039 ICmpInst* isMax = new ICmpInst(insertPoint, CmpInst::ICMP_ULT, oldPc,
1040 createIncrementConstant(0xffffffff, 32),
1041 "isMax");
1042
1043 // Select increment for the path counter based on overflow
1044 SelectInst* inc =
1045 SelectInst::Create( isMax, createIncrementConstant(increment?1:-1,32),
1046 createIncrementConstant(0,32),
1047 "pathInc", insertPoint);
1048
1049 // newPc = oldPc + inc
1050 BinaryOperator* newPc = BinaryOperator::Create(Instruction::Add,
1051 oldPc, inc, "newPC",
1052 insertPoint);
1053
1054 // Store back in to the array
1055 new StoreInst(newPc, pcPointer, insertPoint);
1056 } else { // Counter increment for hash
1057 std::vector<Value*> args(2);
1058 args[0] = ConstantInt::get(Type::getInt32Ty(*Context),
1059 currentFunctionNumber);
1060 args[1] = incValue;
1061
1062 CallInst::Create(
1063 increment ? llvmIncrementHashFunction : llvmDecrementHashFunction,
1064 args, "", insertPoint);
1065 }
1066 }
1067
1068 // Inserts instrumentation for the given edge
1069 //
1070 // Pre: The edge's source node has pathNumber set if edge is non zero
1071 // path number increment.
1072 //
1073 // Post: Edge's target node has a pathNumber set to the path number Value
1074 // corresponding to the value of the path register after edge's
1075 // execution.
1076 //
1077 // FIXME: This should be reworked so it's not recursive.
insertInstrumentationStartingAt(BLInstrumentationEdge * edge,BLInstrumentationDag * dag)1078 void PathProfiler::insertInstrumentationStartingAt(BLInstrumentationEdge* edge,
1079 BLInstrumentationDag* dag) {
1080 // Mark the edge as instrumented
1081 edge->setHasInstrumentation(true);
1082 DEBUG(dbgs() << "\nInstrumenting edge: " << (*edge) << "\n");
1083
1084 // create a new node for this edge's instrumentation
1085 splitCritical(edge, dag);
1086
1087 BLInstrumentationNode* sourceNode = (BLInstrumentationNode*)edge->getSource();
1088 BLInstrumentationNode* targetNode = (BLInstrumentationNode*)edge->getTarget();
1089 BLInstrumentationNode* instrumentNode;
1090 BLInstrumentationNode* nextSourceNode;
1091
1092 bool atBeginning = false;
1093
1094 // Source node has only 1 successor so any information can be simply
1095 // inserted in to it without splitting
1096 if( sourceNode->getBlock() && sourceNode->getNumberSuccEdges() <= 1) {
1097 DEBUG(dbgs() << " Potential instructions to be placed in: "
1098 << sourceNode->getName() << " (at end)\n");
1099 instrumentNode = sourceNode;
1100 nextSourceNode = targetNode; // ... since we never made any new nodes
1101 }
1102
1103 // The target node only has one predecessor, so we can safely insert edge
1104 // instrumentation into it. If there was splitting, it must have been
1105 // successful.
1106 else if( targetNode->getNumberPredEdges() == 1 ) {
1107 DEBUG(dbgs() << " Potential instructions to be placed in: "
1108 << targetNode->getName() << " (at beginning)\n");
1109 pushValueIntoNode(sourceNode, targetNode);
1110 instrumentNode = targetNode;
1111 nextSourceNode = NULL; // ... otherwise we'll just keep splitting
1112 atBeginning = true;
1113 }
1114
1115 // Somehow, splitting must have failed.
1116 else {
1117 errs() << "Instrumenting could not split a critical edge.\n";
1118 DEBUG(dbgs() << " Couldn't split edge " << (*edge) << ".\n");
1119 return;
1120 }
1121
1122 // Insert instrumentation if this is a back or split edge
1123 if( edge->getType() == BallLarusEdge::BACKEDGE ||
1124 edge->getType() == BallLarusEdge::SPLITEDGE ) {
1125 BLInstrumentationEdge* top =
1126 (BLInstrumentationEdge*) edge->getPhonyRoot();
1127 BLInstrumentationEdge* bottom =
1128 (BLInstrumentationEdge*) edge->getPhonyExit();
1129
1130 assert( top->isInitialization() && " Top phony edge did not"
1131 " contain a path number initialization.");
1132 assert( bottom->isCounterIncrement() && " Bottom phony edge"
1133 " did not contain a path counter increment.");
1134
1135 // split edge has yet to be initialized
1136 if( !instrumentNode->getEndingPathNumber() ) {
1137 instrumentNode->setStartingPathNumber(createIncrementConstant(0,32));
1138 instrumentNode->setEndingPathNumber(createIncrementConstant(0,32));
1139 }
1140
1141 BasicBlock::iterator insertPoint = atBeginning ?
1142 instrumentNode->getBlock()->getFirstInsertionPt() :
1143 instrumentNode->getBlock()->getTerminator();
1144
1145 // add information from the bottom edge, if it exists
1146 if( bottom->getIncrement() ) {
1147 Value* newpn =
1148 BinaryOperator::Create(Instruction::Add,
1149 instrumentNode->getStartingPathNumber(),
1150 createIncrementConstant(bottom),
1151 "pathNumber", insertPoint);
1152 instrumentNode->setEndingPathNumber(newpn);
1153 }
1154
1155 insertCounterIncrement(instrumentNode->getEndingPathNumber(),
1156 insertPoint, dag);
1157
1158 if( atBeginning )
1159 instrumentNode->setStartingPathNumber(createIncrementConstant(top));
1160
1161 instrumentNode->setEndingPathNumber(createIncrementConstant(top));
1162
1163 // Check for path counter increments
1164 if( top->isCounterIncrement() ) {
1165 insertCounterIncrement(instrumentNode->getEndingPathNumber(),
1166 instrumentNode->getBlock()->getTerminator(),dag);
1167 instrumentNode->setEndingPathNumber(0);
1168 }
1169 }
1170
1171 // Insert instrumentation if this is a normal edge
1172 else {
1173 BasicBlock::iterator insertPoint = atBeginning ?
1174 instrumentNode->getBlock()->getFirstInsertionPt() :
1175 instrumentNode->getBlock()->getTerminator();
1176
1177 if( edge->isInitialization() ) { // initialize path number
1178 instrumentNode->setEndingPathNumber(createIncrementConstant(edge));
1179 } else if( edge->getIncrement() ) {// increment path number
1180 Value* newpn =
1181 BinaryOperator::Create(Instruction::Add,
1182 instrumentNode->getStartingPathNumber(),
1183 createIncrementConstant(edge),
1184 "pathNumber", insertPoint);
1185 instrumentNode->setEndingPathNumber(newpn);
1186
1187 if( atBeginning )
1188 instrumentNode->setStartingPathNumber(newpn);
1189 }
1190
1191 // Check for path counter increments
1192 if( edge->isCounterIncrement() ) {
1193 insertCounterIncrement(instrumentNode->getEndingPathNumber(),
1194 insertPoint, dag);
1195 instrumentNode->setEndingPathNumber(0);
1196 }
1197 }
1198
1199 // Push it along
1200 if (nextSourceNode && instrumentNode->getEndingPathNumber())
1201 pushValueIntoNode(instrumentNode, nextSourceNode);
1202
1203 // Add all the successors
1204 for( BLEdgeIterator next = targetNode->succBegin(),
1205 end = targetNode->succEnd(); next != end; next++ ) {
1206 // So long as it is un-instrumented, add it to the list
1207 if( !((BLInstrumentationEdge*)(*next))->hasInstrumentation() )
1208 insertInstrumentationStartingAt((BLInstrumentationEdge*)*next,dag);
1209 else
1210 DEBUG(dbgs() << " Edge " << *(BLInstrumentationEdge*)(*next)
1211 << " already instrumented.\n");
1212 }
1213 }
1214
1215 // Inserts instrumentation according to the marked edges in dag. Phony edges
1216 // must be unlinked from the DAG, but accessible from the backedges. Dag
1217 // must have initializations, path number increments, and counter increments
1218 // present.
1219 //
1220 // Counter storage is created here.
insertInstrumentation(BLInstrumentationDag & dag,Module & M)1221 void PathProfiler::insertInstrumentation(
1222 BLInstrumentationDag& dag, Module &M) {
1223
1224 BLInstrumentationEdge* exitRootEdge =
1225 (BLInstrumentationEdge*) dag.getExitRootEdge();
1226 insertInstrumentationStartingAt(exitRootEdge, &dag);
1227
1228 // Iterate through each call edge and apply the appropriate hash increment
1229 // and decrement functions
1230 BLEdgeVector callEdges = dag.getCallPhonyEdges();
1231 for( BLEdgeIterator edge = callEdges.begin(),
1232 end = callEdges.end(); edge != end; edge++ ) {
1233 BLInstrumentationNode* node =
1234 (BLInstrumentationNode*)(*edge)->getSource();
1235 BasicBlock::iterator insertPoint = node->getBlock()->getFirstInsertionPt();
1236
1237 // Find the first function call
1238 while( ((Instruction&)(*insertPoint)).getOpcode() != Instruction::Call )
1239 insertPoint++;
1240
1241 DEBUG(dbgs() << "\nInstrumenting method call block '"
1242 << node->getBlock()->getName() << "'\n");
1243 DEBUG(dbgs() << " Path number initialized: "
1244 << ((node->getStartingPathNumber()) ? "yes" : "no") << "\n");
1245
1246 Value* newpn;
1247 if( node->getStartingPathNumber() ) {
1248 long inc = ((BLInstrumentationEdge*)(*edge))->getIncrement();
1249 if ( inc )
1250 newpn = BinaryOperator::Create(Instruction::Add,
1251 node->getStartingPathNumber(),
1252 createIncrementConstant(inc,32),
1253 "pathNumber", insertPoint);
1254 else
1255 newpn = node->getStartingPathNumber();
1256 } else {
1257 newpn = (Value*)createIncrementConstant(
1258 ((BLInstrumentationEdge*)(*edge))->getIncrement(), 32);
1259 }
1260
1261 insertCounterIncrement(newpn, insertPoint, &dag);
1262 insertCounterIncrement(newpn, node->getBlock()->getTerminator(),
1263 &dag, false);
1264 }
1265 }
1266
1267 // Entry point of the module
runOnFunction(std::vector<Constant * > & ftInit,Function & F,Module & M)1268 void PathProfiler::runOnFunction(std::vector<Constant*> &ftInit,
1269 Function &F, Module &M) {
1270 // Build DAG from CFG
1271 BLInstrumentationDag dag = BLInstrumentationDag(F);
1272 dag.init();
1273
1274 // give each path a unique integer value
1275 dag.calculatePathNumbers();
1276
1277 // modify path increments to increase the efficiency
1278 // of instrumentation
1279 dag.calculateSpanningTree();
1280 dag.calculateChordIncrements();
1281 dag.pushInitialization();
1282 dag.pushCounters();
1283 dag.unlinkPhony();
1284
1285 // potentially generate .dot graph for the dag
1286 if (DotPathDag)
1287 dag.generateDotGraph ();
1288
1289 // Should we store the information in an array or hash
1290 if( dag.getNumberOfPaths() <= HASH_THRESHHOLD ) {
1291 Type* t = ArrayType::get(Type::getInt32Ty(*Context),
1292 dag.getNumberOfPaths());
1293
1294 dag.setCounterArray(new GlobalVariable(M, t, false,
1295 GlobalValue::InternalLinkage,
1296 Constant::getNullValue(t), ""));
1297 }
1298
1299 insertInstrumentation(dag, M);
1300
1301 // Add to global function reference table
1302 unsigned type;
1303 Type* voidPtr = TypeBuilder<types::i<8>*, true>::get(*Context);
1304
1305 if( dag.getNumberOfPaths() <= HASH_THRESHHOLD )
1306 type = ProfilingArray;
1307 else
1308 type = ProfilingHash;
1309
1310 std::vector<Constant*> entryArray(3);
1311 entryArray[0] = createIncrementConstant(type,32);
1312 entryArray[1] = createIncrementConstant(dag.getNumberOfPaths(),32);
1313 entryArray[2] = dag.getCounterArray() ?
1314 ConstantExpr::getBitCast(dag.getCounterArray(), voidPtr) :
1315 Constant::getNullValue(voidPtr);
1316
1317 StructType* at = ftEntryTypeBuilder::get(*Context);
1318 ConstantStruct* functionEntry =
1319 (ConstantStruct*)ConstantStruct::get(at, entryArray);
1320 ftInit.push_back(functionEntry);
1321 }
1322
1323 // Output the bitcode if we want to observe instrumentation changess
1324 #define PRINT_MODULE dbgs() << \
1325 "\n\n============= MODULE BEGIN ===============\n" << M << \
1326 "\n============== MODULE END ================\n"
1327
runOnModule(Module & M)1328 bool PathProfiler::runOnModule(Module &M) {
1329 Context = &M.getContext();
1330
1331 DEBUG(dbgs()
1332 << "****************************************\n"
1333 << "****************************************\n"
1334 << "** **\n"
1335 << "** PATH PROFILING INSTRUMENTATION **\n"
1336 << "** **\n"
1337 << "****************************************\n"
1338 << "****************************************\n");
1339
1340 // No main, no instrumentation!
1341 Function *Main = M.getFunction("main");
1342
1343 // Using fortran? ... this kind of works
1344 if (!Main)
1345 Main = M.getFunction("MAIN__");
1346
1347 if (!Main) {
1348 errs() << "WARNING: cannot insert path profiling into a module"
1349 << " with no main function!\n";
1350 return false;
1351 }
1352
1353 llvmIncrementHashFunction = M.getOrInsertFunction(
1354 "llvm_increment_path_count",
1355 Type::getVoidTy(*Context), // return type
1356 Type::getInt32Ty(*Context), // function number
1357 Type::getInt32Ty(*Context), // path number
1358 NULL );
1359
1360 llvmDecrementHashFunction = M.getOrInsertFunction(
1361 "llvm_decrement_path_count",
1362 Type::getVoidTy(*Context), // return type
1363 Type::getInt32Ty(*Context), // function number
1364 Type::getInt32Ty(*Context), // path number
1365 NULL );
1366
1367 std::vector<Constant*> ftInit;
1368 unsigned functionNumber = 0;
1369 for (Module::iterator F = M.begin(), E = M.end(); F != E; F++) {
1370 if (F->isDeclaration())
1371 continue;
1372
1373 DEBUG(dbgs() << "Function: " << F->getName() << "\n");
1374 functionNumber++;
1375
1376 // set function number
1377 currentFunctionNumber = functionNumber;
1378 runOnFunction(ftInit, *F, M);
1379 }
1380
1381 Type *t = ftEntryTypeBuilder::get(*Context);
1382 ArrayType* ftArrayType = ArrayType::get(t, ftInit.size());
1383 Constant* ftInitConstant = ConstantArray::get(ftArrayType, ftInit);
1384
1385 DEBUG(dbgs() << " ftArrayType:" << *ftArrayType << "\n");
1386
1387 GlobalVariable* functionTable =
1388 new GlobalVariable(M, ftArrayType, false, GlobalValue::InternalLinkage,
1389 ftInitConstant, "functionPathTable");
1390 Type *eltType = ftArrayType->getTypeAtIndex((unsigned)0);
1391 InsertProfilingInitCall(Main, "llvm_start_path_profiling", functionTable,
1392 PointerType::getUnqual(eltType));
1393
1394 DEBUG(PRINT_MODULE);
1395
1396 return true;
1397 }
1398
1399 // If this edge is a critical edge, then inserts a node at this edge.
1400 // This edge becomes the first edge, and a new BallLarusEdge is created.
1401 // Returns true if the edge was split
splitCritical(BLInstrumentationEdge * edge,BLInstrumentationDag * dag)1402 bool PathProfiler::splitCritical(BLInstrumentationEdge* edge,
1403 BLInstrumentationDag* dag) {
1404 unsigned succNum = edge->getSuccessorNumber();
1405 BallLarusNode* sourceNode = edge->getSource();
1406 BallLarusNode* targetNode = edge->getTarget();
1407 BasicBlock* sourceBlock = sourceNode->getBlock();
1408 BasicBlock* targetBlock = targetNode->getBlock();
1409
1410 if(sourceBlock == NULL || targetBlock == NULL
1411 || sourceNode->getNumberSuccEdges() <= 1
1412 || targetNode->getNumberPredEdges() == 1 ) {
1413 return(false);
1414 }
1415
1416 TerminatorInst* terminator = sourceBlock->getTerminator();
1417
1418 if( SplitCriticalEdge(terminator, succNum, this, false)) {
1419 BasicBlock* newBlock = terminator->getSuccessor(succNum);
1420 dag->splitUpdate(edge, newBlock);
1421 return(true);
1422 } else
1423 return(false);
1424 }
1425