diff options
| -rw-r--r-- | llvm/include/llvm/CodeGen/FastISel.h | 7 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 15 | 
2 files changed, 18 insertions, 4 deletions
diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h index 32d6bb03ec1..c233cd48f44 100644 --- a/llvm/include/llvm/CodeGen/FastISel.h +++ b/llvm/include/llvm/CodeGen/FastISel.h @@ -226,6 +226,10 @@ protected:    /// makes sense (for example, on function calls)    MachineInstr *EmitStartPt; +  /// Last local value flush point. On a subsequent flush, no local value will +  /// sink past this point. +  MachineBasicBlock::iterator LastFlushPoint; +  public:    virtual ~FastISel(); @@ -569,7 +573,8 @@ private:      MachineInstr *FirstTerminator = nullptr;      unsigned FirstTerminatorOrder = std::numeric_limits<unsigned>::max(); -    void initialize(MachineBasicBlock *MBB); +    void initialize(MachineBasicBlock *MBB, +                    MachineBasicBlock::iterator LastFlushPoint);    };    /// Sinks the local value materialization instruction LocalMI to its first use diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 84196062491..23a7798f867 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -215,6 +215,7 @@ void FastISel::flushLocalValueMap() {    LastLocalValue = EmitStartPt;    recomputeInsertPt();    SavedInsertPt = FuncInfo.InsertPt; +  LastFlushPoint = FuncInfo.InsertPt;  }  static bool isRegUsedByPhiNodes(unsigned DefReg, @@ -228,7 +229,8 @@ static bool isRegUsedByPhiNodes(unsigned DefReg,  /// Build a map of instruction orders. Return the first terminator and its  /// order. Consider EH_LABEL instructions to be terminators as well, since local  /// values for phis after invokes must be materialized before the call. -void FastISel::InstOrderMap::initialize(MachineBasicBlock *MBB) { +void FastISel::InstOrderMap::initialize( +    MachineBasicBlock *MBB, MachineBasicBlock::iterator LastFlushPoint) {    unsigned Order = 0;    for (MachineInstr &I : *MBB) {      if (!FirstTerminator && @@ -237,6 +239,10 @@ void FastISel::InstOrderMap::initialize(MachineBasicBlock *MBB) {        FirstTerminatorOrder = Order;      }      Orders[&I] = Order++; + +    // We don't need to order instructions past the last flush point. +    if (I.getIterator() == LastFlushPoint) +      break;    }  } @@ -266,13 +272,16 @@ void FastISel::sinkLocalValueMaterialization(MachineInstr &LocalMI,    // Number the instructions if we haven't yet so we can efficiently find the    // earliest use.    if (OrderMap.Orders.empty()) -    OrderMap.initialize(FuncInfo.MBB); +    OrderMap.initialize(FuncInfo.MBB, LastFlushPoint);    // Find the first user in the BB.    MachineInstr *FirstUser = nullptr;    unsigned FirstOrder = std::numeric_limits<unsigned>::max();    for (MachineInstr &UseInst : MRI.use_nodbg_instructions(DefReg)) { -    unsigned UseOrder = OrderMap.Orders[&UseInst]; +    auto I = OrderMap.Orders.find(&UseInst); +    assert(I != OrderMap.Orders.end() && +           "local value used by instruction outside local region"); +    unsigned UseOrder = I->second;      if (UseOrder < FirstOrder) {        FirstOrder = UseOrder;        FirstUser = &UseInst;  | 

