aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2014-02-17 19:21:09 +0000
committerBob Wilson <bob.wilson@apple.com>2014-02-17 19:21:09 +0000
commitbf854f0f53eab60d127d13e33068993007da280f (patch)
tree29dde13fe5bf590de7b56280323d46a29d22853a /clang/lib/CodeGen/CodeGenFunction.h
parenta7b16e0ffde87990d3c6ae53e7bb456e2d888bd9 (diff)
downloadllvm-bf854f0f53eab60d127d13e33068993007da280f.zip
llvm-bf854f0f53eab60d127d13e33068993007da280f.tar.gz
llvm-bf854f0f53eab60d127d13e33068993007da280f.tar.bz2
Change PGO instrumentation to compute counts in a separate AST traversal.
Previously, we made one traversal of the AST prior to codegen to assign counters to the ASTs and then propagated the count values during codegen. This patch now adds a separate AST traversal prior to codegen for the -fprofile-instr-use option to propagate the count values. The counts are then saved in a map from which they can be retrieved during codegen. This new approach has several advantages: 1. It gets rid of a lot of extra PGO-related code that had previously been added to codegen. 2. It fixes a serious bug. My original implementation (which was mailed to the list but never committed) used 3 counters for every loop. Justin improved it to move 2 of those counters into the less-frequently executed breaks and continues, but that turned out to produce wrong count values in some cases. The solution requires visiting a loop body before the condition so that the count for the condition properly includes the break and continue counts. Changing codegen to visit a loop body first would be a fairly invasive change, but with a separate AST traversal, it is easy to control the order of traversal. I've added a testcase (provided by Justin) to make sure this works correctly. 3. It improves the instrumentation overhead, reducing the number of counters for a loop from 3 to 1. We no longer need dedicated counters for breaks and continues, since we can just use the propagated count values when visiting breaks and continues. To make this work, I needed to make a change to the way we count case statements, going back to my original approach of not including the fall-through in the counter values. This was necessary because there isn't always an AST node that can be used to record the fall-through count. Now case statements are handled the same as default statements, with the fall-through paths branching over the counter increments. While I was at it, I also went back to using this approach for do-loops -- omitting the fall-through count into the loop body simplifies some of the calculations and make them behave the same as other loops. Whenever we start using this instrumentation for coverage, we'll need to add the fall-through counts into the counter values. llvm-svn: 201528
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h12
1 files changed, 4 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index a1f6721..185e25c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -818,18 +818,13 @@ private:
llvm::DenseMap<const LabelDecl*, JumpDest> LabelMap;
// BreakContinueStack - This keeps track of where break and continue
- // statements should jump to and the associated base counter for
- // instrumentation.
+ // statements should jump to.
struct BreakContinue {
- BreakContinue(JumpDest Break, JumpDest Continue, RegionCounter *LoopCnt,
- bool CountBreak = true)
- : BreakBlock(Break), ContinueBlock(Continue), LoopCnt(LoopCnt),
- CountBreak(CountBreak) {}
+ BreakContinue(JumpDest Break, JumpDest Continue)
+ : BreakBlock(Break), ContinueBlock(Continue) {}
JumpDest BreakBlock;
JumpDest ContinueBlock;
- RegionCounter *LoopCnt;
- bool CountBreak;
};
SmallVector<BreakContinue, 8> BreakContinueStack;
@@ -1156,6 +1151,7 @@ public:
void EmitDestructorBody(FunctionArgList &Args);
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
void EmitFunctionBody(FunctionArgList &Args, const Stmt *Body);
+ void EmitBlockWithFallThrough(llvm::BasicBlock *BB, RegionCounter &Cnt);
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
CallArgList &CallArgs);