llvm.org GIT mirror llvm / d4ab192
[NVPTX] Fix a few style issues in NVVMReflect git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178536 91177308-0d34-0410-b5e6-96231b3b80d8 Justin Holewinski 7 years ago
1 changed file(s) with 56 addition(s) and 72 deletion(s). Raw diff Collapse all Expand all
88 //
99 // This pass replaces occurences of __nvvm_reflect("string") with an
1010 // integer based on -nvvm-reflect-list string= option given to this pass.
11 // If an undefined string value is seen in a call to __nvvm_reflect("string"),
12 // a default value of 0 will be used.
1113 //
1214 //===----------------------------------------------------------------------===//
1315
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/SmallVector.h"
1418 #include "llvm/ADT/StringMap.h"
1519 #include "llvm/Pass.h"
1620 #include "llvm/IR/Function.h"
3741 namespace {
3842 class LLVM_LIBRARY_VISIBILITY NVVMReflect : public ModulePass {
3943 private:
40 //std::map VarMap;
4144 StringMap VarMap;
42 typedef std::map::iterator VarMapIter;
43 Function *reflectFunction;
45 typedef DenseMap::iterator VarMapIter;
46 Function *ReflectFunction;
4447
4548 public:
4649 static char ID;
4750 NVVMReflect() : ModulePass(ID) {
4851 VarMap.clear();
49 reflectFunction = 0;
52 ReflectFunction = 0;
5053 }
5154
5255 void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); }
6669 false)
6770
6871 static cl::list
69 ReflectList("nvvm-reflect-list", cl::value_desc("name=0/1"),
70 cl::desc("A list of string=num assignments, where num=0 or 1"),
72 ReflectList("nvvm-reflect-list", cl::value_desc("name="),
73 cl::desc("A list of string=num assignments"),
7174 cl::ValueRequired);
7275
73 /// This function does the same operation as perl's split.
74 /// For example, calling this with ("a=1,b=2,c=0", ",") will
75 /// return ["a=1", "b=2", "c=0"] in the return std::vector.
76 static std::vector
77 Tokenize(const std::string &str, const std::string &delim) {
78 std::vector tokens;
79
80 size_t p0 = 0, p1 = std::string::npos;
81 while (p0 != std::string::npos) {
82 p1 = str.find_first_of(delim, p0);
83 if (p1 != p0) {
84 std::string token = str.substr(p0, p1 - p0);
85 tokens.push_back(token);
86 }
87 p0 = str.find_first_not_of(delim, p1);
88 }
89
90 return tokens;
91 }
92
9376 /// The command line can look as follows :
94 /// -R a=1,b=2 -R c=3,d=0 -R e=2
77 /// -nvvm-reflect-list a=1,b=2 -nvvm-reflect-list c=3,d=0 -R e=2
9578 /// The strings "a=1,b=2", "c=3,d=0", "e=2" are available in the
9679 /// ReflectList vector. First, each of ReflectList[i] is 'split'
9780 /// using "," as the delimiter. Then each of this part is split
9881 /// using "=" as the delimiter.
9982 void NVVMReflect::setVarMap() {
10083 for (unsigned i = 0, e = ReflectList.size(); i != e; ++i) {
101 // DEBUG(dbgs() << "Option : " << ReflectList[i] << std::endl);
102 std::vector nameValList = Tokenize(ReflectList[i], ",");
103 for (unsigned j = 0, ej = nameValList.size(); j != ej; ++j) {
104 std::vector nameValPair = Tokenize(nameValList[j], "=");
105 assert(nameValPair.size() == 2 && "name=val expected");
106 std::stringstream valstream(nameValPair[1]);
107 int val;
108 valstream >> val;
109 assert((!(valstream.fail())) && "integer value expected");
110 VarMap[nameValPair[0]] = val;
84 DEBUG(dbgs() << "Option : " << ReflectList[i] << "\n");
85 SmallVector NameValList;
86 StringRef(ReflectList[i]).split(NameValList, ",");
87 for (unsigned j = 0, ej = NameValList.size(); j != ej; ++j) {
88 SmallVector NameValPair;
89 NameValList[j].split(NameValPair, "=");
90 assert(NameValPair.size() == 2 && "name=val expected");
91 std::stringstream ValStream(NameValPair[1]);
92 int Val;
93 ValStream >> Val;
94 assert((!(ValStream.fail())) && "integer value expected");
95 VarMap[NameValPair[0]] = Val;
11196 }
11297 }
11398 }
118103
119104 setVarMap();
120105
121 reflectFunction = M.getFunction(NVVM_REFLECT_FUNCTION);
106 ReflectFunction = M.getFunction(NVVM_REFLECT_FUNCTION);
122107
123108 // If reflect function is not used, then there will be
124109 // no entry in the module.
125 if (reflectFunction == 0) {
110 if (ReflectFunction == 0)
126111 return false;
127 }
128112
129113 // Validate _reflect function
130 assert(reflectFunction->isDeclaration() &&
114 assert(ReflectFunction->isDeclaration() &&
131115 "_reflect function should not have a body");
132 assert(reflectFunction->getReturnType()->isIntegerTy() &&
116 assert(ReflectFunction->getReturnType()->isIntegerTy() &&
133117 "_reflect's return type should be integer");
134118
135 std::vector toRemove;
119 std::vector ToRemove;
136120
137 // Go through the uses of reflectFunction in this Function.
121 // Go through the uses of ReflectFunction in this Function.
138122 // Each of them should a CallInst with a ConstantArray argument.
139123 // First validate that. If the c-string corresponding to the
140124 // ConstantArray can be found successfully, see if it can be
141125 // found in VarMap. If so, replace the uses of CallInst with the
142126 // value found in VarMap. If not, replace the use with value 0.
143 for (Value::use_iterator iter = reflectFunction->use_begin(),
144 iterEnd = reflectFunction->use_end();
145 iter != iterEnd; ++iter) {
146 assert(isa(*iter) && "Only a call instruction can use _reflect");
147 CallInst *reflect = cast(*iter);
127 for (Value::use_iterator I = ReflectFunction->use_begin(),
128 E = ReflectFunction->use_end();
129 I != E; ++I) {
130 assert(isa(*I) && "Only a call instruction can use _reflect");
131 CallInst *Reflect = cast(*I);
148132
149 assert((reflect->getNumOperands() == 2) &&
133 assert((Reflect->getNumOperands() == 2) &&
150134 "Only one operand expect for _reflect function");
151135 // In cuda, we will have an extra constant-to-generic conversion of
152136 // the string.
153 const Value *conv = reflect->getArgOperand(0);
137 const Value *conv = Reflect->getArgOperand(0);
154138 assert(isa(conv) && "Expected a const-to-gen conversion");
155 const CallInst *convcall = cast(conv);
156 const Value *str = convcall->getArgOperand(0);
139 const CallInst *ConvCall = cast(conv);
140 const Value *str = ConvCall->getArgOperand(0);
157141 assert(isa(str) &&
158142 "Format of _reflect function not recognized");
159 const ConstantExpr *gep = cast(str);
143 const ConstantExpr *GEP = cast(str);
160144
161 const Value *sym = gep->getOperand(0);
162 assert(isa(sym) && "Format of _reflect function not recognized");
145 const Value *Sym = GEP->getOperand(0);
146 assert(isa(Sym) && "Format of _reflect function not recognized");
163147
164 const Constant *symstr = cast(sym);
148 const Constant *SymStr = cast(Sym);
165149
166 assert(isa(symstr->getOperand(0)) &&
150 assert(isa(SymStr->getOperand(0)) &&
167151 "Format of _reflect function not recognized");
168152
169 assert(cast(symstr->getOperand(0))->isCString() &&
153 assert(cast(SymStr->getOperand(0))->isCString() &&
170154 "Format of _reflect function not recognized");
171155
172 std::string reflectArg =
173 cast(symstr->getOperand(0))->getAsString();
156 std::string ReflectArg =
157 cast(SymStr->getOperand(0))->getAsString();
174158
175 reflectArg = reflectArg.substr(0, reflectArg.size() - 1);
176 // DEBUG(dbgs() << "Arg of _reflect : " << reflectArg << std::endl);
159 ReflectArg = ReflectArg.substr(0, ReflectArg.size() - 1);
160 DEBUG(dbgs() << "Arg of _reflect : " << ReflectArg << "\n");
177161
178 int reflectVal = 0; // The default value is 0
179 if (VarMap.find(reflectArg) != VarMap.end()) {
180 reflectVal = VarMap[reflectArg];
162 int ReflectVal = 0; // The default value is 0
163 if (VarMap.find(ReflectArg) != VarMap.end()) {
164 ReflectVal = VarMap[ReflectArg];
181165 }
182 reflect->replaceAllUsesWith(
183 ConstantInt::get(reflect->getType(), reflectVal));
184 toRemove.push_back(reflect);
166 Reflect->replaceAllUsesWith(
167 ConstantInt::get(Reflect->getType(), ReflectVal));
168 ToRemove.push_back(Reflect);
185169 }
186 if (toRemove.size() == 0)
170 if (ToRemove.size() == 0)
187171 return false;
188172
189 for (unsigned i = 0, e = toRemove.size(); i != e; ++i)
190 toRemove[i]->eraseFromParent();
173 for (unsigned i = 0, e = ToRemove.size(); i != e; ++i)
174 ToRemove[i]->eraseFromParent();
191175 return true;
192176 }