diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-07-15 17:06:11 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-07-15 17:06:11 +0000 |
commit | c1c3262b63b1d5fbba6a7ad188f4e47d92c7840e (patch) | |
tree | 5b6d391c72c9875f0065f0e772e872bc8544834b /lib/CodeGen | |
parent | 9112829d76cbb8e0c8ef51bbc2d7d1be48cd7b74 (diff) | |
download | FreeBSD-src-c1c3262b63b1d5fbba6a7ad188f4e47d92c7840e.zip FreeBSD-src-c1c3262b63b1d5fbba6a7ad188f4e47d92c7840e.tar.gz |
Update LLVM to r108428.
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/LiveInterval.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/MachineLICM.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/MachineModuleInfo.cpp | 23 | ||||
-rw-r--r-- | lib/CodeGen/ProcessImplicitDefs.cpp | 54 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/FastISel.cpp | 45 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 13 |
8 files changed, 91 insertions, 86 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d9387a8..db1b37a 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -178,7 +178,7 @@ bool AsmPrinter::doInitialization(Module &M) { if (!M.getModuleInlineAsm().empty()) { OutStreamer.AddComment("Start of file scope inline assembly"); OutStreamer.AddBlankLine(); - EmitInlineAsm(M.getModuleInlineAsm(), 0/*no loc cookie*/); + EmitInlineAsm(M.getModuleInlineAsm()+"\n", 0/*no loc cookie*/); OutStreamer.AddComment("End of file scope inline assembly"); OutStreamer.AddBlankLine(); } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index f6f3bae..202d9b6 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -53,17 +53,6 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, unsigned LocCookie) const { } SourceMgr SrcMgr; - - // Ensure the buffer is newline terminated. - char *TmpString = 0; - if (Str.back() != '\n') { - TmpString = new char[Str.size() + 2]; - memcpy(TmpString, Str.data(), Str.size()); - TmpString[Str.size()] = '\n'; - TmpString[Str.size() + 1] = 0; - isNullTerminated = true; - Str = TmpString; - } // If the current LLVMContext has an inline asm handler, set it in SourceMgr. LLVMContext &LLVMCtx = MMI->getModule()->getContext(); @@ -95,9 +84,6 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, unsigned LocCookie) const { /*NoFinalize*/ true); if (Res && !HasDiagHandler) report_fatal_error("Error parsing inline asm\n"); - - if (TmpString) - delete[] TmpString; } diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 21a9b7d..ad57284 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -119,6 +119,7 @@ bool LiveInterval::killedInRange(SlotIndex Start, SlotIndex End) const { // bool LiveInterval::overlapsFrom(const LiveInterval& other, const_iterator StartPos) const { + assert(!empty() && "empty interval"); const_iterator i = begin(); const_iterator ie = end(); const_iterator j = StartPos; @@ -161,16 +162,8 @@ bool LiveInterval::overlapsFrom(const LiveInterval& other, /// by [Start, End). bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const { assert(Start < End && "Invalid range"); - const_iterator I = begin(); - const_iterator E = end(); - const_iterator si = std::upper_bound(I, E, Start); - const_iterator ei = std::upper_bound(I, E, End); - if (si != ei) - return true; - if (si == I) - return false; - --si; - return si->contains(Start); + const_iterator I = std::lower_bound(begin(), end(), End); + return I != begin() && (--I)->end > Start; } /// extendIntervalEndTo - This method is used when we want to extend the range @@ -868,6 +861,10 @@ void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const { OS << "?"; else OS << vni->def; + if (vni->hasPHIKill()) + OS << "-phikill"; + if (vni->hasRedefByEC()) + OS << "-ec"; } } } diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index 956d21c..4c054f5 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -497,11 +497,6 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N) { /// candidate for LICM. e.g. If the instruction is a call, then it's obviously /// not safe to hoist it. bool MachineLICM::IsLICMCandidate(MachineInstr &I) { - // It is not profitable to hoist implicitdefs. FIXME: Why not? what if they - // are an argument to some other otherwise-hoistable instruction? - if (I.isImplicitDef()) - return false; - // Check if it's safe to move the instruction. bool DontMoveAcrossStore = true; if (!I.isSafeToMove(TII, AA, DontMoveAcrossStore)) @@ -717,7 +712,9 @@ MachineLICM::LookForDuplicate(const MachineInstr *MI, bool MachineLICM::EliminateCSE(MachineInstr *MI, DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator &CI) { - if (CI == CSEMap.end()) + // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate + // the undef property onto uses. + if (CI == CSEMap.end() || MI->isImplicitDef()) return false; if (const MachineInstr *Dup = LookForDuplicate(MI, CI->second)) { diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 25284d6..15778b4 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -563,3 +563,26 @@ unsigned MachineModuleInfo::getPersonalityIndex() const { return 0; } +namespace { + /// VariableDebugSorter - Comparison to sort the VariableDbgInfo map + /// by source location, to avoid depending on the arbitrary order that + /// instruction selection visits variables in. + struct VariableDebugSorter { + bool operator()(const MachineModuleInfo::VariableDbgInfoMapTy::value_type &A, + const MachineModuleInfo::VariableDbgInfoMapTy::value_type &B) + const { + if (A.second.second.getLine() != B.second.second.getLine()) + return A.second.second.getLine() < B.second.second.getLine(); + if (A.second.second.getCol() != B.second.second.getCol()) + return A.second.second.getCol() < B.second.second.getCol(); + return false; + } + }; +} + +MachineModuleInfo::VariableDbgInfoMapTy & +MachineModuleInfo::getVariableDbgInfo() { + std::stable_sort(VariableDbgInfo.begin(), VariableDbgInfo.end(), + VariableDebugSorter()); + return VariableDbgInfo; +} diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp index ca4c477..2e31908 100644 --- a/lib/CodeGen/ProcessImplicitDefs.cpp +++ b/lib/CodeGen/ProcessImplicitDefs.cpp @@ -41,21 +41,51 @@ void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, - unsigned Reg, unsigned OpIdx, - const TargetInstrInfo *tii_) { +bool +ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, + unsigned Reg, unsigned OpIdx, + const TargetInstrInfo *tii_, + SmallSet<unsigned, 8> &ImpDefRegs) { unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg && DstSubReg == 0) + Reg == SrcReg && + (DstSubReg == 0 || ImpDefRegs.count(DstReg))) return true; switch(OpIdx) { - case 1: return MI->isCopy() && MI->getOperand(0).getSubReg() == 0; - case 2: return MI->isSubregToReg() && MI->getOperand(0).getSubReg() == 0; - default: return false; + case 1: + return MI->isCopy() && (MI->getOperand(0).getSubReg() == 0 || + ImpDefRegs.count(MI->getOperand(0).getReg())); + case 2: + return MI->isSubregToReg() && (MI->getOperand(0).getSubReg() == 0 || + ImpDefRegs.count(MI->getOperand(0).getReg())); + default: return false; } } +static bool isUndefCopy(MachineInstr *MI, unsigned Reg, + const TargetInstrInfo *tii_, + SmallSet<unsigned, 8> &ImpDefRegs) { + if (MI->isCopy()) { + MachineOperand &MO0 = MI->getOperand(0); + MachineOperand &MO1 = MI->getOperand(1); + if (MO1.getReg() != Reg) + return false; + if (!MO0.getSubReg() || ImpDefRegs.count(MO0.getReg())) + return true; + return false; + } + + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg)) { + if (Reg != SrcReg) + return false; + if (DstSubReg == 0 || ImpDefRegs.count(DstReg)) + return true; + } + return false; +} + /// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure /// there is one implicit_def for each use. Add isUndef marker to /// implicit_def defs and their uses. @@ -104,7 +134,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { // Eliminate %reg1032:sub<def> = COPY undef. if (MI->isCopy() && MI->getOperand(0).getSubReg()) { MachineOperand &MO = MI->getOperand(1); - if (ImpDefRegs.count(MO.getReg())) { + if (MO.isUndef() || ImpDefRegs.count(MO.getReg())) { if (MO.isKill()) { LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); vi.removeKill(MI); @@ -126,7 +156,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { if (!ImpDefRegs.count(Reg)) continue; // Use is a copy, just turn it into an implicit_def. - if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) { + if (CanTurnIntoImplicitDef(MI, Reg, i, tii_, ImpDefRegs)) { bool isKill = MO.isKill(); MI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) @@ -223,11 +253,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { MachineInstr *RMI = RUses[i]; // Turn a copy use into an implicit_def. - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if ((RMI->isCopy() && RMI->getOperand(1).getReg() == Reg && - RMI->getOperand(0).getSubReg() == 0) || - (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg && DstSubReg == 0)) { + if (isUndefCopy(RMI, Reg, tii_, ImpDefRegs)) { RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); bool isKill = false; diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 3f7e4a5..decaa76 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -135,7 +135,7 @@ unsigned FastISel::getRegForValue(const Value *V) { !FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(V)))) return FuncInfo.InitializeRegForValue(V); - MachineBasicBlock::iterator SaveInsertPt = enterLocalValueArea(); + SavePoint SaveInsertPt = enterLocalValueArea(); // Materialize the value in a register. Emit any instructions in the // local value area. @@ -286,18 +286,22 @@ void FastISel::recomputeInsertPt() { ++FuncInfo.InsertPt; } -MachineBasicBlock::iterator FastISel::enterLocalValueArea() { +FastISel::SavePoint FastISel::enterLocalValueArea() { MachineBasicBlock::iterator OldInsertPt = FuncInfo.InsertPt; + DebugLoc OldDL = DL; recomputeInsertPt(); - return OldInsertPt; + DL = DebugLoc(); + SavePoint SP = { OldInsertPt, OldDL }; + return SP; } -void FastISel::leaveLocalValueArea(MachineBasicBlock::iterator OldInsertPt) { +void FastISel::leaveLocalValueArea(SavePoint OldInsertPt) { if (FuncInfo.InsertPt != FuncInfo.MBB->begin()) LastLocalValue = llvm::prior(FuncInfo.InsertPt); // Restore the previous insert position. - FuncInfo.InsertPt = OldInsertPt; + FuncInfo.InsertPt = OldInsertPt.InsertPt; + DL = OldInsertPt.DL; } /// SelectBinaryOp - Select and emit code for a binary operator instruction, @@ -779,39 +783,8 @@ FastISel::SelectFNeg(const User *I) { } bool -FastISel::SelectLoad(const User *I) { - LoadInst *LI = const_cast<LoadInst *>(cast<LoadInst>(I)); - - // For a load from an alloca, make a limited effort to find the value - // already available in a register, avoiding redundant loads. - if (!LI->isVolatile() && isa<AllocaInst>(LI->getPointerOperand())) { - BasicBlock::iterator ScanFrom = LI; - if (const Value *V = FindAvailableLoadedValue(LI->getPointerOperand(), - LI->getParent(), ScanFrom)) { - if (!V->use_empty() && - (!isa<Instruction>(V) || - cast<Instruction>(V)->getParent() == LI->getParent() || - (isa<AllocaInst>(V) && - FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(V)))) && - (!isa<Argument>(V) || - LI->getParent() == &LI->getParent()->getParent()->getEntryBlock())) { - unsigned ResultReg = getRegForValue(V); - if (ResultReg != 0) { - UpdateValueMap(I, ResultReg); - return true; - } - } - } - } - - return false; -} - -bool FastISel::SelectOperator(const User *I, unsigned Opcode) { switch (Opcode) { - case Instruction::Load: - return SelectLoad(I); case Instruction::Add: return SelectBinaryOp(I, ISD::ADD); case Instruction::FAdd: diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index d323c16..458e865 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -820,7 +820,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) { unsigned InReg = It->second; RegsForValue RFV(*DAG.getContext(), TLI, InReg, V->getType()); SDValue Chain = DAG.getEntryNode(); - return N = RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL); + return N = RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain,NULL); } // Otherwise create a new SDValue and remember it. @@ -3955,7 +3955,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { if (AA->alias(I.getArgOperand(0), Size, I.getArgOperand(1), Size) == AliasAnalysis::NoAlias) { DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, isVol, - false, I.getArgOperand(0), 0, I.getArgOperand(1), 0)); + false, I.getArgOperand(0), 0, + I.getArgOperand(1), 0)); return 0; } @@ -5522,10 +5523,12 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { break; } - if (OpInfo.ConstraintType == TargetLowering::C_Other) { - assert(!OpInfo.isIndirect && - "Don't know how to handle indirect other inputs yet!"); + // Treat indirect 'X' constraint as memory. + if (OpInfo.ConstraintType == TargetLowering::C_Other && + OpInfo.isIndirect) + OpInfo.ConstraintType = TargetLowering::C_Memory; + if (OpInfo.ConstraintType == TargetLowering::C_Other) { std::vector<SDValue> Ops; TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode[0], Ops, DAG); |