1 #include <sectionify/SectionifyPass.h>
5 static cl::list
<std::string
>
6 sectionMapOpt("sectionify-section-map",
7 cl::desc("Specify all the comma-separated symbol_regex/section pairs which need to be sectionified. \"NULL\" section doesn't sectionify."),
8 cl::ZeroOrMore
, cl::CommaSeparated
, cl::NotHidden
, cl::ValueRequired
);
10 static cl::list
<std::string
>
11 functionSectionMapOpt("sectionify-function-section-map",
12 cl::desc("Specify all the comma-separated function_regex/section pairs which need to be sectionified"),
13 cl::ZeroOrMore
, cl::CommaSeparated
, cl::NotHidden
, cl::ValueRequired
);
15 static cl::list
<std::string
>
16 dataSectionMapOpt("sectionify-data-section-map",
17 cl::desc("Specify all the comma-separated data_regex/section pairs which need to be sectionified"),
18 cl::ZeroOrMore
, cl::CommaSeparated
, cl::NotHidden
, cl::ValueRequired
);
20 static cl::opt
<std::string
>
21 prefixOpt("sectionify-prefix",
22 cl::desc("Specify the prefix-string for prefixing names of global variables and functions"),
23 cl::Optional
, cl::NotHidden
, cl::ValueRequired
);
26 sectionifyExternalFunctions("sectionify-function-external",
27 llvm::cl::desc("Also sectionify external functions"),
31 sectionifyExternalData("sectionify-data-external",
32 llvm::cl::desc("Also sectionify external data"),
36 sectionifySkipReadOnlyData("sectionify-data-skip-read-only",
37 llvm::cl::desc("Don't sectionify read-only data"),
41 sectionifyTLSData("sectionify-data-tls",
42 llvm::cl::desc("Also sectionify tls data"),
46 sectionifyNoOverride("sectionify-no-override",
47 llvm::cl::desc("Do not override existing sections"),
50 STATISTIC(numSectionifiedGVs
, "Number of sectionified global variables");
51 STATISTIC(numSectionifiedFuncs
, "Number of sectionified functions");
55 //===----------------------------------------------------------------------===//
56 // Constructors, destructor, and operators
57 //===----------------------------------------------------------------------===//
59 SectionifyPass::SectionifyPass() : ModulePass(ID
) {}
60 //===----------------------------------------------------------------------===//
62 //===----------------------------------------------------------------------===//
64 bool SectionifyPass::runOnModule(Module
&M
) {
65 bool sectionified
= false;
66 Module::GlobalListType
&globalList
= M
.getGlobalList();
67 Module::FunctionListType
&functionList
= M
.getFunctionList();
69 functionSectionMapOpt
.insert(functionSectionMapOpt
.end(), sectionMapOpt
.begin(), sectionMapOpt
.end());
70 dataSectionMapOpt
.insert(dataSectionMapOpt
.end(), sectionMapOpt
.begin(), sectionMapOpt
.end());
71 parseAndInitRegexMap(functionSectionMapOpt
, functionRegexList
, functionRegexMap
, "function");
72 parseAndInitRegexMap(dataSectionMapOpt
, dataRegexList
, dataRegexMap
, "data");
75 if ("" != prefixOpt
&& "%MODULE_NAME%" == prefixOpt
)
77 PassUtil::getModuleName(M
, NULL
, NULL
, &moduleName
);
80 for (Module::global_iterator it
= globalList
.begin(); it
!= globalList
.end(); ++it
) {
81 GlobalVariable
*GV
= it
;
82 if (GV
->isDeclaration() && !sectionifyExternalData
) {
83 DEBUG(errs() << "Skipping external GlobalVariable " << GV
->getName() << "\n");
86 if (GV
->isConstant() && sectionifySkipReadOnlyData
) {
87 DEBUG(errs() << "Skipping read-only GlobalVariable " << GV
->getName() << "\n");
90 if (GV
->isThreadLocal() && !sectionifyTLSData
) {
91 DEBUG(errs() << "Skipping TLS GlobalVariable " << GV
->getName() << "\n");
94 if (GV
->hasSection() && sectionifyNoOverride
) {
95 DEBUG(errs() << "Skipping sectionified GlobalVariable " << GV
->getName() << "\n");
98 if (GV
->getName().startswith("llvm.")) {
99 DEBUG(errs() << "Skipping LLVM instrinsic GlobalVariable " << GV
->getName() << "\n");
102 if (sectionify(GV
, dataRegexList
, dataRegexMap
)) {
103 numSectionifiedGVs
++;
107 for (Module::iterator it
= functionList
.begin(); it
!= functionList
.end(); ++it
) {
109 if (F
->isDeclaration() && !sectionifyExternalFunctions
) {
110 DEBUG(errs() << "Skipping external Function " << F
->getName() << "\n");
113 if (F
->hasSection() && sectionifyNoOverride
) {
114 DEBUG(errs() << "Skipping sectionified Function " << F
->getName() << "\n");
117 if (F
->getName().startswith("llvm.")) {
118 DEBUG(errs() << "Skipping LLVM instrinsic Function " << F
->getName() << "\n");
121 if (sectionify(F
, functionRegexList
, functionRegexMap
)) {
122 numSectionifiedFuncs
++;
130 bool SectionifyPass::sectionifyFromRegex(GlobalObject
*value
, Regex
*regex
, std::string
§ion
)
132 bool returnValue
= false;
134 if("NULL" != section
&& regex
->match(value
->getName(), NULL
)) {
135 std::string trgSection
= section
;
136 std::string valueStrPrefix
= "";
137 GlobalVariable
*GV
= dyn_cast
<GlobalVariable
>(value
);
138 if (GV
&& GV
->isConstant()) {
140 valueStrPrefix
= "read-only ";
142 DEBUG(errs() << "Sectionified " << valueStrPrefix
<< (isa
<Function
>(value
) ? "Function " : "GlobalVariable ") << value
->getName() << " with section " << trgSection
<< "\n");
143 value
->setSection(trgSection
);
144 if (value
->hasCommonLinkage()) {
145 value
->setLinkage(GlobalObject::WeakAnyLinkage
);
151 std::string originalName
= value
->getName();
152 std::string prefixString
= "";
153 if ("" != moduleName
)
155 prefixString
= moduleName
;
159 prefixString
= prefixOpt
;
161 DEBUG(errs() << "Prefixing the " << (isa
<Function
>(value
) ? "Function name " : "GlobalVariable name ") << originalName
<< " with " << prefixString
<< "\n");
162 std::string prefixedName
= prefixString
+ originalName
;
163 value
->setName(prefixedName
);
170 bool SectionifyPass::sectionify(GlobalObject
*value
, std::vector
<Regex
*> ®exList
, std::map
<Regex
*, std::string
> ®exMap
)
172 std::map
<Regex
*, std::string
>::iterator regexMapIt
;
173 for (std::vector
<Regex
*>::iterator it
= regexList
.begin(); it
!= regexList
.end(); ++it
) {
175 regexMapIt
= regexMap
.find(regex
);
176 assert(regexMapIt
!= regexMap
.end());
177 std::string section
= regexMapIt
->second
;
178 if (sectionifyFromRegex(value
, regex
, section
)) {
186 bool SectionifyPass::parseStringMapOpt(std::map
<std::string
, std::string
> &map
, std::vector
<std::string
> &keyList
, std::vector
<std::string
> &stringList
)
188 for (std::vector
<std::string
>::iterator it
= stringList
.begin(); it
!= stringList
.end(); ++it
) {
189 StringRef token
= *it
;
190 SmallVector
< StringRef
, 2 > tokenVector
;
191 token
.split(tokenVector
, "/");
192 if(tokenVector
.size() != 2) {
195 StringRef value
= tokenVector
.pop_back_val();
196 StringRef key
= tokenVector
.pop_back_val();
197 map
.insert( std::pair
<std::string
, std::string
>(key
, value
) );
198 keyList
.push_back(key
);
204 void SectionifyPass::parseAndInitRegexMap(cl::list
<std::string
> &stringListOpt
, std::vector
<Regex
*> ®exList
, std::map
<Regex
*, std::string
> ®exMap
, std::string regexType
)
206 std::map
<std::string
, std::string
> sectionMap
;
207 std::vector
<std::string
> sectionList
;
208 if (!parseStringMapOpt(sectionMap
, sectionList
, stringListOpt
) || !initRegexMap(regexMap
, regexList
, sectionMap
, sectionList
, regexType
)) {
209 stringListOpt
.error("Invalid format!");
214 bool SectionifyPass::initRegexMap(std::map
<Regex
*, std::string
> ®exMap
, std::vector
<Regex
*> ®exList
, std::map
<std::string
, std::string
> &stringMap
, std::vector
<std::string
> &stringList
, std::string regexType
)
216 std::map
<std::string
, std::string
>::iterator stringMapIt
;
217 for (std::vector
<std::string
>::iterator it
= stringList
.begin(); it
!= stringList
.end(); ++it
) {
218 std::string key
= *it
;
219 stringMapIt
= stringMap
.find(key
);
220 assert(stringMapIt
!= stringMap
.end());
221 std::string value
= stringMapIt
->second
;
223 Regex
*regex
= new Regex(key
, 0);
224 if(!regex
->isValid(error
)) {
227 DEBUG(errs() << "Using " << regexType
<< " regex " << key
<< " with section " << value
<< "\n");
228 regexMap
.insert(std::pair
<Regex
*, std::string
>(regex
, value
));
229 regexList
.push_back(regex
);
237 char SectionifyPass::ID
= 1;
238 static RegisterPass
<SectionifyPass
> AP("sectionify", "Sectionify Pass");