29
29
using namespace swift ;
30
30
using namespace irgen ;
31
31
32
+ using llvm::coverage::CovMapVersion;
32
33
using llvm::coverage::CounterMappingRegion;
33
34
34
- // This is disabled for some reason.
35
- #define DISABLE_COVERAGE_MAPPING
36
-
37
- #ifndef DISABLE_COVERAGE_MAPPING
38
35
static bool isMachO (IRGenModule &IGM) {
39
36
return SwiftTargetInfo::get (IGM).OutputObjectFormat == llvm::Triple::MachO;
40
37
}
41
38
42
39
static StringRef getCoverageSection (IRGenModule &IGM) {
43
40
return llvm::getInstrProfCoverageSectionName (isMachO (IGM));
44
41
}
45
- #endif
42
+
43
+ static StringRef getProfNamesSection (IRGenModule &IGM) {
44
+ return llvm::getInstrProfNameSectionName (isMachO (IGM));
45
+ }
46
46
47
47
void IRGenModule::emitCoverageMapping () {
48
- #ifdef DISABLE_COVERAGE_MAPPING
49
- return ;
50
- #else
51
48
const auto &Mappings = SILMod->getCoverageMapList ();
52
49
// If there aren't any coverage maps, there's nothing to emit.
53
50
if (Mappings.empty ())
@@ -71,21 +68,20 @@ void IRGenModule::emitCoverageMapping() {
71
68
}
72
69
73
70
// Encode the filenames first.
74
- std::string EncodedDataBuf ;
75
- llvm::raw_string_ostream OS (EncodedDataBuf );
71
+ std::string FilenamesAndCoverageMappings ;
72
+ llvm::raw_string_ostream OS (FilenamesAndCoverageMappings );
76
73
llvm::coverage::CoverageFilenamesSectionWriter (FilenameRefs).write (OS);
77
74
size_t FilenamesSize = OS.str ().size ();
78
75
size_t CurrentSize, PrevSize = FilenamesSize;
79
76
80
77
// Now we need to build up the list of function records.
81
78
llvm::LLVMContext &Ctx = LLVMContext;
82
79
auto *Int32Ty = llvm::Type::getInt32Ty (Ctx);
83
- auto *Int64Ty = llvm::Type::getInt64Ty (Ctx);
84
- auto *Int8PtrTy = llvm::Type::getInt8PtrTy (Ctx);
85
80
86
- #define COVMAP_FUNC_RECORD (Type, LLVMType, Name, Init ) LLVMType,
87
81
llvm::Type *FunctionRecordTypes[] = {
82
+ #define COVMAP_FUNC_RECORD (Type, LLVMType, Name, Init ) LLVMType,
88
83
#include " llvm/ProfileData/InstrProfData.inc"
84
+ #undef COVMAP_FUNC_RECORD
89
85
};
90
86
91
87
auto FunctionRecordTy =
@@ -107,19 +103,31 @@ void IRGenModule::emitCoverageMapping() {
107
103
Regions);
108
104
W.write (OS);
109
105
110
- auto *NameVal = llvm::ConstantDataArray::getString (Ctx, M.getName (), false );
111
- auto *NameVar = new llvm::GlobalVariable (
112
- *getModule (), NameVal->getType (), true ,
113
- llvm::GlobalValue::LinkOnceAnyLinkage, NameVal,
114
- llvm::getInstrProfNameVarPrefix () + M.getName ());
106
+ std::string NameValue = llvm::getPGOFuncName (
107
+ M.getName (), llvm::GlobalValue::LinkOnceAnyLinkage, M.getFile ());
108
+ llvm::GlobalVariable *NamePtr = llvm::createPGOFuncNameVar (
109
+ *getModule (), llvm::GlobalValue::LinkOnceAnyLinkage, NameValue);
110
+
111
+ // The instr-profiling pass in llvm typically sets the function name ptr's
112
+ // section. We do it here because (1) SIL's int_instrprof_increment does not
113
+ // use this exact GlobalVariable, so llvm misses it and (2) we shouldn't
114
+ // expose all name ptrs to llvm via the getCoverageUnusedNamesVarName() API.
115
+ NamePtr->setSection (getProfNamesSection (*this ));
116
+ NamePtr->setAlignment (1 );
115
117
116
118
CurrentSize = OS.str ().size ();
119
+ unsigned MappingLen = CurrentSize - PrevSize;
120
+ StringRef CoverageMapping (OS.str ().c_str () + PrevSize, MappingLen);
121
+
122
+ uint64_t FuncHash = M.getHash ();
123
+
117
124
// Create a record for this function.
118
125
llvm::Constant *FunctionRecordVals[] = {
119
- llvm::ConstantExpr::getBitCast (NameVar, Int8PtrTy),
120
- llvm::ConstantInt::get (Int32Ty, M.getName ().size ()),
121
- llvm::ConstantInt::get (Int32Ty, CurrentSize - PrevSize),
122
- llvm::ConstantInt::get (Int64Ty, M.getHash ())};
126
+ #define COVMAP_FUNC_RECORD (Type, LLVMType, Name, Init ) Init,
127
+ #include " llvm/ProfileData/InstrProfData.inc"
128
+ #undef COVMAP_FUNC_RECORD
129
+ };
130
+
123
131
FunctionRecords.push_back (llvm::ConstantStruct::get (
124
132
FunctionRecordTy, makeArrayRef (FunctionRecordVals)));
125
133
PrevSize = CurrentSize;
@@ -133,32 +141,43 @@ void IRGenModule::emitCoverageMapping() {
133
141
for (size_t I = 0 , S = 8 - Rem; I < S; ++I)
134
142
OS << ' \0 ' ;
135
143
}
136
- auto *EncodedData =
144
+ auto *FilenamesAndMappingsVal =
137
145
llvm::ConstantDataArray::getString (Ctx, OS.str (), false );
138
146
139
147
auto *RecordsTy =
140
148
llvm::ArrayType::get (FunctionRecordTy, FunctionRecords.size ());
141
149
auto *RecordsVal = llvm::ConstantArray::get (RecordsTy, FunctionRecords);
142
150
143
- // Now we embed everything into a constant with a well-known name.
144
- auto *CovDataTy =
145
- llvm::StructType::get (Ctx, {Int32Ty, Int32Ty, Int32Ty, Int32Ty, RecordsTy,
146
- EncodedData->getType ()});
147
- llvm::Constant *TUDataVals[] = {
148
- llvm::ConstantInt::get (Int32Ty, FunctionRecords.size ()),
149
- llvm::ConstantInt::get (Int32Ty, FilenamesSize),
150
- llvm::ConstantInt::get (Int32Ty, CoverageMappingSize),
151
- llvm::ConstantInt::get (Int32Ty, llvm::coverage::CoverageMappingVersion1),
152
- RecordsVal,
153
- EncodedData};
154
- auto CovDataVal =
151
+ // Create the coverage data header.
152
+ llvm::Type *CovDataHeaderTypes[] = {
153
+ #define COVMAP_HEADER (Type, LLVMType, Name, Init ) LLVMType,
154
+ #include " llvm/ProfileData/InstrProfData.inc"
155
+ #undef COVMAP_HEADER
156
+ };
157
+ auto *CovDataHeaderTy =
158
+ llvm::StructType::get (Ctx, makeArrayRef (CovDataHeaderTypes));
159
+ llvm::Constant *CovDataHeaderVals[] = {
160
+ #define COVMAP_HEADER (Type, LLVMType, Name, Init ) Init,
161
+ #include " llvm/ProfileData/InstrProfData.inc"
162
+ #undef COVMAP_HEADER
163
+ };
164
+ auto *CovDataHeaderVal = llvm::ConstantStruct::get (
165
+ CovDataHeaderTy, makeArrayRef (CovDataHeaderVals));
166
+
167
+ // Combine the header, function records, and mappings together.
168
+ llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy,
169
+ FilenamesAndMappingsVal->getType ()};
170
+ auto *CovDataTy = llvm::StructType::get (Ctx, makeArrayRef (CovDataTypes));
171
+ llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal,
172
+ FilenamesAndMappingsVal};
173
+ auto *CovDataVal =
155
174
llvm::ConstantStruct::get (CovDataTy, makeArrayRef (TUDataVals));
175
+
156
176
auto CovData = new llvm::GlobalVariable (
157
177
*getModule (), CovDataTy, true , llvm::GlobalValue::InternalLinkage,
158
178
CovDataVal, llvm::getCoverageMappingVarName ());
159
179
CovData->setSection (getCoverageSection (*this ));
160
180
CovData->setAlignment (8 );
161
181
162
182
addUsedGlobal (CovData);
163
- #endif
164
183
}
0 commit comments