llvm.org GIT mirror llvm / bc0b9f7
start inferring 'no side effects'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45822 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
4 changed file(s) with 65 addition(s) and 59 deletion(s). Raw diff Collapse all Expand all
320320 Properties |= 1 << SDNPMayStore;
321321 } else if (PropList[i]->getName() == "SDNPMayLoad") {
322322 Properties |= 1 << SDNPMayLoad;
323 } else if (PropList[i]->getName() == "SDNPSideEffect") {
324 Properties |= 1 << SDNPSideEffect;
323325 } else {
324326 cerr << "Unknown SD Node property '" << PropList[i]->getName()
325327 << "' on node '" << R->getName() << "'!\n";
3737 SDNPInFlag,
3838 SDNPOptInFlag,
3939 SDNPMayLoad,
40 SDNPMayStore
40 SDNPMayStore,
41 SDNPSideEffect
4142 };
4243
4344 /// getValueType - Return the MVT::ValueType that the specified TableGen record
144144 const CodeGenDAGPatterns &CDP;
145145 bool &mayStore;
146146 bool &mayLoad;
147 bool &NeverHasSideEffects;
147 bool &HasSideEffects;
148148 public:
149149 InstAnalyzer(const CodeGenDAGPatterns &cdp,
150 bool &maystore, bool &mayload, bool &nhse)
151 : CDP(cdp), mayStore(maystore), mayLoad(mayload), NeverHasSideEffects(nhse){
150 bool &maystore, bool &mayload, bool &hse)
151 : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
152152 }
153153
154154 void Analyze(Record *InstRecord) {
155155 const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
156156 if (Pattern == 0) return; // No pattern.
157
158 // Assume there is no side-effect unless we see one.
159 NeverHasSideEffects = true;
160157
161158 // FIXME: Assume only the first tree is the pattern. The others are clobber
162159 // nodes.
168165 if (N->isLeaf())
169166 return;
170167
171 if (N->getOperator()->getName() != "set") {
172 // Get information about the SDNode for the operator.
173 const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
174
175 // If node writes to memory, it obviously stores to memory.
176 if (OpInfo.hasProperty(SDNPMayStore))
177 mayStore = true;
178
179 // If it reads memory, remember this.
180 if (OpInfo.hasProperty(SDNPMayLoad))
181 mayLoad = true;
182
183 if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
184 // If this is an intrinsic, analyze it.
185 if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem) {
186 mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
187 }
188
189 if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
190 mayLoad = true;// These may also load memory.
191 }
192 }
193
168 // Analyze children.
194169 for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
195170 AnalyzeNode(N->getChild(i));
171
172 // Ignore set nodes, which are not SDNodes.
173 if (N->getOperator()->getName() == "set")
174 return;
175
176 // Get information about the SDNode for the operator.
177 const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
178
179 // If node writes to memory, it obviously stores to memory.
180 if (OpInfo.hasProperty(SDNPMayStore))
181 mayStore = true;
182
183 // If it reads memory, remember this.
184 if (OpInfo.hasProperty(SDNPMayLoad))
185 mayLoad = true;
186
187 // If it reads memory, remember this.
188 if (OpInfo.hasProperty(SDNPSideEffect))
189 HasSideEffects = true;
190
191 if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
192 // If this is an intrinsic, analyze it.
193 if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
194 mayLoad = true;// These may load memory.
195
196 if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem)
197 mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
198
199 if (IntInfo->ModRef >= CodeGenIntrinsic::WriteMem)
200 // WriteMem intrinsics can have other strange effects.
201 HasSideEffects = true;
202 }
196203 }
197204
198205 };
199206
200207 void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst,
201 bool &mayStore, bool &mayLoad,
202 bool &NeverHasSideEffects) {
203 mayStore = mayLoad = NeverHasSideEffects = false;
204
205 InstAnalyzer(CDP, mayStore, mayLoad,NeverHasSideEffects).Analyze(Inst.TheDef);
208 bool &MayStore, bool &MayLoad,
209 bool &HasSideEffects) {
210 MayStore = MayLoad = HasSideEffects = false;
211
212 InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
206213
207214 // InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
208215 if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it.
209216 // If we decided that this is a store from the pattern, then the .td file
210217 // entry is redundant.
211 if (mayStore)
218 if (MayStore)
212219 fprintf(stderr,
213220 "Warning: mayStore flag explicitly set on instruction '%s'"
214221 " but flag already inferred from pattern.\n",
215222 Inst.TheDef->getName().c_str());
216 mayStore = true;
223 MayStore = true;
217224 }
218225
219226 if (Inst.mayLoad) { // If the .td file explicitly sets mayLoad, use it.
220227 // If we decided that this is a load from the pattern, then the .td file
221228 // entry is redundant.
222 if (mayLoad)
229 if (MayLoad)
223230 fprintf(stderr,
224231 "Warning: mayLoad flag explicitly set on instruction '%s'"
225232 " but flag already inferred from pattern.\n",
226233 Inst.TheDef->getName().c_str());
227 mayLoad = true;
228 }
229
230
231 NeverHasSideEffects = Inst.neverHasSideEffects;
232
233 #if 0
234 // If the .td file explicitly says there is no side effect, believe it.
235 if (Inst.neverHasSideEffects)
236 NeverHasSideEffects = true;
237 #endif
234 MayLoad = true;
235 }
236
237 if (Inst.neverHasSideEffects) {
238 // If we already decided that this instruction has no side effects, then the
239 // .td file entry is redundant.
240 if (!HasSideEffects)
241 fprintf(stderr,
242 "Warning: neverHasSideEffects flag explicitly set on instruction"
243 " '%s' but flag already inferred from pattern.\n",
244 Inst.TheDef->getName().c_str());
245 HasSideEffects = false;
246 }
238247 }
239248
240249
298307 const OperandInfoMapTy &OpInfo,
299308 std::ostream &OS) {
300309 // Determine properties of the instruction from its pattern.
301 bool mayStore, mayLoad, NeverHasSideEffects;
302 InferFromPattern(Inst, mayStore, mayLoad, NeverHasSideEffects);
303
304 if (NeverHasSideEffects && Inst.mayHaveSideEffects) {
305 std::cerr << "error: Instruction '" << Inst.TheDef->getName()
306 << "' is marked with 'mayHaveSideEffects', but it can never have them!\n";
307 exit(1);
308 }
310 bool mayStore, mayLoad, HasSideEffects;
311 InferFromPattern(Inst, mayStore, mayLoad, HasSideEffects);
309312
310313 int MinOperands = 0;
311314 if (!Inst.OperandList.empty())
340343 OS << "|(1<
341344 if (Inst.isVariadic) OS << "|(1<
342345 if (Inst.mayHaveSideEffects) OS << "|(1<
343 if (NeverHasSideEffects) OS << "|(1<
346 if (!HasSideEffects) OS << "|(1<
344347 OS << ", 0";
345348
346349 // Emit all of the target-specific flags...
4242
4343 // Instruction analysis.
4444 void InferFromPattern(const CodeGenInstruction &Inst,
45 bool &isStore, bool &isLoad, bool &NeverHasSideEffects);
45 bool &MayStore, bool &MayLoad, bool &HasSideEffects);
4646
4747 void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
4848 Record *InstrInfo,