diff options
Diffstat (limited to 'lib/CodeGen')
| -rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 1 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGenPrepare.cpp | 3 | ||||
| -rw-r--r-- | lib/CodeGen/LiveDebugValues.cpp | 17 | ||||
| -rw-r--r-- | lib/CodeGen/MachineCSE.cpp | 25 | ||||
| -rw-r--r-- | lib/CodeGen/MachineModuleInfo.cpp | 2 | ||||
| -rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp | 10 | ||||
| -rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 1 | ||||
| -rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 35 | ||||
| -rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 18 | 
9 files changed, 94 insertions, 18 deletions
| diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index 7721e996aca5..5e49fec9c053 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -432,6 +432,7 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,                const BlockAddress *BA = MI->getOperand(OpNo).getBlockAddress();                MCSymbol *Sym = AP->GetBlockAddressSymbol(BA);                Sym->print(OS, AP->MAI); +              MMI->getContext().registerInlineAsmLabel(Sym);              } else if (MI->getOperand(OpNo).isMBB()) {                const MCSymbol *Sym = MI->getOperand(OpNo).getMBB()->getSymbol();                Sym->print(OS, AP->MAI); diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp index 52b4bbea012b..e6f2aa9ef930 100644 --- a/lib/CodeGen/CodeGenPrepare.cpp +++ b/lib/CodeGen/CodeGenPrepare.cpp @@ -1682,10 +1682,11 @@ static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI,      TheUse = InsertedShift;    } -  // If we removed all uses, nuke the shift. +  // If we removed all uses, or there are none, nuke the shift.    if (ShiftI->use_empty()) {      salvageDebugInfo(*ShiftI);      ShiftI->eraseFromParent(); +    MadeChange = true;    }    return MadeChange; diff --git a/lib/CodeGen/LiveDebugValues.cpp b/lib/CodeGen/LiveDebugValues.cpp index a669e64692b9..05e994c9eb51 100644 --- a/lib/CodeGen/LiveDebugValues.cpp +++ b/lib/CodeGen/LiveDebugValues.cpp @@ -691,9 +691,17 @@ void LiveDebugValues::insertTransferDebugPair(             "No register supplied when handling a restore of a debug value");      MachineFunction *MF = MI.getMF();      DIBuilder DIB(*const_cast<Function &>(MF->getFunction()).getParent()); + +    const DIExpression *NewExpr; +    if (auto Fragment = DebugInstr->getDebugExpression()->getFragmentInfo()) +      NewExpr = *DIExpression::createFragmentExpression(DIB.createExpression(), +        Fragment->OffsetInBits, Fragment->SizeInBits); +    else +      NewExpr = DIB.createExpression(); +      NewDebugInstr =          BuildMI(*MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(), false, -                NewReg, DebugInstr->getDebugVariable(), DIB.createExpression()); +                NewReg, DebugInstr->getDebugVariable(), NewExpr);      VarLoc VL(*NewDebugInstr, LS);      ProcessVarLoc(VL, NewDebugInstr);      LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for register restore: "; @@ -848,9 +856,14 @@ void LiveDebugValues::transferSpillOrRestoreInst(MachineInstr &MI,                        << "\n");    }    // Check if the register or spill location is the location of a debug value. +  // FIXME: Don't create a spill transfer if there is a complex expression, +  // because we currently cannot recover the original expression on restore.    for (unsigned ID : OpenRanges.getVarLocs()) { +    const MachineInstr *DebugInstr = &VarLocIDs[ID].MI; +      if (TKind == TransferKind::TransferSpill && -        VarLocIDs[ID].isDescribedByReg() == Reg) { +        VarLocIDs[ID].isDescribedByReg() == Reg && +        !DebugInstr->getDebugExpression()->isComplex()) {        LLVM_DEBUG(dbgs() << "Spilling Register " << printReg(Reg, TRI) << '('                          << VarLocIDs[ID].Var.getVar()->getName() << ")\n");      } else if (TKind == TransferKind::TransferRestore && diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index 2df6d40d9293..a5af5cb72df9 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -21,6 +21,7 @@  #include "llvm/Analysis/AliasAnalysis.h"  #include "llvm/Analysis/CFG.h"  #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"  #include "llvm/CodeGen/MachineDominators.h"  #include "llvm/CodeGen/MachineFunction.h"  #include "llvm/CodeGen/MachineFunctionPass.h" @@ -66,6 +67,7 @@ namespace {      AliasAnalysis *AA;      MachineDominatorTree *DT;      MachineRegisterInfo *MRI; +    MachineBlockFrequencyInfo *MBFI;    public:      static char ID; // Pass identification @@ -83,6 +85,8 @@ namespace {        AU.addPreservedID(MachineLoopInfoID);        AU.addRequired<MachineDominatorTree>();        AU.addPreserved<MachineDominatorTree>(); +      AU.addRequired<MachineBlockFrequencyInfo>(); +      AU.addPreserved<MachineBlockFrequencyInfo>();      }      void releaseMemory() override { @@ -133,6 +137,11 @@ namespace {      bool isPRECandidate(MachineInstr *MI);      bool ProcessBlockPRE(MachineDominatorTree *MDT, MachineBasicBlock *MBB);      bool PerformSimplePRE(MachineDominatorTree *DT); +    /// Heuristics to see if it's beneficial to move common computations of MBB +    /// and MBB1 to CandidateBB. +    bool isBeneficalToHoistInto(MachineBasicBlock *CandidateBB, +                                MachineBasicBlock *MBB, +                                MachineBasicBlock *MBB1);    };  } // end anonymous namespace @@ -802,6 +811,9 @@ bool MachineCSE::ProcessBlockPRE(MachineDominatorTree *DT,      if (!CMBB->isLegalToHoistInto())        continue; +    if (!isBeneficalToHoistInto(CMBB, MBB, MBB1)) +      continue; +      // Two instrs are partial redundant if their basic blocks are reachable      // from one to another but one doesn't dominate another.      if (CMBB != MBB1) { @@ -854,6 +866,18 @@ bool MachineCSE::PerformSimplePRE(MachineDominatorTree *DT) {    return Changed;  } +bool MachineCSE::isBeneficalToHoistInto(MachineBasicBlock *CandidateBB, +                                        MachineBasicBlock *MBB, +                                        MachineBasicBlock *MBB1) { +  if (CandidateBB->getParent()->getFunction().hasMinSize()) +    return true; +  assert(DT->dominates(CandidateBB, MBB) && "CandidateBB should dominate MBB"); +  assert(DT->dominates(CandidateBB, MBB1) && +         "CandidateBB should dominate MBB1"); +  return MBFI->getBlockFreq(CandidateBB) <= +         MBFI->getBlockFreq(MBB) + MBFI->getBlockFreq(MBB1); +} +  bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {    if (skipFunction(MF.getFunction()))      return false; @@ -863,6 +887,7 @@ bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {    MRI = &MF.getRegInfo();    AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();    DT = &getAnalysis<MachineDominatorTree>(); +  MBFI = &getAnalysis<MachineBlockFrequencyInfo>();    LookAheadLimit = TII->getMachineCSELookAheadLimit();    bool ChangedPRE, ChangedCSE;    ChangedPRE = PerformSimplePRE(DT); diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index aadcd7319799..2e720018262c 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -121,7 +121,7 @@ ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {    BBCallbacks.back().setMap(this);    Entry.Index = BBCallbacks.size() - 1;    Entry.Fn = BB->getParent(); -  Entry.Symbols.push_back(Context.createTempSymbol()); +  Entry.Symbols.push_back(Context.createTempSymbol(!BB->hasAddressTaken()));    return Entry.Symbols;  } diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp index 568c6191e512..e09f2e760f55 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -909,6 +909,12 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {        // Remember the source order of the inserted instruction.        if (HasDbg)          ProcessSourceNode(N, DAG, Emitter, VRBaseMap, Orders, Seen, NewInsn); + +      if (MDNode *MD = DAG->getHeapAllocSite(N)) { +        if (NewInsn && NewInsn->isCall()) +          MF.addCodeViewHeapAllocSite(NewInsn, MD); +      } +        GluedNodes.pop_back();      }      auto NewInsn = @@ -917,6 +923,10 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {      if (HasDbg)        ProcessSourceNode(SU->getNode(), DAG, Emitter, VRBaseMap, Orders, Seen,                          NewInsn); +    if (MDNode *MD = DAG->getHeapAllocSite(SU->getNode())) { +      if (NewInsn && NewInsn->isCall()) +        MF.addCodeViewHeapAllocSite(NewInsn, MD); +    }    }    // Insert all the dbg_values which have not already been inserted in source diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 5852e693fa9f..6b0245dfd380 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1084,6 +1084,7 @@ void SelectionDAG::clear() {    ExternalSymbols.clear();    TargetExternalSymbols.clear();    MCSymbols.clear(); +  SDCallSiteDbgInfo.clear();    std::fill(CondCodeNodes.begin(), CondCodeNodes.end(),              static_cast<CondCodeSDNode*>(nullptr));    std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(), diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index e818dd27c05e..3c02c36a7d26 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8021,6 +8021,14 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {      // Compute the constraint code and ConstraintType to use.      TLI.ComputeConstraintToUse(T, SDValue()); +    if (T.ConstraintType == TargetLowering::C_Immediate && +        OpInfo.CallOperand && !isa<ConstantSDNode>(OpInfo.CallOperand)) +      // We've delayed emitting a diagnostic like the "n" constraint because +      // inlining could cause an integer showing up. +      return emitInlineAsmError( +          CS, "constraint '" + Twine(T.ConstraintCode) + "' expects an " +                  "integer constant expression"); +      ExtraInfo.update(T);    } @@ -8105,7 +8113,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {      switch (OpInfo.Type) {      case InlineAsm::isOutput:        if (OpInfo.ConstraintType == TargetLowering::C_Memory || -          (OpInfo.ConstraintType == TargetLowering::C_Other && +          ((OpInfo.ConstraintType == TargetLowering::C_Immediate || +            OpInfo.ConstraintType == TargetLowering::C_Other) &&             OpInfo.isIndirect)) {          unsigned ConstraintID =              TLI.getInlineAsmMemConstraint(OpInfo.ConstraintCode); @@ -8119,13 +8128,14 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {                                                          MVT::i32));          AsmNodeOperands.push_back(OpInfo.CallOperand);          break; -      } else if ((OpInfo.ConstraintType == TargetLowering::C_Other && +      } else if (((OpInfo.ConstraintType == TargetLowering::C_Immediate || +                   OpInfo.ConstraintType == TargetLowering::C_Other) &&                    !OpInfo.isIndirect) ||                   OpInfo.ConstraintType == TargetLowering::C_Register ||                   OpInfo.ConstraintType == TargetLowering::C_RegisterClass) {          // Otherwise, this outputs to a register (directly for C_Register / -        // C_RegisterClass, and a target-defined fashion for C_Other). Find a -        // register that we can use. +        // C_RegisterClass, and a target-defined fashion for +        // C_Immediate/C_Other). Find a register that we can use.          if (OpInfo.AssignedRegs.Regs.empty()) {            emitInlineAsmError(                CS, "couldn't allocate output register for constraint '" + @@ -8205,15 +8215,24 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {        }        // Treat indirect 'X' constraint as memory. -      if (OpInfo.ConstraintType == TargetLowering::C_Other && +      if ((OpInfo.ConstraintType == TargetLowering::C_Immediate || +           OpInfo.ConstraintType == TargetLowering::C_Other) &&            OpInfo.isIndirect)          OpInfo.ConstraintType = TargetLowering::C_Memory; -      if (OpInfo.ConstraintType == TargetLowering::C_Other) { +      if (OpInfo.ConstraintType == TargetLowering::C_Immediate || +          OpInfo.ConstraintType == TargetLowering::C_Other) {          std::vector<SDValue> Ops;          TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode,                                            Ops, DAG);          if (Ops.empty()) { +          if (OpInfo.ConstraintType == TargetLowering::C_Immediate) +            if (isa<ConstantSDNode>(InOperandVal)) { +              emitInlineAsmError(CS, "value out of range for constraint '" + +                                 Twine(OpInfo.ConstraintCode) + "'"); +              return; +            } +            emitInlineAsmError(CS, "invalid operand for inline asm constraint '" +                                       Twine(OpInfo.ConstraintCode) + "'");            return; @@ -8250,7 +8269,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {        }        assert((OpInfo.ConstraintType == TargetLowering::C_RegisterClass || -              OpInfo.ConstraintType == TargetLowering::C_Register) && +              OpInfo.ConstraintType == TargetLowering::C_Register || +              OpInfo.ConstraintType == TargetLowering::C_Immediate) &&               "Unknown constraint type!");        // TODO: Support this. @@ -8356,6 +8376,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {          Val = OpInfo.AssignedRegs.getCopyFromRegs(              DAG, FuncInfo, getCurSDLoc(), Chain, &Flag, CS.getInstruction());          break; +      case TargetLowering::C_Immediate:        case TargetLowering::C_Other:          Val = TLI.LowerAsmOutputForConstraint(Chain, Flag, getCurSDLoc(),                                                OpInfo, DAG); diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index b260cd91d468..2d90dcba12b6 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3567,15 +3567,17 @@ TargetLowering::getConstraintType(StringRef Constraint) const {    if (S == 1) {      switch (Constraint[0]) {      default: break; -    case 'r': return C_RegisterClass; +    case 'r': +      return C_RegisterClass;      case 'm': // memory      case 'o': // offsetable      case 'V': // not offsetable        return C_Memory; -    case 'i': // Simple Integer or Relocatable Constant      case 'n': // Simple Integer      case 'E': // Floating Point Constant      case 'F': // Floating Point Constant +      return C_Immediate; +    case 'i': // Simple Integer or Relocatable Constant      case 's': // Relocatable Constant      case 'p': // Address.      case 'X': // Allow ANY value. @@ -3950,6 +3952,7 @@ TargetLowering::ParseConstraints(const DataLayout &DL,  /// Return an integer indicating how general CT is.  static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) {    switch (CT) { +  case TargetLowering::C_Immediate:    case TargetLowering::C_Other:    case TargetLowering::C_Unknown:      return 0; @@ -4069,11 +4072,12 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo,      TargetLowering::ConstraintType CType =        TLI.getConstraintType(OpInfo.Codes[i]); -    // If this is an 'other' constraint, see if the operand is valid for it. -    // For example, on X86 we might have an 'rI' constraint.  If the operand -    // is an integer in the range [0..31] we want to use I (saving a load -    // of a register), otherwise we must use 'r'. -    if (CType == TargetLowering::C_Other && Op.getNode()) { +    // If this is an 'other' or 'immediate' constraint, see if the operand is +    // valid for it. For example, on X86 we might have an 'rI' constraint. If +    // the operand is an integer in the range [0..31] we want to use I (saving a +    // load of a register), otherwise we must use 'r'. +    if ((CType == TargetLowering::C_Other || +         CType == TargetLowering::C_Immediate) && Op.getNode()) {        assert(OpInfo.Codes[i].size() == 1 &&               "Unhandled multi-letter 'other' constraint");        std::vector<SDValue> ResultOps; | 
