diff options
author | dim <dim@FreeBSD.org> | 2011-02-26 22:03:50 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-26 22:03:50 +0000 |
commit | c80ac9d286b8fcc6d1ee5d76048134cf80aa9edc (patch) | |
tree | ddf53b8bd9235bcb0b8aae16c5e22310dcdad665 /lib/CodeGen | |
parent | cbb70ce070d220642b038ea101d9c0f9fbf860d6 (diff) | |
download | FreeBSD-src-c80ac9d286b8fcc6d1ee5d76048134cf80aa9edc.zip FreeBSD-src-c80ac9d286b8fcc6d1ee5d76048134cf80aa9edc.tar.gz |
Vendor import of llvm trunk r126547:
http://llvm.org/svn/llvm-project/llvm/trunk@126547
Diffstat (limited to 'lib/CodeGen')
24 files changed, 590 insertions, 264 deletions
diff --git a/lib/CodeGen/AllocationOrder.h b/lib/CodeGen/AllocationOrder.h index 3db4b69..61fd8f8 100644 --- a/lib/CodeGen/AllocationOrder.h +++ b/lib/CodeGen/AllocationOrder.h @@ -47,6 +47,8 @@ public: /// rewind - Start over from the beginning. void rewind() { Pos = 0; } + /// isHint - Return true if PhysReg is a preferred register. + bool isHint(unsigned PhysReg) const { return PhysReg == Hint; } }; } // end namespace llvm diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 43e8990..9cb882e 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -764,7 +764,7 @@ bool AsmPrinter::doFinalization(Module &M) { continue; MCSymbol *Name = Mang->getSymbol(&F); - EmitVisibility(Name, V); + EmitVisibility(Name, V, false); } // Finalize debug and EH information. @@ -1820,13 +1820,17 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { } } -void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility) const { +void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility, + bool IsDefinition) const { MCSymbolAttr Attr = MCSA_Invalid; switch (Visibility) { default: break; case GlobalValue::HiddenVisibility: - Attr = MAI->getHiddenVisibilityAttr(); + if (IsDefinition) + Attr = MAI->getHiddenVisibilityAttr(); + else + Attr = MAI->getHiddenDeclarationVisibilityAttr(); break; case GlobalValue::ProtectedVisibility: Attr = MAI->getProtectedVisibilityAttr(); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 5106d57..780fa40 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -31,6 +31,7 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Analysis/DebugInfo.h" +#include "llvm/Analysis/DIBuilder.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -644,12 +645,12 @@ void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die, for (unsigned i = 0, N = DV->getNumAddrElements(); i < N; ++i) { uint64_t Element = DV->getAddrElement(i); - if (Element == DIFactory::OpPlus) { + if (Element == DIBuilder::OpPlus) { addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i)); - } else if (Element == DIFactory::OpDeref) { + } else if (Element == DIBuilder::OpDeref) { addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); - } else llvm_unreachable("unknown DIFactory Opcode"); + } else llvm_unreachable("unknown DIBuilder Opcode"); } // Now attach the location information to the DIE. @@ -1894,7 +1895,7 @@ void DwarfDebug::constructCompileUnit(const MDNode *N) { DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string, DIUnit.getProducer()); - addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1, + addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2, DIUnit.getLanguage()); addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN); // Use DW_AT_entry_pc instead of DW_AT_low_pc/DW_AT_high_pc pair. This diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index cb81aa3..78a8743 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -501,10 +501,11 @@ static bool ProfitableToMerge(MachineBasicBlock *MBB1, MachineBasicBlock *SuccBB, MachineBasicBlock *PredBB) { CommonTailLen = ComputeCommonTailLength(MBB1, MBB2, I1, I2); - MachineFunction *MF = MBB1->getParent(); - if (CommonTailLen == 0) return false; + DEBUG(dbgs() << "Common tail length of BB#" << MBB1->getNumber() + << " and BB#" << MBB2->getNumber() << " is " << CommonTailLen + << '\n'); // It's almost always profitable to merge any number of non-terminator // instructions with the block that falls through into the common successor. @@ -541,6 +542,7 @@ static bool ProfitableToMerge(MachineBasicBlock *MBB1, // we don't have to split a block. At worst we will be introducing 1 new // branch instruction, which is likely to be smaller than the 2 // instructions that would be deleted in the merge. + MachineFunction *MF = MBB1->getParent(); if (EffectiveTailLen >= 2 && MF->getFunction()->hasFnAttr(Attribute::OptimizeForSize) && (I1 == MBB1->begin() || I2 == MBB2->begin())) diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index a1bd972..38e6c85 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -102,8 +102,7 @@ Spiller *createInlineSpiller(MachineFunctionPass &pass, } } -/// reMaterializeFor - Attempt to rematerialize edit_->getReg() before MI instead of -/// reloading it. +/// reMaterializeFor - Attempt to rematerialize before MI instead of reloading. bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) { SlotIndex UseIdx = lis_.getInstructionIndex(MI).getUseIndex(); VNInfo *OrigVNI = edit_->getParent().getVNInfoAt(UseIdx); @@ -346,7 +345,8 @@ void InlineSpiller::spill(LiveRangeEdit &edit) { && "Trying to spill a stack slot."); DEBUG(dbgs() << "Inline spilling " << mri_.getRegClass(edit.getReg())->getName() - << ':' << edit.getParent() << "\n"); + << ':' << edit.getParent() << "\nFrom original " + << PrintReg(vrm_.getOriginal(edit.getReg())) << '\n'); assert(edit.getParent().isSpillable() && "Attempting to spill already spilled value."); @@ -357,12 +357,20 @@ void InlineSpiller::spill(LiveRangeEdit &edit) { return; rc_ = mri_.getRegClass(edit.getReg()); - stackSlot_ = vrm_.assignVirt2StackSlot(edit_->getReg()); + + // Share a stack slot among all descendants of Orig. + unsigned Orig = vrm_.getOriginal(edit.getReg()); + stackSlot_ = vrm_.getStackSlot(Orig); + if (stackSlot_ == VirtRegMap::NO_STACK_SLOT) + stackSlot_ = vrm_.assignVirt2StackSlot(Orig); + + if (Orig != edit.getReg()) + vrm_.assignVirt2StackSlot(edit.getReg(), stackSlot_); // Update LiveStacks now that we are committed to spilling. LiveInterval &stacklvr = lss_.getOrCreateInterval(stackSlot_, rc_); - assert(stacklvr.empty() && "Just created stack slot not empty"); - stacklvr.getNextValue(SlotIndex(), 0, lss_.getVNInfoAllocator()); + if (!stacklvr.hasAtLeastOneValue()) + stacklvr.getNextValue(SlotIndex(), 0, lss_.getVNInfoAllocator()); stacklvr.MergeRangesInAsValue(edit_->getParent(), stacklvr.getValNumInfo(0)); // Iterate over instructions using register. diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index ad1c537..7871ba9 100644 --- a/lib/CodeGen/LowerSubregs.cpp +++ b/lib/CodeGen/LowerSubregs.cpp @@ -37,7 +37,7 @@ namespace { public: static char ID; // Pass identification, replacement for typeid LowerSubregsInstructionPass() : MachineFunctionPass(ID) {} - + const char *getPassName() const { return "Subregister lowering instruction pass"; } @@ -64,8 +64,8 @@ namespace { char LowerSubregsInstructionPass::ID = 0; } -FunctionPass *llvm::createLowerSubregsPass() { - return new LowerSubregsInstructionPass(); +FunctionPass *llvm::createLowerSubregsPass() { + return new LowerSubregsInstructionPass(); } /// TransferDeadFlag - MI is a pseudo-instruction with DstReg dead, @@ -192,9 +192,9 @@ bool LowerSubregsInstructionPass::LowerCopy(MachineInstr *MI) { /// copies. /// bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { - DEBUG(dbgs() << "Machine Function\n" + DEBUG(dbgs() << "Machine Function\n" << "********** LOWERING SUBREG INSTRS **********\n" - << "********** Function: " + << "********** Function: " << MF.getFunction()->getName() << '\n'); TRI = MF.getTarget().getRegisterInfo(); TII = MF.getTarget().getInstrInfo(); diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 8553240..d81e4a1 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -396,8 +396,7 @@ void MachineFunction::viewCFGOnly() const /// addLiveIn - Add the specified physical register as a live-in value and /// create a corresponding virtual register for it. unsigned MachineFunction::addLiveIn(unsigned PReg, - const TargetRegisterClass *RC, - DebugLoc DL) { + const TargetRegisterClass *RC) { MachineRegisterInfo &MRI = getRegInfo(); unsigned VReg = MRI.getLiveInVirtReg(PReg); if (VReg) { @@ -406,7 +405,6 @@ unsigned MachineFunction::addLiveIn(unsigned PReg, } VReg = MRI.createVirtualRegister(RC); MRI.addLiveIn(PReg, VReg); - MRI.addLiveInLoc(VReg, DL); return VReg; } @@ -646,6 +644,10 @@ MachineConstantPool::~MachineConstantPool() { for (unsigned i = 0, e = Constants.size(); i != e; ++i) if (Constants[i].isMachineConstantPoolEntry()) delete Constants[i].Val.MachineCPVal; + for (DenseSet<MachineConstantPoolValue*>::iterator I = + MachineCPVsSharingEntries.begin(), E = MachineCPVsSharingEntries.end(); + I != E; ++I) + delete *I; } /// CanShareConstantPoolEntry - Test whether the given two constants @@ -723,8 +725,10 @@ unsigned MachineConstantPool::getConstantPoolIndex(MachineConstantPoolValue *V, // // FIXME, this could be made much more efficient for large constant pools. int Idx = V->getExistingMachineCPValue(this, Alignment); - if (Idx != -1) + if (Idx != -1) { + MachineCPVsSharingEntries.insert(V); return (unsigned)Idx; + } Constants.push_back(MachineConstantPoolEntry(V, Alignment)); return Constants.size()-1; diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp index b3fb337..7244d5f 100644 --- a/lib/CodeGen/MachineRegisterInfo.cpp +++ b/lib/CodeGen/MachineRegisterInfo.cpp @@ -210,15 +210,8 @@ MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB, LiveIns.erase(LiveIns.begin() + i); --i; --e; } else { - DebugLoc DL; - // If there is a location for this live in then use it. - DenseMap<unsigned, DebugLoc>::iterator DLI = - LiveInLocs.find(LiveIns[i].second); - if (DLI != LiveInLocs.end()) - DL = DLI->second; - // Emit a copy. - BuildMI(*EntryMBB, EntryMBB->begin(), DL, + BuildMI(*EntryMBB, EntryMBB->begin(), DebugLoc(), TII.get(TargetOpcode::COPY), LiveIns[i].second) .addReg(LiveIns[i].first); diff --git a/lib/CodeGen/RegAllocBase.h b/lib/CodeGen/RegAllocBase.h index 8c7e5f5..5af0ce7 100644 --- a/lib/CodeGen/RegAllocBase.h +++ b/lib/CodeGen/RegAllocBase.h @@ -39,7 +39,6 @@ #include "llvm/ADT/OwningPtr.h" #include "LiveIntervalUnion.h" -#include <queue> namespace llvm { @@ -58,8 +57,8 @@ class LiveVirtRegQueue; /// be extended to add interesting heuristics. /// /// Register allocators must override the selectOrSplit() method to implement -/// live range splitting. They may also override getPriority() which otherwise -/// defaults to the spill weight computed by CalculateSpillWeights. +/// live range splitting. They must also override enqueue/dequeue to provide an +/// assignment order. class RegAllocBase { LiveIntervalUnion::Allocator UnionAllocator; protected: @@ -120,9 +119,11 @@ protected: // Get a temporary reference to a Spiller instance. virtual Spiller &spiller() = 0; - // getPriority - Calculate the allocation priority for VirtReg. - // Virtual registers with higher priorities are allocated first. - virtual float getPriority(LiveInterval *LI) = 0; + /// enqueue - Add VirtReg to the priority queue of unassigned registers. + virtual void enqueue(LiveInterval *LI) = 0; + + /// dequeue - Return the next unassigned register, or NULL. + virtual LiveInterval *dequeue() = 0; // A RegAlloc pass should override this to provide the allocation heuristics. // Each call must guarantee forward progess by returning an available PhysReg @@ -170,7 +171,7 @@ public: static bool VerifyEnabled; private: - void seedLiveVirtRegs(std::priority_queue<std::pair<float, unsigned> >&); + void seedLiveRegs(); void spillReg(LiveInterval &VirtReg, unsigned PhysReg, SmallVectorImpl<LiveInterval*> &SplitVRegs); diff --git a/lib/CodeGen/RegAllocBasic.cpp b/lib/CodeGen/RegAllocBasic.cpp index 045c8db..6923908 100644 --- a/lib/CodeGen/RegAllocBasic.cpp +++ b/lib/CodeGen/RegAllocBasic.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/Timer.h" #include <cstdlib> +#include <queue> using namespace llvm; @@ -65,6 +66,14 @@ const char *RegAllocBase::TimerGroupName = "Register Allocation"; bool RegAllocBase::VerifyEnabled = false; namespace { + struct CompSpillWeight { + bool operator()(LiveInterval *A, LiveInterval *B) const { + return A->weight < B->weight; + } + }; +} + +namespace { /// RABasic provides a minimal implementation of the basic register allocation /// algorithm. It prioritizes live virtual registers by spill weight and spills /// whenever a register is unavailable. This is not practical in production but @@ -82,7 +91,8 @@ class RABasic : public MachineFunctionPass, public RegAllocBase // state std::auto_ptr<Spiller> SpillerInstance; - + std::priority_queue<LiveInterval*, std::vector<LiveInterval*>, + CompSpillWeight> Queue; public: RABasic(); @@ -100,6 +110,18 @@ public: virtual float getPriority(LiveInterval *LI) { return LI->weight; } + virtual void enqueue(LiveInterval *LI) { + Queue.push(LI); + } + + virtual LiveInterval *dequeue() { + if (Queue.empty()) + return 0; + LiveInterval *LI = Queue.top(); + Queue.pop(); + return LI; + } + virtual unsigned selectOrSplit(LiveInterval &VirtReg, SmallVectorImpl<LiveInterval*> &SplitVRegs); @@ -227,18 +249,17 @@ void RegAllocBase::releaseMemory() { PhysReg2LiveUnion.clear(); } -// Visit all the live virtual registers. If they are already assigned to a -// physical register, unify them with the corresponding LiveIntervalUnion, -// otherwise push them on the priority queue for later assignment. -void RegAllocBase:: -seedLiveVirtRegs(std::priority_queue<std::pair<float, unsigned> > &VirtRegQ) { +// Visit all the live registers. If they are already assigned to a physical +// register, unify them with the corresponding LiveIntervalUnion, otherwise push +// them on the priority queue for later assignment. +void RegAllocBase::seedLiveRegs() { for (LiveIntervals::iterator I = LIS->begin(), E = LIS->end(); I != E; ++I) { unsigned RegNum = I->first; LiveInterval &VirtReg = *I->second; if (TargetRegisterInfo::isPhysicalRegister(RegNum)) PhysReg2LiveUnion[RegNum].unify(VirtReg); else - VirtRegQ.push(std::make_pair(getPriority(&VirtReg), RegNum)); + enqueue(&VirtReg); } } @@ -263,38 +284,31 @@ void RegAllocBase::unassign(LiveInterval &VirtReg, unsigned PhysReg) { // Top-level driver to manage the queue of unassigned VirtRegs and call the // selectOrSplit implementation. void RegAllocBase::allocatePhysRegs() { - - // Push each vreg onto a queue or "precolor" by adding it to a physreg union. - std::priority_queue<std::pair<float, unsigned> > VirtRegQ; - seedLiveVirtRegs(VirtRegQ); + seedLiveRegs(); // Continue assigning vregs one at a time to available physical registers. - while (!VirtRegQ.empty()) { - // Pop the highest priority vreg. - LiveInterval &VirtReg = LIS->getInterval(VirtRegQ.top().second); - VirtRegQ.pop(); - + while (LiveInterval *VirtReg = dequeue()) { // selectOrSplit requests the allocator to return an available physical // register if possible and populate a list of new live intervals that // result from splitting. - DEBUG(dbgs() << "\nselectOrSplit " << MRI->getRegClass(VirtReg.reg)->getName() - << ':' << VirtReg << '\n'); + DEBUG(dbgs() << "\nselectOrSplit " + << MRI->getRegClass(VirtReg->reg)->getName() + << ':' << *VirtReg << '\n'); typedef SmallVector<LiveInterval*, 4> VirtRegVec; VirtRegVec SplitVRegs; - unsigned AvailablePhysReg = selectOrSplit(VirtReg, SplitVRegs); + unsigned AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs); if (AvailablePhysReg) - assign(VirtReg, AvailablePhysReg); + assign(*VirtReg, AvailablePhysReg); for (VirtRegVec::iterator I = SplitVRegs.begin(), E = SplitVRegs.end(); I != E; ++I) { - LiveInterval* SplitVirtReg = *I; + LiveInterval *SplitVirtReg = *I; if (SplitVirtReg->empty()) continue; DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n"); assert(TargetRegisterInfo::isVirtualRegister(SplitVirtReg->reg) && "expect split value in virtual register"); - VirtRegQ.push(std::make_pair(getPriority(SplitVirtReg), - SplitVirtReg->reg)); + enqueue(SplitVirtReg); ++NumNewQueued; } } diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index c1372cd..406485a 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -43,6 +43,8 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Timer.h" +#include <queue> + using namespace llvm; STATISTIC(NumGlobalSplits, "Number of split global live ranges"); @@ -71,6 +73,8 @@ class RAGreedy : public MachineFunctionPass, public RegAllocBase { // state std::auto_ptr<Spiller> SpillerInstance; std::auto_ptr<SplitAnalysis> SA; + std::priority_queue<std::pair<unsigned, unsigned> > Queue; + IndexedMap<unsigned, VirtReg2IndexFunctor> Generation; // splitting state. @@ -91,13 +95,10 @@ public: /// RAGreedy analysis usage. virtual void getAnalysisUsage(AnalysisUsage &AU) const; - virtual void releaseMemory(); - virtual Spiller &spiller() { return *SpillerInstance; } - - virtual float getPriority(LiveInterval *LI); - + virtual void enqueue(LiveInterval *LI); + virtual LiveInterval *dequeue(); virtual unsigned selectOrSplit(LiveInterval&, SmallVectorImpl<LiveInterval*>&); @@ -119,9 +120,12 @@ private: SlotIndex getPrevMappedIndex(const MachineInstr*); void calcPrevSlots(); unsigned nextSplitPoint(unsigned); + bool canEvictInterference(LiveInterval&, unsigned, unsigned, float&); - unsigned tryReassignOrEvict(LiveInterval&, AllocationOrder&, + unsigned tryReassign(LiveInterval&, AllocationOrder&, SmallVectorImpl<LiveInterval*>&); + unsigned tryEvict(LiveInterval&, AllocationOrder&, + SmallVectorImpl<LiveInterval*>&); unsigned tryRegionSplit(LiveInterval&, AllocationOrder&, SmallVectorImpl<LiveInterval*>&); unsigned tryLocalSplit(LiveInterval&, AllocationOrder&, @@ -183,25 +187,42 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const { void RAGreedy::releaseMemory() { SpillerInstance.reset(0); + Generation.clear(); RegAllocBase::releaseMemory(); } -float RAGreedy::getPriority(LiveInterval *LI) { - float Priority = LI->weight; - - // Prioritize hinted registers so they are allocated first. - std::pair<unsigned, unsigned> Hint; - if (Hint.first || Hint.second) { - // The hint can be target specific, a virtual register, or a physreg. - Priority *= 2; - - // Prefer physreg hints above anything else. - if (Hint.first == 0 && TargetRegisterInfo::isPhysicalRegister(Hint.second)) - Priority *= 2; - } - return Priority; +void RAGreedy::enqueue(LiveInterval *LI) { + // Prioritize live ranges by size, assigning larger ranges first. + // The queue holds (size, reg) pairs. + const unsigned Size = LI->getSize(); + const unsigned Reg = LI->reg; + assert(TargetRegisterInfo::isVirtualRegister(Reg) && + "Can only enqueue virtual registers"); + const unsigned Hint = VRM->getRegAllocPref(Reg); + unsigned Prio; + + Generation.grow(Reg); + if (++Generation[Reg] == 1) + // 1st generation ranges are handled first, long -> short. + Prio = (1u << 31) + Size; + else + // Repeat offenders are handled second, short -> long + Prio = (1u << 30) - Size; + + // Boost ranges that have a physical register hint. + if (TargetRegisterInfo::isPhysicalRegister(Hint)) + Prio |= (1u << 30); + + Queue.push(std::make_pair(Prio, Reg)); } +LiveInterval *RAGreedy::dequeue() { + if (Queue.empty()) + return 0; + LiveInterval *LI = &LIS->getInterval(Queue.top().second); + Queue.pop(); + return LI; +} //===----------------------------------------------------------------------===// // Register Reassignment @@ -230,8 +251,7 @@ LiveInterval *RAGreedy::getSingleInterference(LiveInterval &VirtReg, if (Q.checkInterference()) { if (Interference) return 0; - Q.collectInterferingVRegs(1); - if (!Q.seenAllInterferences()) + if (Q.collectInterferingVRegs(2) > 1) return 0; Interference = Q.interferingVRegs().front(); } @@ -276,21 +296,14 @@ bool RAGreedy::reassignVReg(LiveInterval &InterferingVReg, return false; } -/// tryReassignOrEvict - Try to reassign a single interferences to a different -/// physreg, or evict a single interference with a lower spill weight. +/// tryReassign - Try to reassign a single interference to a different physreg. /// @param VirtReg Currently unassigned virtual register. /// @param Order Physregs to try. /// @return Physreg to assign VirtReg, or 0. -unsigned RAGreedy::tryReassignOrEvict(LiveInterval &VirtReg, - AllocationOrder &Order, - SmallVectorImpl<LiveInterval*> &NewVRegs){ +unsigned RAGreedy::tryReassign(LiveInterval &VirtReg, AllocationOrder &Order, + SmallVectorImpl<LiveInterval*> &NewVRegs){ NamedRegionTimer T("Reassign", TimerGroupName, TimePassesIsEnabled); - // Keep track of the lightest single interference seen so far. - float BestWeight = VirtReg.weight; - LiveInterval *BestVirt = 0; - unsigned BestPhys = 0; - Order.rewind(); while (unsigned PhysReg = Order.next()) { LiveInterval *InterferingVReg = getSingleInterference(VirtReg, PhysReg); @@ -300,25 +313,92 @@ unsigned RAGreedy::tryReassignOrEvict(LiveInterval &VirtReg, continue; if (reassignVReg(*InterferingVReg, PhysReg)) return PhysReg; + } + return 0; +} + + +//===----------------------------------------------------------------------===// +// Interference eviction +//===----------------------------------------------------------------------===// + +/// canEvict - Return true if all interferences between VirtReg and PhysReg can +/// be evicted. Set maxWeight to the maximal spill weight of an interference. +bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, unsigned PhysReg, + unsigned Size, float &MaxWeight) { + float Weight = 0; + for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) { + LiveIntervalUnion::Query &Q = query(VirtReg, *AliasI); + // If there is 10 or more interferences, chances are one is smaller. + if (Q.collectInterferingVRegs(10) >= 10) + return false; - // Cannot reassign, is this an eviction candidate? - if (InterferingVReg->weight < BestWeight) { - BestVirt = InterferingVReg; - BestPhys = PhysReg; - BestWeight = InterferingVReg->weight; + // CHeck if any interfering live range is shorter than VirtReg. + for (unsigned i = 0, e = Q.interferingVRegs().size(); i != e; ++i) { + LiveInterval *Intf = Q.interferingVRegs()[i]; + if (TargetRegisterInfo::isPhysicalRegister(Intf->reg)) + return false; + if (Intf->getSize() <= Size) + return false; + Weight = std::max(Weight, Intf->weight); } } + MaxWeight = Weight; + return true; +} + +/// tryEvict - Try to evict all interferences for a physreg. +/// @param VirtReg Currently unassigned virtual register. +/// @param Order Physregs to try. +/// @return Physreg to assign VirtReg, or 0. +unsigned RAGreedy::tryEvict(LiveInterval &VirtReg, + AllocationOrder &Order, + SmallVectorImpl<LiveInterval*> &NewVRegs){ + NamedRegionTimer T("Evict", TimerGroupName, TimePassesIsEnabled); + + // We can only evict interference if all interfering registers are virtual and + // longer than VirtReg. + const unsigned Size = VirtReg.getSize(); + + // Keep track of the lightest single interference seen so far. + float BestWeight = 0; + unsigned BestPhys = 0; - // Nothing reassigned, can we evict a lighter single interference? - if (BestVirt) { - DEBUG(dbgs() << "evicting lighter " << *BestVirt << '\n'); - unassign(*BestVirt, VRM->getPhys(BestVirt->reg)); - ++NumEvicted; - NewVRegs.push_back(BestVirt); - return BestPhys; + Order.rewind(); + while (unsigned PhysReg = Order.next()) { + float Weight = 0; + if (!canEvictInterference(VirtReg, PhysReg, Size, Weight)) + continue; + + // This is an eviction candidate. + DEBUG(dbgs() << "max " << PrintReg(PhysReg, TRI) << " interference = " + << Weight << '\n'); + if (BestPhys && Weight >= BestWeight) + continue; + + // Best so far. + BestPhys = PhysReg; + BestWeight = Weight; + // Stop if the hint can be used. + if (Order.isHint(PhysReg)) + break; } - return 0; + if (!BestPhys) + return 0; + + DEBUG(dbgs() << "evicting " << PrintReg(BestPhys, TRI) << " interference\n"); + for (const unsigned *AliasI = TRI->getOverlaps(BestPhys); *AliasI; ++AliasI) { + LiveIntervalUnion::Query &Q = query(VirtReg, *AliasI); + assert(Q.seenAllInterferences() && "Didn't check all interfererences."); + for (unsigned i = 0, e = Q.interferingVRegs().size(); i != e; ++i) { + LiveInterval *Intf = Q.interferingVRegs()[i]; + unassign(*Intf, VRM->getPhys(Intf->reg)); + ++NumEvicted; + NewVRegs.push_back(Intf); + } + } + return BestPhys; } @@ -426,8 +506,13 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) { if (!IntI.valid()) break; // Not live in, but before the first use. - if (IntI.start() < BI.FirstUse) + if (IntI.start() < BI.FirstUse) { BC.Entry = SpillPlacement::PrefSpill; + // If the block contains a kill from an earlier split, never split + // again in the same block. + if (!BI.LiveThrough && !SA->isOriginalEndpoint(BI.Kill)) + BC.Entry = SpillPlacement::MustSpill; + } } // Does interference overlap the uses in the entry segment @@ -458,8 +543,12 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) { IntI.advanceTo(BI.LastUse); if (!IntI.valid()) break; - if (IntI.start() < Stop) + if (IntI.start() < Stop) { BC.Exit = SpillPlacement::PrefSpill; + // Avoid splitting twice in the same block. + if (!BI.LiveThrough && !SA->isOriginalEndpoint(BI.Def)) + BC.Exit = SpillPlacement::MustSpill; + } } } } @@ -1221,12 +1310,22 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, return PhysReg; } - // Try to reassign interferences. - if (unsigned PhysReg = tryReassignOrEvict(VirtReg, Order, NewVRegs)) + if (unsigned PhysReg = tryReassign(VirtReg, Order, NewVRegs)) + return PhysReg; + + if (unsigned PhysReg = tryEvict(VirtReg, Order, NewVRegs)) return PhysReg; assert(NewVRegs.empty() && "Cannot append to existing NewVRegs"); + // The first time we see a live range, don't try to split or spill. + // Wait until the second time, when all smaller ranges have been allocated. + // This gives a better picture of the interference to split around. + if (Generation[VirtReg.reg] == 1) { + NewVRegs.push_back(&VirtReg); + return 0; + } + // Try splitting VirtReg or interferences. unsigned PhysReg = trySplit(VirtReg, Order, NewVRegs); if (PhysReg || !NewVRegs.empty()) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9035602..9cc70a3 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -279,8 +279,8 @@ namespace { /// getShiftAmountTy - Returns a type large enough to hold any valid /// shift amount - before type legalization these can be huge. - EVT getShiftAmountTy() { - return LegalTypes ? TLI.getShiftAmountTy() : TLI.getPointerTy(); + EVT getShiftAmountTy(EVT LHSTy) { + return LegalTypes ? TLI.getShiftAmountTy(LHSTy) : TLI.getPointerTy(); } /// isTypeLegal - This method returns true if we are running before type @@ -670,7 +670,7 @@ SDValue DAGCombiner::PromoteOperand(SDValue Op, EVT PVT, bool &Replace) { if (LoadSDNode *LD = dyn_cast<LoadSDNode>(Op)) { EVT MemVT = LD->getMemoryVT(); ISD::LoadExtType ExtType = ISD::isNON_EXTLoad(LD) - ? (TLI.isLoadExtLegal(ISD::ZEXTLOAD, MemVT) ? ISD::ZEXTLOAD + ? (TLI.isLoadExtLegal(ISD::ZEXTLOAD, MemVT) ? ISD::ZEXTLOAD : ISD::EXTLOAD) : LD->getExtensionType(); Replace = true; @@ -894,7 +894,7 @@ bool DAGCombiner::PromoteLoad(SDValue Op) { LoadSDNode *LD = cast<LoadSDNode>(N); EVT MemVT = LD->getMemoryVT(); ISD::LoadExtType ExtType = ISD::isNON_EXTLoad(LD) - ? (TLI.isLoadExtLegal(ISD::ZEXTLOAD, MemVT) ? ISD::ZEXTLOAD + ? (TLI.isLoadExtLegal(ISD::ZEXTLOAD, MemVT) ? ISD::ZEXTLOAD : ISD::EXTLOAD) : LD->getExtensionType(); SDValue NewLD = DAG.getExtLoad(ExtType, dl, PVT, @@ -1521,7 +1521,7 @@ SDValue DAGCombiner::visitADDE(SDNode *N) { // Since it may not be valid to emit a fold to zero for vector initializers // check if we can before folding. static SDValue tryFoldToZero(DebugLoc DL, const TargetLowering &TLI, EVT VT, - SelectionDAG &DAG, bool LegalOperations) { + SelectionDAG &DAG, bool LegalOperations) { if (!VT.isVector()) { return DAG.getConstant(0, VT); } else if (!LegalOperations || TLI.isOperationLegal(ISD::BUILD_VECTOR, VT)) { @@ -1647,7 +1647,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) { if (N1C && N1C->getAPIntValue().isPowerOf2()) return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0, DAG.getConstant(N1C->getAPIntValue().logBase2(), - getShiftAmountTy())); + getShiftAmountTy(N0.getValueType()))); // fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c if (N1C && (-N1C->getAPIntValue()).isPowerOf2()) { unsigned Log2Val = (-N1C->getAPIntValue()).logBase2(); @@ -1656,7 +1656,8 @@ SDValue DAGCombiner::visitMUL(SDNode *N) { return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, DAG.getConstant(0, VT), DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0, - DAG.getConstant(Log2Val, getShiftAmountTy()))); + DAG.getConstant(Log2Val, + getShiftAmountTy(N0.getValueType())))); } // (mul (shl X, c1), c2) -> (mul X, c2 << c1) if (N1C && N0.getOpcode() == ISD::SHL && @@ -1753,18 +1754,18 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) { // Splat the sign bit into the register SDValue SGN = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0, DAG.getConstant(VT.getSizeInBits()-1, - getShiftAmountTy())); + getShiftAmountTy(N0.getValueType()))); AddToWorkList(SGN.getNode()); // Add (N0 < 0) ? abs2 - 1 : 0; SDValue SRL = DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, SGN, DAG.getConstant(VT.getSizeInBits() - lg2, - getShiftAmountTy())); + getShiftAmountTy(SGN.getValueType()))); SDValue ADD = DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0, SRL); AddToWorkList(SRL.getNode()); AddToWorkList(ADD.getNode()); // Divide by pow2 SDValue SRA = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, ADD, - DAG.getConstant(lg2, getShiftAmountTy())); + DAG.getConstant(lg2, getShiftAmountTy(ADD.getValueType()))); // If we're dividing by a positive value, we're done. Otherwise, we must // negate the result. @@ -1814,7 +1815,7 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) { if (N1C && N1C->getAPIntValue().isPowerOf2()) return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, DAG.getConstant(N1C->getAPIntValue().logBase2(), - getShiftAmountTy())); + getShiftAmountTy(N0.getValueType()))); // fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2 if (N1.getOpcode() == ISD::SHL) { if (ConstantSDNode *SHC = dyn_cast<ConstantSDNode>(N1.getOperand(0))) { @@ -1955,7 +1956,7 @@ SDValue DAGCombiner::visitMULHS(SDNode *N) { if (N1C && N1C->getAPIntValue() == 1) return DAG.getNode(ISD::SRA, N->getDebugLoc(), N0.getValueType(), N0, DAG.getConstant(N0.getValueType().getSizeInBits() - 1, - getShiftAmountTy())); + getShiftAmountTy(N0.getValueType()))); // fold (mulhs x, undef) -> 0 if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF) return DAG.getConstant(0, VT); @@ -1971,11 +1972,11 @@ SDValue DAGCombiner::visitMULHS(SDNode *N) { N1 = DAG.getNode(ISD::SIGN_EXTEND, DL, NewVT, N1); N1 = DAG.getNode(ISD::MUL, DL, NewVT, N0, N1); N1 = DAG.getNode(ISD::SRL, DL, NewVT, N1, - DAG.getConstant(SimpleSize, getShiftAmountTy())); + DAG.getConstant(SimpleSize, getShiftAmountTy(N1.getValueType()))); return DAG.getNode(ISD::TRUNCATE, DL, VT, N1); } } - + return SDValue(); } @@ -2007,11 +2008,11 @@ SDValue DAGCombiner::visitMULHU(SDNode *N) { N1 = DAG.getNode(ISD::ZERO_EXTEND, DL, NewVT, N1); N1 = DAG.getNode(ISD::MUL, DL, NewVT, N0, N1); N1 = DAG.getNode(ISD::SRL, DL, NewVT, N1, - DAG.getConstant(SimpleSize, getShiftAmountTy())); + DAG.getConstant(SimpleSize, getShiftAmountTy(N1.getValueType()))); return DAG.getNode(ISD::TRUNCATE, DL, VT, N1); } } - + return SDValue(); } @@ -2090,14 +2091,14 @@ SDValue DAGCombiner::visitSMUL_LOHI(SDNode *N) { Lo = DAG.getNode(ISD::MUL, DL, NewVT, Lo, Hi); // Compute the high part as N1. Hi = DAG.getNode(ISD::SRL, DL, NewVT, Lo, - DAG.getConstant(SimpleSize, getShiftAmountTy())); + DAG.getConstant(SimpleSize, getShiftAmountTy(Lo.getValueType()))); Hi = DAG.getNode(ISD::TRUNCATE, DL, VT, Hi); // Compute the low part as N0. Lo = DAG.getNode(ISD::TRUNCATE, DL, VT, Lo); return CombineTo(N, Lo, Hi); } } - + return SDValue(); } @@ -2107,7 +2108,7 @@ SDValue DAGCombiner::visitUMUL_LOHI(SDNode *N) { EVT VT = N->getValueType(0); DebugLoc DL = N->getDebugLoc(); - + // If the type twice as wide is legal, transform the mulhu to a wider multiply // plus a shift. if (VT.isSimple() && !VT.isVector()) { @@ -2120,14 +2121,14 @@ SDValue DAGCombiner::visitUMUL_LOHI(SDNode *N) { Lo = DAG.getNode(ISD::MUL, DL, NewVT, Lo, Hi); // Compute the high part as N1. Hi = DAG.getNode(ISD::SRL, DL, NewVT, Lo, - DAG.getConstant(SimpleSize, getShiftAmountTy())); + DAG.getConstant(SimpleSize, getShiftAmountTy(Lo.getValueType()))); Hi = DAG.getNode(ISD::TRUNCATE, DL, VT, Hi); // Compute the low part as N0. Lo = DAG.getNode(ISD::TRUNCATE, DL, VT, Lo); return CombineTo(N, Lo, Hi); } } - + return SDValue(); } @@ -3004,7 +3005,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { N0.getOpcode() == ISD::SIGN_EXTEND) && N0.getOperand(0).getOpcode() == ISD::SHL && isa<ConstantSDNode>(N0.getOperand(0)->getOperand(1))) { - uint64_t c1 = + uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(0)->getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); EVT InnerShiftVT = N0.getOperand(0).getValueType(); @@ -3133,7 +3134,8 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { TLI.isOperationLegalOrCustom(ISD::TRUNCATE, VT) && TLI.isTruncateFree(VT, TruncVT)) { - SDValue Amt = DAG.getConstant(ShiftAmt, getShiftAmountTy()); + SDValue Amt = DAG.getConstant(ShiftAmt, + getShiftAmountTy(N0.getOperand(0).getValueType())); SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT, N0.getOperand(0), Amt); SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), TruncVT, @@ -3180,7 +3182,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { LargeShiftAmt->getZExtValue()) { SDValue Amt = DAG.getConstant(LargeShiftAmt->getZExtValue() + N1C->getZExtValue(), - getShiftAmountTy()); + getShiftAmountTy(N0.getOperand(0).getOperand(0).getValueType())); SDValue SRA = DAG.getNode(ISD::SRA, N->getDebugLoc(), LargeVT, N0.getOperand(0).getOperand(0), Amt); return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, SRA); @@ -3245,7 +3247,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { if (N1C && N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getOpcode() == ISD::SRL && isa<ConstantSDNode>(N0.getOperand(0)->getOperand(1))) { - uint64_t c1 = + uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(0)->getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); EVT InnerShiftVT = N0.getOperand(0).getValueType(); @@ -3256,7 +3258,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { if (c1 + c2 >= InnerShiftSize) return DAG.getConstant(0, VT); return DAG.getNode(ISD::TRUNCATE, N0->getDebugLoc(), VT, - DAG.getNode(ISD::SRL, N0->getDebugLoc(), InnerShiftVT, + DAG.getNode(ISD::SRL, N0->getDebugLoc(), InnerShiftVT, N0.getOperand(0)->getOperand(0), DAG.getConstant(c1 + c2, ShiftCountVT))); } @@ -3320,7 +3322,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { if (ShAmt) { Op = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT, Op, - DAG.getConstant(ShAmt, getShiftAmountTy())); + DAG.getConstant(ShAmt, getShiftAmountTy(Op.getValueType()))); AddToWorkList(Op.getNode()); } @@ -3685,7 +3687,9 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { } // fold (sext (load x)) -> (sext (truncate (sextload x))) - if (ISD::isNON_EXTLoad(N0.getNode()) && + // None of the supported targets knows how to perform load and sign extend + // in one instruction. We only perform this transformation on scalars. + if (ISD::isNON_EXTLoad(N0.getNode()) && !VT.isVector() && ((!LegalOperations && !cast<LoadSDNode>(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::SEXTLOAD, N0.getValueType()))) { bool DoXform = true; @@ -3887,7 +3891,9 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { } // fold (zext (load x)) -> (zext (truncate (zextload x))) - if (ISD::isNON_EXTLoad(N0.getNode()) && + // None of the supported targets knows how to perform load and vector_zext + // in one instruction. We only perform this transformation on scalar zext. + if (ISD::isNON_EXTLoad(N0.getNode()) && !VT.isVector() && ((!LegalOperations && !cast<LoadSDNode>(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::ZEXTLOAD, N0.getValueType()))) { bool DoXform = true; @@ -4021,11 +4027,11 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { } DebugLoc DL = N->getDebugLoc(); - - // Ensure that the shift amount is wide enough for the shifted value. + + // Ensure that the shift amount is wide enough for the shifted value. if (VT.getSizeInBits() >= 256) ShAmt = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, ShAmt); - + return DAG.getNode(N0.getOpcode(), DL, VT, DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0)), ShAmt); @@ -4094,7 +4100,9 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { } // fold (aext (load x)) -> (aext (truncate (extload x))) - if (ISD::isNON_EXTLoad(N0.getNode()) && + // None of the supported targets knows how to perform load and any_ext + // in one instruction. We only perform this transformation on scalars. + if (ISD::isNON_EXTLoad(N0.getNode()) && !VT.isVector() && ((!LegalOperations && !cast<LoadSDNode>(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) { bool DoXform = true; @@ -4272,12 +4280,12 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { return SDValue(); unsigned EVTBits = ExtVT.getSizeInBits(); - + // Do not generate loads of non-round integer types since these can // be expensive (and would be wrong if the type is not byte sized). if (!ExtVT.isRound()) return SDValue(); - + unsigned ShAmt = 0; if (N0.getOpcode() == ISD::SRL && N0.hasOneUse()) { if (ConstantSDNode *N01 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) { @@ -4292,7 +4300,7 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { // At this point, we must have a load or else we can't do the transform. if (!isa<LoadSDNode>(N0)) return SDValue(); - + // If the shift amount is larger than the input type then we're not // accessing any of the loaded bytes. If the load was a zextload/extload // then the result of the shift+trunc is zero/undef (handled elsewhere). @@ -4313,18 +4321,18 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { N0 = N0.getOperand(0); } } - + // If we haven't found a load, we can't narrow it. Don't transform one with // multiple uses, this would require adding a new load. if (!isa<LoadSDNode>(N0) || !N0.hasOneUse() || // Don't change the width of a volatile load. cast<LoadSDNode>(N0)->isVolatile()) return SDValue(); - + // Verify that we are actually reducing a load width here. if (cast<LoadSDNode>(N0)->getMemoryVT().getSizeInBits() < EVTBits) return SDValue(); - + LoadSDNode *LN0 = cast<LoadSDNode>(N0); EVT PtrType = N0.getOperand(1).getValueType(); @@ -4362,7 +4370,7 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { // Shift the result left, if we've swallowed a left shift. SDValue Result = Load; if (ShLeftAmt != 0) { - EVT ShImmTy = getShiftAmountTy(); + EVT ShImmTy = getShiftAmountTy(Result.getValueType()); if (!isUIntN(ShImmTy.getSizeInBits(), ShLeftAmt)) ShImmTy = VT; Result = DAG.getNode(ISD::SHL, N0.getDebugLoc(), VT, @@ -4504,14 +4512,17 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) { } // See if we can simplify the input to this truncate through knowledge that - // only the low bits are being used. For example "trunc (or (shl x, 8), y)" - // -> trunc y - SDValue Shorter = - GetDemandedBits(N0, APInt::getLowBitsSet(N0.getValueSizeInBits(), - VT.getSizeInBits())); - if (Shorter.getNode()) - return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Shorter); - + // only the low bits are being used. + // For example "trunc (or (shl x, 8), y)" // -> trunc y + // Currenly we only perform this optimization on scalars because vectors + // may have different active low bits. + if (!VT.isVector()) { + SDValue Shorter = + GetDemandedBits(N0, APInt::getLowBitsSet(N0.getValueSizeInBits(), + VT.getSizeInBits())); + if (Shorter.getNode()) + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Shorter); + } // fold (truncate (load x)) -> (smaller load x) // fold (truncate (srl (load x), c)) -> (smaller load (x+c/evtbits)) if (!LegalTypes || TLI.isTypeDesirableForOp(N0.getOpcode(), VT)) { @@ -5975,7 +5986,8 @@ ShrinkLoadReplaceStoreWithStore(const std::pair<unsigned, unsigned> &MaskInfo, // shifted by ByteShift and truncated down to NumBytes. if (ByteShift) IVal = DAG.getNode(ISD::SRL, IVal->getDebugLoc(), IVal.getValueType(), IVal, - DAG.getConstant(ByteShift*8, DC->getShiftAmountTy())); + DAG.getConstant(ByteShift*8, + DC->getShiftAmountTy(IVal.getValueType()))); // Figure out the offset for the store and the alignment of the access. unsigned StOffset; @@ -6390,7 +6402,7 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) { EVT VT = InVec.getValueType(); - // If we can't generate a legal BUILD_VECTOR, exit + // If we can't generate a legal BUILD_VECTOR, exit if (LegalOperations && !TLI.isOperationLegal(ISD::BUILD_VECTOR, VT)) return SDValue(); @@ -7098,7 +7110,8 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, if (N2C && ((N2C->getAPIntValue() & (N2C->getAPIntValue()-1)) == 0)) { unsigned ShCtV = N2C->getAPIntValue().logBase2(); ShCtV = XType.getSizeInBits()-ShCtV-1; - SDValue ShCt = DAG.getConstant(ShCtV, getShiftAmountTy()); + SDValue ShCt = DAG.getConstant(ShCtV, + getShiftAmountTy(N0.getValueType())); SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), XType, N0, ShCt); AddToWorkList(Shift.getNode()); @@ -7114,7 +7127,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, - getShiftAmountTy())); + getShiftAmountTy(N0.getValueType()))); AddToWorkList(Shift.getNode()); if (XType.bitsGT(AType)) { @@ -7142,13 +7155,15 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, // Shift the tested bit over the sign bit. APInt AndMask = ConstAndRHS->getAPIntValue(); SDValue ShlAmt = - DAG.getConstant(AndMask.countLeadingZeros(), getShiftAmountTy()); + DAG.getConstant(AndMask.countLeadingZeros(), + getShiftAmountTy(AndLHS.getValueType())); SDValue Shl = DAG.getNode(ISD::SHL, N0.getDebugLoc(), VT, AndLHS, ShlAmt); // Now arithmetic right shift it all the way over, so the result is either // all-ones, or zero. SDValue ShrAmt = - DAG.getConstant(AndMask.getBitWidth()-1, getShiftAmountTy()); + DAG.getConstant(AndMask.getBitWidth()-1, + getShiftAmountTy(Shl.getValueType())); SDValue Shr = DAG.getNode(ISD::SRA, N0.getDebugLoc(), VT, Shl, ShrAmt); return DAG.getNode(ISD::AND, DL, VT, Shr, N3); @@ -7192,7 +7207,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, // shl setcc result by log2 n2c return DAG.getNode(ISD::SHL, DL, N2.getValueType(), Temp, DAG.getConstant(N2C->getAPIntValue().logBase2(), - getShiftAmountTy())); + getShiftAmountTy(Temp.getValueType()))); } // Check to see if this is the equivalent of setcc @@ -7215,7 +7230,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue Ctlz = DAG.getNode(ISD::CTLZ, N0.getDebugLoc(), XType, N0); return DAG.getNode(ISD::SRL, DL, XType, Ctlz, DAG.getConstant(Log2_32(XType.getSizeInBits()), - getShiftAmountTy())); + getShiftAmountTy(Ctlz.getValueType()))); } // fold (setgt X, 0) -> (srl (and (-X, ~X), size(X)-1)) if (N1C && N1C->isNullValue() && CC == ISD::SETGT) { @@ -7225,13 +7240,13 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, return DAG.getNode(ISD::SRL, DL, XType, DAG.getNode(ISD::AND, DL, XType, NegN0, NotN0), DAG.getConstant(XType.getSizeInBits()-1, - getShiftAmountTy())); + getShiftAmountTy(XType))); } // fold (setgt X, -1) -> (xor (srl (X, size(X)-1), 1)) if (N1C && N1C->isAllOnesValue() && CC == ISD::SETGT) { SDValue Sign = DAG.getNode(ISD::SRL, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, - getShiftAmountTy())); + getShiftAmountTy(N0.getValueType()))); return DAG.getNode(ISD::XOR, DL, XType, Sign, DAG.getConstant(1, XType)); } } @@ -7258,7 +7273,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, - getShiftAmountTy())); + getShiftAmountTy(N0.getValueType()))); SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(), XType, N0, Shift); AddToWorkList(Shift.getNode()); diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 98582ba..2ae3286 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -219,6 +219,7 @@ void FunctionLoweringInfo::clear() { CatchInfoFound.clear(); #endif LiveOutRegInfo.clear(); + VisitedBBs.clear(); ArgDbgValues.clear(); ByValArgFrameIndexMap.clear(); RegFixups.clear(); @@ -254,6 +255,123 @@ unsigned FunctionLoweringInfo::CreateRegs(const Type *Ty) { return FirstReg; } +/// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the +/// register is a PHI destination and the PHI's LiveOutInfo is not valid. If +/// the register's LiveOutInfo is for a smaller bit width, it is extended to +/// the larger bit width by zero extension. The bit width must be no smaller +/// than the LiveOutInfo's existing bit width. +const FunctionLoweringInfo::LiveOutInfo * +FunctionLoweringInfo::GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth) { + if (!LiveOutRegInfo.inBounds(Reg)) + return NULL; + + LiveOutInfo *LOI = &LiveOutRegInfo[Reg]; + if (!LOI->IsValid) + return NULL; + + if (BitWidth > LOI->KnownZero.getBitWidth()) { + LOI->NumSignBits = 1; + LOI->KnownZero = LOI->KnownZero.zextOrTrunc(BitWidth); + LOI->KnownOne = LOI->KnownOne.zextOrTrunc(BitWidth); + } + + return LOI; +} + +/// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination +/// register based on the LiveOutInfo of its operands. +void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) { + const Type *Ty = PN->getType(); + if (!Ty->isIntegerTy() || Ty->isVectorTy()) + return; + + SmallVector<EVT, 1> ValueVTs; + ComputeValueVTs(TLI, Ty, ValueVTs); + assert(ValueVTs.size() == 1 && + "PHIs with non-vector integer types should have a single VT."); + EVT IntVT = ValueVTs[0]; + + if (TLI.getNumRegisters(PN->getContext(), IntVT) != 1) + return; + IntVT = TLI.getTypeToTransformTo(PN->getContext(), IntVT); + unsigned BitWidth = IntVT.getSizeInBits(); + + unsigned DestReg = ValueMap[PN]; + if (!TargetRegisterInfo::isVirtualRegister(DestReg)) + return; + LiveOutRegInfo.grow(DestReg); + LiveOutInfo &DestLOI = LiveOutRegInfo[DestReg]; + + Value *V = PN->getIncomingValue(0); + if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) { + DestLOI.NumSignBits = 1; + APInt Zero(BitWidth, 0); + DestLOI.KnownZero = Zero; + DestLOI.KnownOne = Zero; + return; + } + + if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + APInt Val = CI->getValue().zextOrTrunc(BitWidth); + DestLOI.NumSignBits = Val.getNumSignBits(); + DestLOI.KnownZero = ~Val; + DestLOI.KnownOne = Val; + } else { + assert(ValueMap.count(V) && "V should have been placed in ValueMap when its" + "CopyToReg node was created."); + unsigned SrcReg = ValueMap[V]; + if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) { + DestLOI.IsValid = false; + return; + } + const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth); + if (!SrcLOI) { + DestLOI.IsValid = false; + return; + } + DestLOI = *SrcLOI; + } + + assert(DestLOI.KnownZero.getBitWidth() == BitWidth && + DestLOI.KnownOne.getBitWidth() == BitWidth && + "Masks should have the same bit width as the type."); + + for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) { + Value *V = PN->getIncomingValue(i); + if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) { + DestLOI.NumSignBits = 1; + APInt Zero(BitWidth, 0); + DestLOI.KnownZero = Zero; + DestLOI.KnownOne = Zero; + return; + } + + if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + APInt Val = CI->getValue().zextOrTrunc(BitWidth); + DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, Val.getNumSignBits()); + DestLOI.KnownZero &= ~Val; + DestLOI.KnownOne &= Val; + continue; + } + + assert(ValueMap.count(V) && "V should have been placed in ValueMap when " + "its CopyToReg node was created."); + unsigned SrcReg = ValueMap[V]; + if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) { + DestLOI.IsValid = false; + return; + } + const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth); + if (!SrcLOI) { + DestLOI.IsValid = false; + return; + } + DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, SrcLOI->NumSignBits); + DestLOI.KnownZero &= SrcLOI->KnownZero; + DestLOI.KnownOne &= SrcLOI->KnownOne; + } +} + /// setByValArgumentFrameIndex - Record frame index for the byval /// argument. This overrides previous frame index entry for this argument, /// if any. diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 49c862c..f08528f 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -87,7 +87,7 @@ class SelectionDAGLegalize { // If someone requests legalization of the new node, return itself. if (From != To) LegalizedNodes.insert(std::make_pair(To, To)); - + // Transfer SDDbgValues. DAG.TransferDbgValues(From, To); } @@ -498,7 +498,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, int IncrementSize = NumBits / 8; // Divide the stored value in two parts. - SDValue ShiftAmount = DAG.getConstant(NumBits, TLI.getShiftAmountTy()); + SDValue ShiftAmount = DAG.getConstant(NumBits, + TLI.getShiftAmountTy(Val.getValueType())); SDValue Lo = Val; SDValue Hi = DAG.getNode(ISD::SRL, dl, VT, Val, ShiftAmount); @@ -645,7 +646,8 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, } // aggregate the two parts - SDValue ShiftAmount = DAG.getConstant(NumBits, TLI.getShiftAmountTy()); + SDValue ShiftAmount = DAG.getConstant(NumBits, + TLI.getShiftAmountTy(Hi.getValueType())); SDValue Result = DAG.getNode(ISD::SHL, dl, VT, Hi, ShiftAmount); Result = DAG.getNode(ISD::OR, dl, VT, Result, Lo); @@ -1264,7 +1266,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Move the top bits to the right place. Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, - DAG.getConstant(RoundWidth, TLI.getShiftAmountTy())); + DAG.getConstant(RoundWidth, + TLI.getShiftAmountTy(Hi.getValueType()))); // Join the hi and lo parts. Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); @@ -1293,7 +1296,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Move the top bits to the right place. Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, - DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy())); + DAG.getConstant(ExtraWidth, + TLI.getShiftAmountTy(Hi.getValueType()))); // Join the hi and lo parts. Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); @@ -1482,7 +1486,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, DAG.getIntPtrConstant(IncrementSize)); Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, - DAG.getConstant(RoundWidth, TLI.getShiftAmountTy())); + DAG.getConstant(RoundWidth, + TLI.getShiftAmountTy(Tmp3.getValueType()))); Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getPointerInfo().getWithOffset(IncrementSize), ExtraVT, isVolatile, isNonTemporal, @@ -1492,7 +1497,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE@+2:i8 X // Store the top RoundWidth bits. Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, - DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy())); + DAG.getConstant(ExtraWidth, + TLI.getShiftAmountTy(Tmp3.getValueType()))); Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getPointerInfo(), RoundVT, isVolatile, isNonTemporal, Alignment); @@ -1727,7 +1733,8 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) { assert(BitShift < LoadTy.getSizeInBits() && "Pointer advanced wrong?"); if (BitShift) SignBit = DAG.getNode(ISD::SHL, dl, LoadTy, SignBit, - DAG.getConstant(BitShift,TLI.getShiftAmountTy())); + DAG.getConstant(BitShift, + TLI.getShiftAmountTy(SignBit.getValueType()))); } } // Now get the sign bit proper, by seeing whether the value is negative. @@ -2207,7 +2214,8 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, if (!isSigned) { SDValue Fast = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, Op0); - SDValue ShiftConst = DAG.getConstant(1, TLI.getShiftAmountTy()); + SDValue ShiftConst = + DAG.getConstant(1, TLI.getShiftAmountTy(Op0.getValueType())); SDValue Shr = DAG.getNode(ISD::SRL, dl, MVT::i64, Op0, ShiftConst); SDValue AndConst = DAG.getConstant(1, MVT::i64); SDValue And = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, AndConst); @@ -2226,7 +2234,6 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, } // Otherwise, implement the fully general conversion. - EVT SHVT = TLI.getShiftAmountTy(); SDValue And = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, DAG.getConstant(UINT64_C(0xfffffffffffff800), MVT::i64)); @@ -2241,6 +2248,7 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, Op0, DAG.getConstant(UINT64_C(0x0020000000000000), MVT::i64), ISD::SETUGE); SDValue Sel2 = DAG.getNode(ISD::SELECT, dl, MVT::i64, Ge, Sel, Op0); + EVT SHVT = TLI.getShiftAmountTy(Sel2.getValueType()); SDValue Sh = DAG.getNode(ISD::SRL, dl, MVT::i64, Sel2, DAG.getConstant(32, SHVT)); @@ -2387,7 +2395,7 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, /// SDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, DebugLoc dl) { EVT VT = Op.getValueType(); - EVT SHVT = TLI.getShiftAmountTy(); + EVT SHVT = TLI.getShiftAmountTy(VT); SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8; switch (VT.getSimpleVT().SimpleTy) { default: assert(0 && "Unhandled Expand type in BSWAP!"); @@ -2450,7 +2458,7 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, default: assert(0 && "Cannot expand this yet!"); case ISD::CTPOP: { EVT VT = Op.getValueType(); - EVT ShVT = TLI.getShiftAmountTy(); + EVT ShVT = TLI.getShiftAmountTy(VT); unsigned Len = VT.getSizeInBits(); assert(VT.isInteger() && Len <= 128 && Len % 8 == 0 && @@ -2487,7 +2495,7 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, Op = DAG.getNode(ISD::SRL, dl, VT, DAG.getNode(ISD::MUL, dl, VT, Op, Mask01), DAG.getConstant(Len - 8, ShVT)); - + return Op; } case ISD::CTLZ: { @@ -2501,7 +2509,7 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, // // but see also: http://www.hackersdelight.org/HDcode/nlz.cc EVT VT = Op.getValueType(); - EVT ShVT = TLI.getShiftAmountTy(); + EVT ShVT = TLI.getShiftAmountTy(VT); unsigned len = VT.getSizeInBits(); for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); @@ -2737,7 +2745,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, // SAR. However, it is doubtful that any exist. EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); EVT VT = Node->getValueType(0); - EVT ShiftAmountTy = TLI.getShiftAmountTy(); + EVT ShiftAmountTy = TLI.getShiftAmountTy(VT); if (VT.isVector()) ShiftAmountTy = VT; unsigned BitsDiff = VT.getScalarType().getSizeInBits() - @@ -2901,7 +2909,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, // 1 -> Hi Tmp1 = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0), DAG.getConstant(OpTy.getSizeInBits()/2, - TLI.getShiftAmountTy())); + TLI.getShiftAmountTy(Node->getOperand(0).getValueType()))); Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1); } else { // 0 -> Lo @@ -3260,7 +3268,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, assert(LC != RTLIB::UNKNOWN_LIBCALL && "Cannot expand this operation!"); LHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, LHS); RHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, RHS); - + SDValue Ret = ExpandLibCall(LC, Node, isSigned); BottomHalf = DAG.getNode(ISD::TRUNCATE, dl, VT, Ret); TopHalf = DAG.getNode(ISD::SRL, dl, Ret.getValueType(), Ret, @@ -3268,7 +3276,8 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, TopHalf = DAG.getNode(ISD::TRUNCATE, dl, VT, TopHalf); } if (isSigned) { - Tmp1 = DAG.getConstant(VT.getSizeInBits() - 1, TLI.getShiftAmountTy()); + Tmp1 = DAG.getConstant(VT.getSizeInBits() - 1, + TLI.getShiftAmountTy(BottomHalf.getValueType())); Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, Tmp1); TopHalf = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), TopHalf, Tmp1, ISD::SETNE); @@ -3286,7 +3295,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, Tmp2 = DAG.getNode(ISD::ANY_EXTEND, dl, PairTy, Node->getOperand(1)); Tmp2 = DAG.getNode(ISD::SHL, dl, PairTy, Tmp2, DAG.getConstant(PairTy.getSizeInBits()/2, - TLI.getShiftAmountTy())); + TLI.getShiftAmountTy(PairTy))); Results.push_back(DAG.getNode(ISD::OR, dl, PairTy, Tmp1, Tmp2)); break; } @@ -3464,7 +3473,7 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node, Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1); Tmp1 = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, - DAG.getConstant(DiffBits, TLI.getShiftAmountTy())); + DAG.getConstant(DiffBits, TLI.getShiftAmountTy(NVT))); Results.push_back(Tmp1); break; } diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 2775212..27a466b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -177,25 +177,27 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { // First get the sign bit of second operand. SDValue SignBit = DAG.getNode(ISD::SHL, dl, RVT, DAG.getConstant(1, RVT), DAG.getConstant(RSize - 1, - TLI.getShiftAmountTy())); + TLI.getShiftAmountTy(RVT))); SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit); // Shift right or sign-extend it if the two operands have different types. int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits(); if (SizeDiff > 0) { SignBit = DAG.getNode(ISD::SRL, dl, RVT, SignBit, - DAG.getConstant(SizeDiff, TLI.getShiftAmountTy())); + DAG.getConstant(SizeDiff, + TLI.getShiftAmountTy(SignBit.getValueType()))); SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit); } else if (SizeDiff < 0) { SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit); SignBit = DAG.getNode(ISD::SHL, dl, LVT, SignBit, - DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy())); + DAG.getConstant(-SizeDiff, + TLI.getShiftAmountTy(SignBit.getValueType()))); } // Clear the sign bit of the first operand. SDValue Mask = DAG.getNode(ISD::SHL, dl, LVT, DAG.getConstant(1, LVT), DAG.getConstant(LSize - 1, - TLI.getShiftAmountTy())); + TLI.getShiftAmountTy(LVT))); Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, LVT)); LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 2fb2f2d..9120288 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1420,7 +1420,7 @@ SDValue SelectionDAG::getMDNode(const MDNode *MD) { /// the target's desired shift amount type. SDValue SelectionDAG::getShiftAmountOperand(SDValue Op) { EVT OpTy = Op.getValueType(); - MVT ShTy = TLI.getShiftAmountTy(); + MVT ShTy = TLI.getShiftAmountTy(OpTy); if (OpTy == ShTy || OpTy.isVector()) return Op; ISD::NodeType Opcode = OpTy.bitsGT(ShTy) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; @@ -2048,7 +2048,7 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask, return; } break; - + default: // Allow the target to implement this method for its nodes. if (Op.getOpcode() >= ISD::BUILTIN_OP_END) { @@ -2088,12 +2088,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{ case ISD::Constant: { const APInt &Val = cast<ConstantSDNode>(Op)->getAPIntValue(); - // If negative, return # leading ones. - if (Val.isNegative()) - return Val.countLeadingOnes(); - - // Return # leading zeros. - return Val.countLeadingZeros(); + return Val.getNumSignBits(); } case ISD::SIGN_EXTEND: @@ -2297,12 +2292,12 @@ bool SelectionDAG::isBaseWithConstantOffset(SDValue Op) const { if ((Op.getOpcode() != ISD::ADD && Op.getOpcode() != ISD::OR) || !isa<ConstantSDNode>(Op.getOperand(1))) return false; - - if (Op.getOpcode() == ISD::OR && + + if (Op.getOpcode() == ISD::OR && !MaskedValueIsZero(Op.getOperand(0), cast<ConstantSDNode>(Op.getOperand(1))->getAPIntValue())) return false; - + return true; } @@ -2753,7 +2748,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT, // i8, which is easy to fall into in generic code that uses // TLI.getShiftAmount(). assert(N2.getValueType().getSizeInBits() >= - Log2_32_Ceil(N1.getValueType().getSizeInBits()) && + Log2_32_Ceil(N1.getValueType().getSizeInBits()) && "Invalid use of small shift amount with oversized value!"); // Always fold shifts of i1 values so the code generator doesn't need to diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 452f561..48d9bbb 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -641,16 +641,17 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, // If the source register was virtual and if we know something about it, // add an assert node. if (!TargetRegisterInfo::isVirtualRegister(Regs[Part+i]) || - !RegisterVT.isInteger() || RegisterVT.isVector() || - !FuncInfo.LiveOutRegInfo.inBounds(Regs[Part+i])) + !RegisterVT.isInteger() || RegisterVT.isVector()) + continue; + + const FunctionLoweringInfo::LiveOutInfo *LOI = + FuncInfo.GetLiveOutRegInfo(Regs[Part+i]); + if (!LOI) continue; - - const FunctionLoweringInfo::LiveOutInfo &LOI = - FuncInfo.LiveOutRegInfo[Regs[Part+i]]; unsigned RegSize = RegisterVT.getSizeInBits(); - unsigned NumSignBits = LOI.NumSignBits; - unsigned NumZeroBits = LOI.KnownZero.countLeadingOnes(); + unsigned NumSignBits = LOI->NumSignBits; + unsigned NumZeroBits = LOI->KnownZero.countLeadingOnes(); // FIXME: We capture more information than the dag can represent. For // now, just use the tightest assertzext/assertsext possible. @@ -908,7 +909,7 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V, Val.getResNo(), Offset, dl, DbgSDNodeOrder); DAG.AddDbgValue(SDV, Val.getNode(), false); } - } else + } else DEBUG(dbgs() << "Dropping debug info for " << DI); DanglingDebugInfoMap[V] = DanglingDebugInfo(); } @@ -1417,7 +1418,7 @@ void SelectionDAGBuilder::visitBr(const BranchInst &I) { // jle foo // if (const BinaryOperator *BOp = dyn_cast<BinaryOperator>(CondVal)) { - if (!TLI.isJumpExpensive() && + if (!TLI.isJumpExpensive() && BOp->hasOneUse() && (BOp->getOpcode() == Instruction::And || BOp->getOpcode() == Instruction::Or)) { @@ -1915,7 +1916,7 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR, DEBUG(dbgs() << "Lowering jump table\n" << "First entry: " << First << ". Last entry: " << Last << '\n' << "Range: " << Range - << "Size: " << TSize << ". Density: " << Density << "\n\n"); + << ". Size: " << TSize << ". Density: " << Density << "\n\n"); // Get the MachineFunction which holds the current MBB. This is used when // inserting any additional MBBs necessary to represent the switch. @@ -2408,19 +2409,19 @@ void SelectionDAGBuilder::visitBinary(const User &I, unsigned OpCode) { void SelectionDAGBuilder::visitShift(const User &I, unsigned Opcode) { SDValue Op1 = getValue(I.getOperand(0)); SDValue Op2 = getValue(I.getOperand(1)); - - MVT ShiftTy = TLI.getShiftAmountTy(); - + + MVT ShiftTy = TLI.getShiftAmountTy(Op2.getValueType()); + // Coerce the shift amount to the right type if we can. if (!I.getType()->isVectorTy() && Op2.getValueType() != ShiftTy) { unsigned ShiftSize = ShiftTy.getSizeInBits(); unsigned Op2Size = Op2.getValueType().getSizeInBits(); DebugLoc DL = getCurDebugLoc(); - + // If the operand is smaller than the shift count type, promote it. if (ShiftSize > Op2Size) Op2 = DAG.getNode(ISD::ZERO_EXTEND, DL, ShiftTy, Op2); - + // If the operand is larger than the shift count type but the shift // count type has enough bits to represent any shift value, truncate // it now. This is a common case and it exposes the truncate to diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index a1a70c3..8f466d9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -348,7 +348,7 @@ public: SDValue getControlRoot(); DebugLoc getCurDebugLoc() const { return CurDebugLoc; } - void setCurDebugLoc(DebugLoc dl){ CurDebugLoc = dl; } + unsigned getSDNodeOrder() const { return SDNodeOrder; } void CopyValueToVirtualRegister(const Value *V, unsigned Reg); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 62ebc81..68ba966 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -49,6 +49,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/Statistic.h" #include <algorithm> using namespace llvm; @@ -479,16 +480,7 @@ void SelectionDAGISel::ComputeLiveOutVRegInfo() { unsigned NumSignBits = CurDAG->ComputeNumSignBits(Src); Mask = APInt::getAllOnesValue(SrcVT.getSizeInBits()); CurDAG->ComputeMaskedBits(Src, Mask, KnownZero, KnownOne); - - // Only install this information if it tells us something. - if (NumSignBits != 1 || KnownZero != 0 || KnownOne != 0) { - FuncInfo->LiveOutRegInfo.grow(DestReg); - FunctionLoweringInfo::LiveOutInfo &LOI = - FuncInfo->LiveOutRegInfo[DestReg]; - LOI.NumSignBits = NumSignBits; - LOI.KnownOne = KnownOne; - LOI.KnownZero = KnownZero; - } + FuncInfo->AddLiveOutRegInfo(DestReg, NumSignBits, KnownZero, KnownOne); } while (!Worklist.empty()); } @@ -832,11 +824,39 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { FastIS = TLI.createFastISel(*FuncInfo); // Iterate over all basic blocks in the function. - for (Function::const_iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { - const BasicBlock *LLVMBB = &*I; + ReversePostOrderTraversal<const Function*> RPOT(&Fn); + for (ReversePostOrderTraversal<const Function*>::rpo_iterator + I = RPOT.begin(), E = RPOT.end(); I != E; ++I) { + const BasicBlock *LLVMBB = *I; #ifndef NDEBUG CheckLineNumbers(LLVMBB); #endif + + if (OptLevel != CodeGenOpt::None) { + bool AllPredsVisited = true; + for (const_pred_iterator PI = pred_begin(LLVMBB), PE = pred_end(LLVMBB); + PI != PE; ++PI) { + if (!FuncInfo->VisitedBBs.count(*PI)) { + AllPredsVisited = false; + break; + } + } + + if (AllPredsVisited) { + for (BasicBlock::const_iterator I = LLVMBB->begin(), E = LLVMBB->end(); + I != E && isa<PHINode>(I); ++I) { + FuncInfo->ComputePHILiveOutRegInfo(cast<PHINode>(I)); + } + } else { + for (BasicBlock::const_iterator I = LLVMBB->begin(), E = LLVMBB->end(); + I != E && isa<PHINode>(I); ++I) { + FuncInfo->InvalidatePHILiveOutRegInfo(cast<PHINode>(I)); + } + } + + FuncInfo->VisitedBBs.insert(LLVMBB); + } + FuncInfo->MBB = FuncInfo->MBBMap[LLVMBB]; FuncInfo->InsertPt = FuncInfo->MBB->getFirstNonPHI(); @@ -851,17 +871,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { PrepareEHLandingPad(); // Lower any arguments needed in this block if this is the entry block. - if (LLVMBB == &Fn.getEntryBlock()) { - for (BasicBlock::const_iterator DBI = LLVMBB->begin(), DBE = LLVMBB->end(); - DBI != DBE; ++DBI) { - if (const DbgInfoIntrinsic *DI = dyn_cast<DbgInfoIntrinsic>(DBI)) { - const DebugLoc DL = DI->getDebugLoc(); - SDB->setCurDebugLoc(DL); - break; - } - } + if (LLVMBB == &Fn.getEntryBlock()) LowerArguments(LLVMBB); - } // Before doing SelectionDAG ISel, see if FastISel has been requested. if (FastIS) { diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 691390e..35b847c 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -563,7 +563,7 @@ TargetLowering::TargetLowering(const TargetMachine &tm, setOperationAction(ISD::TRAP, MVT::Other, Expand); IsLittleEndian = TD->isLittleEndian(); - ShiftAmountTy = PointerTy = MVT::getIntegerVT(8*TD->getPointerSize()); + PointerTy = MVT::getIntegerVT(8*TD->getPointerSize()); memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*)); memset(TargetDAGCombineArray, 0, array_lengthof(TargetDAGCombineArray)); maxStoresPerMemset = maxStoresPerMemcpy = maxStoresPerMemmove = 8; @@ -596,6 +596,10 @@ TargetLowering::~TargetLowering() { delete &TLOF; } +MVT TargetLowering::getShiftAmountTy(EVT LHSTy) const { + return MVT::getIntegerVT(8*TD->getPointerSize()); +} + /// canOpTrap - Returns true if the operation can trap for the value type. /// VT must be a legal type. bool TargetLowering::canOpTrap(unsigned Op, EVT VT) const { @@ -1401,7 +1405,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, BitWidth - InnerVT.getSizeInBits()) & DemandedMask) == 0 && isTypeDesirableForOp(ISD::SHL, InnerVT)) { - EVT ShTy = getShiftAmountTy(); + EVT ShTy = getShiftAmountTy(InnerVT); if (!APInt(BitWidth, ShAmt).isIntN(ShTy.getSizeInBits())) ShTy = InnerVT; SDValue NarrowShl = @@ -2188,7 +2192,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1, if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N0.getOperand(1))) { EVT ShiftTy = DCI.isBeforeLegalize() ? - getPointerTy() : getShiftAmountTy(); + getPointerTy() : getShiftAmountTy(N0.getValueType()); if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0 --> (X & 8) >> 3 // Perform the xform if the AND RHS is a single bit. if (AndRHS->getAPIntValue().isPowerOf2()) { @@ -2359,7 +2363,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1, // (Z-X) == X --> Z == X<<1 SDValue SH = DAG.getNode(ISD::SHL, dl, N1.getValueType(), N1, - DAG.getConstant(1, getShiftAmountTy())); + DAG.getConstant(1, getShiftAmountTy(N1.getValueType()))); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(SH.getNode()); return DAG.getSetCC(dl, VT, N0.getOperand(0), SH, Cond); @@ -2381,7 +2385,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1, assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); // X == (Z-X) --> X<<1 == Z SDValue SH = DAG.getNode(ISD::SHL, dl, N1.getValueType(), N0, - DAG.getConstant(1, getShiftAmountTy())); + DAG.getConstant(1, getShiftAmountTy(N0.getValueType()))); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(SH.getNode()); return DAG.getSetCC(dl, VT, SH, N1.getOperand(0), Cond); @@ -2493,7 +2497,7 @@ bool TargetLowering::isGAPlusOffset(SDNode *N, const GlobalValue *&GA, } } } - + return false; } @@ -3141,14 +3145,14 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, // Shift right algebraic if shift value is nonzero if (magics.s > 0) { Q = DAG.getNode(ISD::SRA, dl, VT, Q, - DAG.getConstant(magics.s, getShiftAmountTy())); + DAG.getConstant(magics.s, getShiftAmountTy(Q.getValueType()))); if (Created) Created->push_back(Q.getNode()); } // Extract the sign bit and add it to the quotient SDValue T = DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(VT.getSizeInBits()-1, - getShiftAmountTy())); + getShiftAmountTy(Q.getValueType()))); if (Created) Created->push_back(T.getNode()); return DAG.getNode(ISD::ADD, dl, VT, Q, T); @@ -3192,19 +3196,19 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG, assert(magics.s < N1C->getAPIntValue().getBitWidth() && "We shouldn't generate an undefined shift!"); return DAG.getNode(ISD::SRL, dl, VT, Q, - DAG.getConstant(magics.s, getShiftAmountTy())); + DAG.getConstant(magics.s, getShiftAmountTy(Q.getValueType()))); } else { SDValue NPQ = DAG.getNode(ISD::SUB, dl, VT, N->getOperand(0), Q); if (Created) Created->push_back(NPQ.getNode()); NPQ = DAG.getNode(ISD::SRL, dl, VT, NPQ, - DAG.getConstant(1, getShiftAmountTy())); + DAG.getConstant(1, getShiftAmountTy(NPQ.getValueType()))); if (Created) Created->push_back(NPQ.getNode()); NPQ = DAG.getNode(ISD::ADD, dl, VT, NPQ, Q); if (Created) Created->push_back(NPQ.getNode()); return DAG.getNode(ISD::SRL, dl, VT, NPQ, - DAG.getConstant(magics.s-1, getShiftAmountTy())); + DAG.getConstant(magics.s-1, getShiftAmountTy(NPQ.getValueType()))); } } diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index 5663936..fd5d50b 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -167,6 +167,20 @@ void SplitAnalysis::calcLiveBlockInfo() { } } +bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const { + unsigned OrigReg = VRM.getOriginal(CurLI->reg); + const LiveInterval &Orig = LIS.getInterval(OrigReg); + assert(!Orig.empty() && "Splitting empty interval?"); + LiveInterval::const_iterator I = Orig.find(Idx); + + // Range containing Idx should begin at Idx. + if (I != Orig.end() && I->start <= Idx) + return I->start == Idx; + + // Range does not contain Idx, previous must end at Idx. + return I != Orig.begin() && (--I)->end == Idx; +} + void SplitAnalysis::print(const BlockPtrSet &B, raw_ostream &OS) const { for (BlockPtrSet::const_iterator I = B.begin(), E = B.end(); I != E; ++I) { unsigned count = UsingBlocks.lookup(*I); @@ -947,10 +961,10 @@ void SplitEditor::splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks) { openIntv(); SlotIndex SegStart = enterIntvBefore(BI.FirstUse); - if (BI.LastUse < BI.LastSplitPoint) { + if (!BI.LiveOut || BI.LastUse < BI.LastSplitPoint) { useIntv(SegStart, leaveIntvAfter(BI.LastUse)); } else { - // THe last use os after tha last valid split point. + // The last use is after the last valid split point. SlotIndex SegStop = leaveIntvBefore(BI.LastSplitPoint); useIntv(SegStart, SegStop); overlapIntv(SegStop, BI.LastUse); diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h index 5c34afd..e02e629 100644 --- a/lib/CodeGen/SplitKit.h +++ b/lib/CodeGen/SplitKit.h @@ -125,6 +125,13 @@ public: return UsingBlocks.lookup(MBB); } + /// isOriginalEndpoint - Return true if the original live range was killed or + /// (re-)defined at Idx. Idx should be the 'def' slot for a normal kill/def, + /// and 'use' for an early-clobber def. + /// This can be used to recognize code inserted by earlier live range + /// splitting. + bool isOriginalEndpoint(SlotIndex Idx) const; + typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet; // Print a set of blocks with use counts. diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 0b7bd98..fa311dc 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -178,6 +178,10 @@ const MCSection *TargetLoweringObjectFileELF::getEHFrameSection() const { static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) { + // FIXME: Why is this here? Codegen is should not be in the business + // of figuring section flags. If the user wrote section(".eh_frame"), + // we should just pass that to MC which will defer to the assembly + // or use its default if producing an object file. if (Name.empty() || Name[0] != '.') return K; // Some lame default implementation based on some magic section names. @@ -203,6 +207,9 @@ getELFKindForNamedSection(StringRef Name, SectionKind K) { Name.startswith(".llvm.linkonce.tb.")) return SectionKind::getThreadBSS(); + if (Name == ".eh_frame") + return SectionKind::getDataRel(); + return K; } @@ -441,11 +448,15 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, Triple T(((LLVMTargetMachine&)TM).getTargetTriple()); if (T.getOS() == Triple::Darwin) { - unsigned MajNum = T.getDarwinMajorNumber(); - if (MajNum == 7 || MajNum == 8) // 10.3 Panther, 10.4 Tiger + switch (T.getDarwinMajorNumber()) { + case 7: // 10.3 Panther. + case 8: // 10.4 Tiger. CommDirectiveSupportsAlignment = false; - if (MajNum > 9) // 10.6 SnowLeopard - IsFunctionEHSymbolGlobal = false; + break; + case 9: // 10.5 Leopard. + case 10: // 10.6 SnowLeopard. + break; + } } TargetLoweringObjectFile::Initialize(Ctx, TM); @@ -630,7 +641,7 @@ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { // Parse the section specifier and create it if valid. StringRef Segment, Section; - unsigned TAA, StubSize; + unsigned TAA = (unsigned)MCSectionMachO::SECTION_ATTRIBUTES, StubSize = 0; std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section, TAA, StubSize); @@ -643,10 +654,19 @@ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, return DataSection; } + bool TAAWasSet = (TAA != MCSectionMachO::SECTION_ATTRIBUTES); + if (!TAAWasSet) + TAA = 0; // Sensible default if this is a new section. + // Get the section. const MCSectionMachO *S = getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); + // If TAA wasn't set by ParseSectionSpecifier() above, + // use the value returned by getMachOSection() as a default. + if (!TAAWasSet) + TAA = S->getTypeAndAttributes(); + // Okay, now that we got the section, verify that the TAA & StubSize agree. // If the user declared multiple globals with different section flags, we need // to reject it here. diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index 458a213..ec149dd 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -478,7 +478,8 @@ static void ResurrectConfirmedKill(unsigned Reg, const TargetRegisterInfo* TRI, if (!RegKills[KReg]) return; - assert(KillOps[KReg] == KillOp && "invalid superreg kill flags"); + assert(KillOps[KReg]->getParent() == KillOp->getParent() && + "invalid superreg kill flags"); KillOps[KReg] = NULL; RegKills.reset(KReg); @@ -487,7 +488,8 @@ static void ResurrectConfirmedKill(unsigned Reg, const TargetRegisterInfo* TRI, for (const unsigned *SR = TRI->getSubRegisters(KReg); *SR; ++SR) { DEBUG(dbgs() << " Resurrect subreg " << TRI->getName(*SR) << "\n"); - assert(KillOps[*SR] == KillOp && "invalid subreg kill flags"); + assert(KillOps[*SR]->getParent() == KillOp->getParent() && + "invalid subreg kill flags"); KillOps[*SR] = NULL; RegKills.reset(*SR); } |