llvm.org GIT mirror llvm / 912519a
Heed guessInstructionProperties, and stop warning on redundant flags. Emit TableGen errors if guessInstructionProperties is 0 and instruction properties can't be inferred from patterns. Allow explicit instruction properties even when they can be inferred. This patch doesn't change the TableGen output. Redundant properties are not yet verified because the tree has errors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162516 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 7 years ago
3 changed file(s) with 95 addition(s) and 96 deletion(s). Raw diff Collapse all Expand all
23662366
23672367 class InstAnalyzer {
23682368 const CodeGenDAGPatterns &CDP;
2369 bool &mayStore;
2370 bool &mayLoad;
2371 bool &IsBitcast;
2372 bool &HasSideEffects;
2373 bool &IsVariadic;
23742369 public:
2375 InstAnalyzer(const CodeGenDAGPatterns &cdp,
2376 bool &maystore, bool &mayload, bool &isbc, bool &hse, bool &isv)
2377 : CDP(cdp), mayStore(maystore), mayLoad(mayload), IsBitcast(isbc),
2378 HasSideEffects(hse), IsVariadic(isv) {
2379 }
2380
2381 /// Analyze - Analyze the specified instruction, returning true if the
2382 /// instruction had a pattern.
2383 bool Analyze(Record *InstRecord) {
2384 const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
2385 if (Pattern == 0) {
2386 HasSideEffects = 1;
2387 return false; // No pattern.
2388 }
2389
2390 // FIXME: Assume only the first tree is the pattern. The others are clobber
2391 // nodes.
2392 AnalyzeNode(Pattern->getTree(0));
2393 return true;
2370 bool hasSideEffects;
2371 bool mayStore;
2372 bool mayLoad;
2373 bool isBitcast;
2374 bool isVariadic;
2375
2376 InstAnalyzer(const CodeGenDAGPatterns &cdp)
2377 : CDP(cdp), hasSideEffects(false), mayStore(false), mayLoad(false),
2378 isBitcast(false), isVariadic(false) {}
2379
2380 void Analyze(const TreePattern *Pat) {
2381 // Assume only the first tree is the pattern. The others are clobber nodes.
2382 AnalyzeNode(Pat->getTree(0));
23942383 }
23952384
23962385 private:
23972386 bool IsNodeBitcast(const TreePatternNode *N) const {
2398 if (HasSideEffects || mayLoad || mayStore || IsVariadic)
2387 if (hasSideEffects || mayLoad || mayStore || isVariadic)
23992388 return false;
24002389
24012390 if (N->getNumChildren() != 2)
24262415 const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
24272416 if (CP.hasProperty(SDNPMayStore)) mayStore = true;
24282417 if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
2429 if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
2418 if (CP.hasProperty(SDNPSideEffect)) hasSideEffects = true;
24302419 }
24312420 }
24322421 return;
24382427
24392428 // Ignore set nodes, which are not SDNodes.
24402429 if (N->getOperator()->getName() == "set") {
2441 IsBitcast = IsNodeBitcast(N);
2430 isBitcast = IsNodeBitcast(N);
24422431 return;
24432432 }
24442433
24482437 // Notice properties of the node.
24492438 if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
24502439 if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
2451 if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
2452 if (OpInfo.hasProperty(SDNPVariadic)) IsVariadic = true;
2440 if (OpInfo.hasProperty(SDNPSideEffect)) hasSideEffects = true;
2441 if (OpInfo.hasProperty(SDNPVariadic)) isVariadic = true;
24532442
24542443 if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
24552444 // If this is an intrinsic, analyze it.
24612450
24622451 if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem)
24632452 // WriteMem intrinsics can have other strange effects.
2464 HasSideEffects = true;
2453 hasSideEffects = true;
24652454 }
24662455 }
24672456
24682457 };
24692458
2470 static void InferFromPattern(const CodeGenInstruction &Inst,
2471 bool &MayStore, bool &MayLoad,
2472 bool &IsBitcast,
2473 bool &HasSideEffects, bool &IsVariadic,
2474 const CodeGenDAGPatterns &CDP) {
2475 MayStore = MayLoad = IsBitcast = HasSideEffects = IsVariadic = false;
2476
2477 bool HadPattern =
2478 InstAnalyzer(CDP, MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic)
2479 .Analyze(Inst.TheDef);
2480
2481 // InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
2482 if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it.
2483 // If we decided that this is a store from the pattern, then the .td file
2484 // entry is redundant.
2485 if (MayStore)
2486 PrintWarning(Inst.TheDef->getLoc(),
2487 "mayStore flag explicitly set on "
2488 "instruction, but flag already inferred from pattern.");
2489 MayStore = true;
2490 }
2491
2492 if (Inst.mayLoad) { // If the .td file explicitly sets mayLoad, use it.
2493 // If we decided that this is a load from the pattern, then the .td file
2494 // entry is redundant.
2495 if (MayLoad)
2496 PrintWarning(Inst.TheDef->getLoc(),
2497 "mayLoad flag explicitly set on "
2498 "instruction, but flag already inferred from pattern.");
2499 MayLoad = true;
2500 }
2501
2502 if (Inst.neverHasSideEffects) {
2503 if (HadPattern)
2504 PrintWarning(Inst.TheDef->getLoc(),
2505 "neverHasSideEffects flag explicitly set on "
2506 "instruction, but flag already inferred from pattern.");
2507 HasSideEffects = false;
2508 }
2509
2510 if (Inst.hasSideEffects) {
2511 if (HasSideEffects)
2512 PrintWarning(Inst.TheDef->getLoc(),
2513 "hasSideEffects flag explicitly set on "
2514 "instruction, but flag already inferred from pattern.");
2515 HasSideEffects = true;
2516 }
2517
2518 if (Inst.Operands.isVariadic)
2519 IsVariadic = true; // Can warn if we want.
2459 static void InferFromPattern(CodeGenInstruction &InstInfo,
2460 const InstAnalyzer &PatInfo,
2461 Record *PatDef) {
2462 // Remember where InstInfo got its flags.
2463 if (InstInfo.hasUndefFlags())
2464 InstInfo.InferredFrom = PatDef;
2465
2466 // Transfer inferred flags.
2467 InstInfo.hasSideEffects |= PatInfo.hasSideEffects;
2468 InstInfo.mayStore |= PatInfo.mayStore;
2469 InstInfo.mayLoad |= PatInfo.mayLoad;
2470
2471 // These flags are silently added without any verification.
2472 InstInfo.isBitcast |= PatInfo.isBitcast;
2473 InstInfo.Operands.isVariadic |= PatInfo.isVariadic;
25202474 }
25212475
25222476 /// hasNullFragReference - Return true if the DAG has any reference to the
28512805 void CodeGenDAGPatterns::InferInstructionFlags() {
28522806 const std::vector &Instructions =
28532807 Target.getInstructionsByEnumValue();
2808
2809 // First try to infer flags from the primary instruction pattern, if any.
2810 SmallVector Revisit;
28542811 for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
28552812 CodeGenInstruction &InstInfo =
28562813 const_cast(*Instructions[i]);
2857 // Determine properties of the instruction from its pattern.
2858 bool MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic;
2859 InferFromPattern(InstInfo, MayStore, MayLoad, IsBitcast,
2860 HasSideEffects, IsVariadic, *this);
2861 InstInfo.mayStore = MayStore;
2862 InstInfo.mayLoad = MayLoad;
2863 InstInfo.isBitcast = IsBitcast;
2864 InstInfo.hasSideEffects = HasSideEffects;
2865 InstInfo.Operands.isVariadic = IsVariadic;
2866
2867 // Sanity checks.
2868 if (InstInfo.isReMaterializable && InstInfo.hasSideEffects)
2869 throw TGError(InstInfo.TheDef->getLoc(), "The instruction " +
2870 InstInfo.TheDef->getName() +
2871 " is rematerializable AND has unmodeled side effects?");
2814
2815 // Treat neverHasSideEffects = 1 as the equivalent of hasSideEffects = 0.
2816 // This flag is obsolete and will be removed.
2817 if (InstInfo.neverHasSideEffects) {
2818 assert(!InstInfo.hasSideEffects);
2819 InstInfo.hasSideEffects_Unset = false;
2820 }
2821
2822 // Get the primary instruction pattern.
2823 const TreePattern *Pattern = getInstruction(InstInfo.TheDef).getPattern();
2824 if (!Pattern) {
2825 if (InstInfo.hasUndefFlags())
2826 Revisit.push_back(&InstInfo);
2827 continue;
2828 }
2829 InstAnalyzer PatInfo(*this);
2830 PatInfo.Analyze(Pattern);
2831 InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef);
2832 }
2833
2834 // Revisit instructions with undefined flags and no pattern.
2835 if (Target.guessInstructionProperties()) {
2836 for (unsigned i = 0, e = Revisit.size(); i != e; ++i) {
2837 CodeGenInstruction &InstInfo = *Revisit[i];
2838 if (InstInfo.InferredFrom)
2839 continue;
2840 // The mayLoad and mayStore flags default to false.
2841 // Conservatively assume hasSideEffects if it wasn't explicit.
2842 if (InstInfo.hasSideEffects_Unset)
2843 InstInfo.hasSideEffects = true;
2844 }
2845 return;
2846 }
2847
2848 // Complain about any flags that are still undefined.
2849 for (unsigned i = 0, e = Revisit.size(); i != e; ++i) {
2850 CodeGenInstruction &InstInfo = *Revisit[i];
2851 if (InstInfo.InferredFrom)
2852 continue;
2853 if (InstInfo.hasSideEffects_Unset)
2854 PrintError(InstInfo.TheDef->getLoc(),
2855 "Can't infer hasSideEffects from patterns");
2856 if (InstInfo.mayStore_Unset)
2857 PrintError(InstInfo.TheDef->getLoc(),
2858 "Can't infer mayStore from patterns");
2859 if (InstInfo.mayLoad_Unset)
2860 PrintError(InstInfo.TheDef->getLoc(),
2861 "Can't infer mayLoad from patterns");
28722862 }
28732863 }
28742864
286286 // CodeGenInstruction Implementation
287287 //===----------------------------------------------------------------------===//
288288
289 CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) {
289 CodeGenInstruction::CodeGenInstruction(Record *R)
290 : TheDef(R), Operands(R), InferredFrom(0) {
290291 Namespace = R->getValueAsString("Namespace");
291292 AsmString = R->getValueAsString("AsmString");
292293
248248 bool isCodeGenOnly;
249249 bool isPseudo;
250250
251 /// Are there any undefined flags?
252 bool hasUndefFlags() const {
253 return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
254 }
255
256 // The record used to infer instruction flags, or NULL if no flag values
257 // have been inferred.
258 Record *InferredFrom;
251259
252260 CodeGenInstruction(Record *R);
253261