summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2015-02-11 02:52:44 +0000
committerJustin Bogner <mail@justinbogner.com>2015-02-11 02:52:44 +0000
commitd24e185784585b5a4e0711521f33a329b6ec663b (patch)
treeeab8ffc19900c9de6907f087e78e0e0b2c09d033 /llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
parent215f423ff22981327e56769150496a9000c2ba53 (diff)
downloadbcm5719-llvm-d24e185784585b5a4e0711521f33a329b6ec663b.tar.gz
bcm5719-llvm-d24e185784585b5a4e0711521f33a329b6ec663b.zip
InstrProf: Lower coverage mappings by setting their sections appropriately
Add handling for __llvm_coverage_mapping to the InstrProfiling pass. We need to make sure the constant and any profile names it refers to are in the correct sections, which is easier and cleaner to do here where we have to know about profiling sections anyway. This is really tricky to test without a frontend, so I'm committing the test for the fix in clang. If anyone knows a good way to test this within LLVM, please let me know. Fixes PR22531. llvm-svn: 228793
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp')
-rw-r--r--llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 5f73b89e855..2a3d15421de 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -71,9 +71,17 @@ private:
return isMachO() ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
}
+ /// Get the section name for the coverage mapping data.
+ StringRef getCoverageSection() const {
+ return isMachO() ? "__DATA,__llvm_covmap" : "__llvm_covmap";
+ }
+
/// Replace instrprof_increment with an increment of the appropriate value.
void lowerIncrement(InstrProfIncrementInst *Inc);
+ /// Set up the section and uses for coverage data and its references.
+ void lowerCoverageData(GlobalVariable *CoverageData);
+
/// Get the region counters for an increment, creating them if necessary.
///
/// If the counter array doesn't yet exist, the profile data variables
@@ -118,6 +126,10 @@ bool InstrProfiling::runOnModule(Module &M) {
lowerIncrement(Inc);
MadeChange = true;
}
+ if (GlobalVariable *Coverage = M.getNamedGlobal("__llvm_coverage_mapping")) {
+ lowerCoverageData(Coverage);
+ MadeChange = true;
+ }
if (!MadeChange)
return false;
@@ -140,6 +152,35 @@ void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
Inc->eraseFromParent();
}
+void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageData) {
+ CoverageData->setSection(getCoverageSection());
+ CoverageData->setAlignment(8);
+
+ Constant *Init = CoverageData->getInitializer();
+ // We're expecting { i32, i32, i32, i32, [n x { i8*, i32, i32 }], [m x i8] }
+ // for some C. If not, the frontend's given us something broken.
+ assert(Init->getNumOperands() == 6 && "bad number of fields in coverage map");
+ assert(isa<ConstantArray>(Init->getAggregateElement(4)) &&
+ "invalid function list in coverage map");
+ ConstantArray *Records = cast<ConstantArray>(Init->getAggregateElement(4));
+ for (unsigned I = 0, E = Records->getNumOperands(); I < E; ++I) {
+ Constant *Record = Records->getOperand(I);
+ Value *V = const_cast<Value *>(Record->getOperand(0))->stripPointerCasts();
+
+ assert(isa<GlobalVariable>(V) && "Missing reference to function name");
+ GlobalVariable *Name = cast<GlobalVariable>(V);
+
+ // If we have region counters for this name, we've already handled it.
+ auto It = RegionCounters.find(Name);
+ if (It != RegionCounters.end())
+ continue;
+
+ // Move the name variable to the right section.
+ Name->setSection(getNameSection());
+ Name->setAlignment(1);
+ }
+}
+
/// Get the name of a profiling variable for a particular function.
static std::string getVarName(InstrProfIncrementInst *Inc, StringRef VarName) {
auto *Arr = cast<ConstantDataArray>(Inc->getName()->getInitializer());
OpenPOWER on IntegriCloud