diff options
| -rw-r--r-- | llvm/include/llvm/CodeGen/MachineInstr.h | 8 | ||||
| -rw-r--r-- | llvm/include/llvm/InlineAsm.h | 2 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MachineVerifier.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ScheduleDAGInstrs.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 20 | 
6 files changed, 36 insertions, 11 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index eab74bd3019..42709012d21 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -58,8 +58,10 @@ public:      NoFlags      = 0,      FrameSetup   = 1 << 0,              // Instruction is used as a part of                                          // function frame setup code. -    InsideBundle = 1 << 1               // Instruction is inside a bundle (not +    InsideBundle = 1 << 1,              // Instruction is inside a bundle (not                                          // the first MI in a bundle) +    MayLoad      = 1 << 2,              // Instruction could possibly read memory. +    MayStore     = 1 << 3               // Instruction could possibly modify memory.    };  private:    const MCInstrDesc *MCID;              // Instruction descriptor. @@ -445,7 +447,7 @@ public:    /// Instructions with this flag set are not necessarily simple load    /// instructions, they may load a value and modify it, for example.    bool mayLoad(QueryType Type = AnyInBundle) const { -    return hasProperty(MCID::MayLoad, Type); +    return hasProperty(MCID::MayLoad, Type) || (Flags & MayLoad);    } @@ -454,7 +456,7 @@ public:    /// instructions, they may store a modified value based on their operands, or    /// may not actually modify anything, for example.    bool mayStore(QueryType Type = AnyInBundle) const { -    return hasProperty(MCID::MayStore, Type); +    return hasProperty(MCID::MayStore, Type) || (Flags & MayStore);    }    //===--------------------------------------------------------------------===// diff --git a/llvm/include/llvm/InlineAsm.h b/llvm/include/llvm/InlineAsm.h index c6e0aab05e7..b5e0fd4effd 100644 --- a/llvm/include/llvm/InlineAsm.h +++ b/llvm/include/llvm/InlineAsm.h @@ -214,6 +214,8 @@ public:      Extra_HasSideEffects = 1,      Extra_IsAlignStack = 2,      Extra_AsmDialect = 4, +    Extra_MayLoad = 8, +    Extra_MayStore = 16,      // Inline asm operands map to multiple SDNode / MachineInstr operands.      // The first operand is an immediate describing the asm operand, the low diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index dca68da2f3e..69a3ae84ec9 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -707,8 +707,9 @@ void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) {      report("Asm string must be an external symbol", MI);    if (!MI->getOperand(1).isImm())      report("Asm flags must be an immediate", MI); -  // Allowed flags are Extra_HasSideEffects = 1, and Extra_IsAlignStack = 2. -  if (!isUInt<2>(MI->getOperand(1).getImm())) +  // Allowed flags are Extra_HasSideEffects = 1, Extra_IsAlignStack = 2, +  // Extra_AsmDialect = 4, Extra_MayLoad = 8, and Extra_MayStore = 16. +  if (!isUInt<5>(MI->getOperand(1).getImm()))      report("Unknown asm flags", &MI->getOperand(1), 1);    assert(InlineAsm::MIOp_FirstOperand == 2 && "Asm format changed"); diff --git a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp index 8ea0f8a3eac..496473d3a4b 100644 --- a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -420,11 +420,6 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {  /// Return true if MI is an instruction we are unable to reason about  /// (like a call or something with unmodeled side effects).  static inline bool isGlobalMemoryObject(AliasAnalysis *AA, MachineInstr *MI) { -  if (MI->isInlineAsm()) { -    // Until we can tell if an inline assembly instruction accesses -    // memory, we must assume all such instructions do so. -    return true; -  }    if (MI->isCall() || MI->hasUnmodeledSideEffects() ||        (MI->hasOrderedMemoryRef() &&         (!MI->mayLoad() || !MI->isInvariantLoad(AA)))) diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index d1baa3f7167..5fc71cc2238 100644 --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -903,6 +903,13 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,                            getZExtValue();      MI->addOperand(MachineOperand::CreateImm(ExtraInfo)); +    // Set the MayLoad and MayStore flags. +    if (ExtraInfo & InlineAsm::Extra_MayLoad) +      MI->setFlag(MachineInstr::MayLoad); + +    if (ExtraInfo & InlineAsm::Extra_MayStore) +      MI->setFlag(MachineInstr::MayStore); +      // Remember to operand index of the group flags.      SmallVector<unsigned, 8> GroupIdx; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 85103d5750a..eacba90f0ce 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6128,7 +6128,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {    const MDNode *SrcLoc = CS.getInstruction()->getMetadata("srcloc");    AsmNodeOperands.push_back(DAG.getMDNode(SrcLoc)); -  // Remember the HasSideEffect, AlignStack and AsmDialect bits as operand 3. +  // Remember the HasSideEffect, AlignStack, AsmDialect, MayLoad and MayStore +  // bits as operand 3.    unsigned ExtraInfo = 0;    if (IA->hasSideEffects())      ExtraInfo |= InlineAsm::Extra_HasSideEffects; @@ -6136,6 +6137,23 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {      ExtraInfo |= InlineAsm::Extra_IsAlignStack;    // Set the asm dialect.    ExtraInfo |= IA->getDialect() * InlineAsm::Extra_AsmDialect; + +  // Determine if this InlineAsm MayLoad or MayStore based on the constraints. +  for (unsigned i = 0, e = TargetConstraints.size(); i != e; ++i) { +    TargetLowering::AsmOperandInfo &OpInfo = TargetConstraints[i]; + +    // Compute the constraint code and ConstraintType to use. +    TLI.ComputeConstraintToUse(OpInfo, SDValue()); + +    if (OpInfo.ConstraintType == TargetLowering::C_Memory || +        OpInfo.ConstraintType == TargetLowering::C_Other) { +      if (OpInfo.Type == InlineAsm::isInput) +        ExtraInfo |= InlineAsm::Extra_MayLoad; +      else if (OpInfo.Type == InlineAsm::isOutput) +        ExtraInfo |= InlineAsm::Extra_MayStore; +    } +  } +    AsmNodeOperands.push_back(DAG.getTargetConstant(ExtraInfo,                                                    TLI.getPointerTy()));  | 

