[llvm-commits] [llvm] r157505 - /llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp
Bill Wendling
isanbard at gmail.com
Fri May 25 16:55:01 PDT 2012
Author: void
Date: Fri May 25 18:55:00 2012
New Revision: 157505
URL: http://llvm.org/viewvc/llvm-project?rev=157505&view=rev
Log:
The llvm_gcda_increment_indirect_counter function writes to the arguments that
are passed in. However, those arguments may be in a write-protected area, as far
as the runtime library is concerned. For instance, the data could be placed into
a 'linkedit' section, which isn't writable. Emit the code from
llvm_gcda_increment_indirect_counter directly into the function instead.
Note: The code for this is ugly, and can lead to bloat. We should look into
simplifying this code instead of having all of these branches.
<rdar://problem/11181370>
Modified:
llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp
Modified: llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp?rev=157505&r1=157504&r2=157505&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp Fri May 25 18:55:00 2012
@@ -70,7 +70,9 @@
// Get pointers to the functions in the runtime library.
Constant *getStartFileFunc();
- Constant *getIncrementIndirectCounterFunc();
+ void incrementIndirectCounter(IRBuilder<> &Builder, BasicBlock *Exit,
+ GlobalVariable *EdgeState,
+ Value *CounterPtrArray);
Constant *getEmitFunctionFunc();
Constant *getEmitArcsFunc();
Constant *getEndFileFunc();
@@ -501,16 +503,17 @@
}
for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
// call runtime to perform increment
- BasicBlock::iterator InsertPt =
- ComplexEdgeSuccs[i+1]->getFirstInsertionPt();
+ BasicBlock *BB = ComplexEdgeSuccs[i+1];
+ BasicBlock::iterator InsertPt = BB->getFirstInsertionPt();
+ BasicBlock *Split = BB->splitBasicBlock(InsertPt);
+ InsertPt = BB->getFirstInsertionPt();
IRBuilder<> Builder(InsertPt);
Value *CounterPtrArray =
Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
i * ComplexEdgePreds.size());
- Builder.CreateCall2(getIncrementIndirectCounterFunc(),
- EdgeState, CounterPtrArray);
- // clear the predecessor number
- Builder.CreateStore(ConstantInt::get(Int32Ty, 0xffffffff), EdgeState);
+
+ // Build code to increment the counter.
+ incrementIndirectCounter(Builder, Split, EdgeState, CounterPtrArray);
}
}
}
@@ -573,14 +576,52 @@
return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
}
-Constant *GCOVProfiler::getIncrementIndirectCounterFunc() {
- Type *Args[] = {
- Type::getInt32PtrTy(*Ctx), // uint32_t *predecessor
- Type::getInt64PtrTy(*Ctx)->getPointerTo(), // uint64_t **state_table_row
- };
- FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
- Args, false);
- return M->getOrInsertFunction("llvm_gcda_increment_indirect_counter", FTy);
+/// incrementIndirectCounter - Emit code that increments the indirect
+/// counter. The code is meant to copy the llvm_gcda_increment_indirect_counter
+/// function, but because it's inlined into the function, we don't have to worry
+/// about the runtime library possibly writing into a protected area.
+void GCOVProfiler::incrementIndirectCounter(IRBuilder<> &Builder,
+ BasicBlock *Exit,
+ GlobalVariable *EdgeState,
+ Value *CounterPtrArray) {
+ Type *Int64Ty = Type::getInt64Ty(*Ctx);
+ ConstantInt *NegOne = ConstantInt::get(Type::getInt32Ty(*Ctx), 0xffffffff);
+
+ // Create exiting blocks.
+ BasicBlock *InsBB = Builder.GetInsertBlock();
+ Function *Fn = InsBB->getParent();
+ BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn, Exit);
+ BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn, Exit);
+
+ // uint32_t pred = *EdgeState;
+ // if (pred == 0xffffffff) return;
+ Value *Pred = Builder.CreateLoad(EdgeState, "predecessor");
+ Value *Cond = Builder.CreateICmpEQ(Pred, NegOne);
+ InsBB->getTerminator()->eraseFromParent();
+ BranchInst::Create(Exit, PredNotNegOne, Cond, InsBB);
+
+ Builder.SetInsertPoint(PredNotNegOne);
+
+ // uint64_t *counter = CounterPtrArray[pred];
+ // if (!counter) return;
+ Value *ZExtPred = Builder.CreateZExt(Pred, Int64Ty);
+ Value *GEP = Builder.CreateGEP(CounterPtrArray, ZExtPred);
+ Value *Counter = Builder.CreateLoad(GEP, "counter");
+ Cond = Builder.CreateICmpEQ(Counter,
+ Constant::getNullValue(Type::getInt64PtrTy(*Ctx, 0)));
+ Builder.CreateCondBr(Cond, Exit, CounterEnd);
+
+ Builder.SetInsertPoint(CounterEnd);
+
+ // ++*counter;
+ Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter),
+ ConstantInt::get(Int64Ty, 1));
+ Builder.CreateStore(Add, Counter);
+ Builder.CreateBr(Exit);
+
+ // Clear the predecessor number
+ Builder.SetInsertPoint(Exit->getFirstInsertionPt());
+ Builder.CreateStore(NegOne, EdgeState);
}
Constant *GCOVProfiler::getEmitFunctionFunc() {
@@ -588,8 +629,7 @@
Type::getInt32Ty(*Ctx), // uint32_t ident
Type::getInt8PtrTy(*Ctx), // const char *function_name
};
- FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
- Args, false);
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
}
More information about the llvm-commits
mailing list