From zwarich at apple.com Mon Dec 27 04:08:19 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 27 Dec 2010 10:08:19 -0000 Subject: [llvm-commits] [llvm] r122582 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101227100820.00E752A6C12C@llvm.org> Author: zwarich Date: Mon Dec 27 04:08:19 2010 New Revision: 122582 URL: http://llvm.org/viewvc/llvm-project?rev=122582&view=rev Log: Land a first cut at StrongPHIElimination. There are only 5 new test failures when running without the verifier, and I have not yet checked them to see if the new results are still correct. There are more verifier failures, but they all seem to be additional occurrences of verifier failures that occur with the existing PHIElimination pass. There are a few obvious issues with the code: 1) It doesn't properly update the register equivalence classes during copy insertion, and instead recomputes them before merging live intervals and renaming registers. I wanted to keep this first patch simple for debugging purposes, but it shouldn't be very hard to do this. 2) It doesn't mix the renaming and live interval merging with the copy insertion process, which leads to a lot of virtual register churn. Virtual registers and live intervals are created, only to later be merged into others. The code should be smarter and only create a new virtual register if there is no existing register in the same congruence class. 3) In one place the code uses a DenseMap per basic block, which is unnecessary heap allocation. There should be an inline storage version of DenseMap. I did a quick compile-time test of running llc on 403.gcc with and without StrongPHIElimination. It is slightly slower with StrongPHIElimination, because the small decrease in the coalescer runtime can't beat the increase in phi elimination runtime. Perhaps fixing the above performance issues will narrow the gap. I also haven't yet run any tests of the quality of the generated code. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122582&r1=122581&r2=122582&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Dec 27 04:08:19 2010 @@ -1,4 +1,4 @@ -//===- StrongPhiElimination.cpp - Eliminate PHI nodes by inserting copies -===// +//===- StrongPHIElimination.cpp - Eliminate PHI nodes by inserting copies -===// // // The LLVM Compiler Infrastructure // @@ -7,6 +7,34 @@ // //===----------------------------------------------------------------------===// // +// This pass eliminates PHI instructions by aggressively coalescing the copies +// that would be inserted by a naive algorithm and only inserting the copies +// that are necessary. The coalescing technique initially assumes that all +// registers appearing in a PHI instruction do not interfere. It then eliminates +// proven interferences, using dominators to only perform a linear number of +// interference tests instead of the quadratic number of interference tests +// that this would naively require. This is a technique derived from: +// +// Budimlic, et al. Fast copy coalescing and live-range identification. +// In Proceedings of the ACM SIGPLAN 2002 Conference on Programming Language +// Design and Implementation (Berlin, Germany, June 17 - 19, 2002). +// PLDI '02. ACM, New York, NY, 25-32. +// +// The original implementation constructs a data structure they call a dominance +// forest for this purpose. The dominance forest was shown to be unnecessary, +// as it is possible to emulate the creation and traversal of a dominance forest +// by directly using the dominator tree, rather than actually constructing the +// dominance forest. This technique is explained in: +// +// Boissinot, et al. Revisiting Out-of-SSA Translation for Correctness, Code +// Quality and Efficiency, +// In Proceedings of the 7th annual IEEE/ACM International Symposium on Code +// Generation and Optimization (Seattle, Washington, March 22 - 25, 2009). +// CGO '09. IEEE, Washington, DC, 114-125. +// +// Careful implementation allows for all of the dominator forest interference +// checks to be performed at once in a single depth-first traversal of the +// dominator tree, which is what is implemented here. // //===----------------------------------------------------------------------===// @@ -34,14 +62,104 @@ bool runOnMachineFunction(MachineFunction&); private: + /// This struct represents a single node in the union-find data structure + /// representing the variable congruence classes. There is one difference + /// from a normal union-find data structure. We steal two bits from the parent + /// pointer . One of these bits is used to represent whether the register + /// itself has been isolated, and the other is used to represent whether the + /// PHI with that register as its destination has been isolated. + /// + /// Note that this leads to the strange situation where the leader of a + /// congruence class may no longer logically be a member, due to being + /// isolated. + struct Node { + enum Flags { + kRegisterIsolatedFlag = 1, + kPHIIsolatedFlag = 2 + }; + Node(unsigned v) : value(v), rank(0) { parent.setPointer(this); } + + Node* getLeader(); + + PointerIntPair parent; + unsigned value; + unsigned rank; + }; + + /// Add a register in a new congruence class containing only itself. + void addReg(unsigned); + + /// Join the congruence classes of two registers. + void unionRegs(unsigned, unsigned); + + /// Get the color of a register. The color is 0 if the register has been + /// isolated. + unsigned getRegColor(unsigned); + + // Isolate a register. + void isolateReg(unsigned); + + /// Get the color of a PHI. The color of a PHI is 0 if the PHI has been + /// isolated. Otherwise, it is the original color of its destination and + /// all of its operands (before they were isolated, if they were). + unsigned getPHIColor(MachineInstr*); + + /// Isolate a PHI. + void isolatePHI(MachineInstr*); + + void PartitionRegisters(MachineFunction& MF); + + /// Traverses a basic block, splitting any interferences found between + /// registers in the same congruence class. It takes two DenseMaps as + /// arguments that it also updates: CurrentDominatingParent, which maps + /// a color to the register in that congruence class whose definition was + /// most recently seen, and ImmediateDominatingParent, which maps a register + /// to the register in the same congruence class that most immediately + /// dominates it. + /// + /// This function assumes that it is being called in a depth-first traversal + /// of the dominator tree. + void SplitInterferencesForBasicBlock( + MachineBasicBlock&, + DenseMap& CurrentDominatingParent, + DenseMap& ImmediateDominatingParent); + + // Lowers a PHI instruction, inserting copies of the source and destination + // registers as necessary. void InsertCopiesForPHI(MachineInstr*, MachineBasicBlock*); + // Merges the live interval of Reg into NewReg and renames Reg to NewReg + // everywhere that Reg appears. Requires Reg and NewReg to have non- + // overlapping lifetimes. + void MergeLIsAndRename(unsigned Reg, unsigned NewReg); + MachineRegisterInfo* MRI; const TargetInstrInfo* TII; + MachineDominatorTree* DT; LiveIntervals* LI; - typedef DenseSet > CopySet; - CopySet InsertedCopies; + BumpPtrAllocator Allocator; + + DenseMap RegNodeMap; + + // FIXME: Can these two data structures be combined? Would a std::multimap + // be any better? + + // Stores pairs of predecessor basic blocks and the source registers of + // inserted copy instructions. + typedef DenseSet > SrcCopySet; + SrcCopySet InsertedSrcCopySet; + + // Maps pairs of predecessor basic blocks and colors to their defining copy + // instructions. + typedef DenseMap, MachineInstr*> + SrcCopyMap; + SrcCopyMap InsertedSrcCopyMap; + + // Maps inserted destination copy registers to their defining copy + // instructions. + typedef DenseMap DestCopyMap; + DestCopyMap InsertedDestCopies; }; } // namespace @@ -86,8 +204,22 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction& MF) { MRI = &MF.getRegInfo(); TII = MF.getTarget().getInstrInfo(); + DT = &getAnalysis(); LI = &getAnalysis(); + PartitionRegisters(MF); + + // Perform a depth-first traversal of the dominator tree, splitting + // interferences amongst PHI-congruence classes. + DenseMap CurrentDominatingParent; + DenseMap ImmediateDominatingParent; + for (df_iterator DI = df_begin(DT->getRootNode()), + DE = df_end(DT->getRootNode()); DI != DE; ++DI) { + SplitInterferencesForBasicBlock(*DI->getBlock(), + CurrentDominatingParent, + ImmediateDominatingParent); + } + // Insert copies for all PHI source and destination registers. for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { @@ -97,13 +229,86 @@ } } + // FIXME: Preserve the equivalence classes during copy insertion and use + // the preversed equivalence classes instead of recomputing them. + RegNodeMap.clear(); + PartitionRegisters(MF); + + DenseMap RegRenamingMap; + bool Changed = false; + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); + while (BBI != BBE && BBI->isPHI()) { + MachineInstr* PHI = BBI; + + assert(PHI->getNumOperands() > 0); + + unsigned SrcReg = PHI->getOperand(1).getReg(); + unsigned SrcColor = getRegColor(SrcReg); + unsigned NewReg = RegRenamingMap[SrcColor]; + if (!NewReg) { + NewReg = SrcReg; + RegRenamingMap[SrcColor] = SrcReg; + } + MergeLIsAndRename(SrcReg, NewReg); + + unsigned DestReg = PHI->getOperand(0).getReg(); + if (!InsertedDestCopies.count(DestReg)) + MergeLIsAndRename(DestReg, NewReg); + + for (unsigned i = 3; i < PHI->getNumOperands(); i += 2) { + unsigned SrcReg = PHI->getOperand(i).getReg(); + MergeLIsAndRename(SrcReg, NewReg); + } + + ++BBI; + LI->RemoveMachineInstrFromMaps(PHI); + PHI->eraseFromParent(); + Changed = true; + } + } + + // Due to the insertion of copies to split live ranges, the live intervals are + // guaranteed to not overlap, except in one case: an original PHI source and a + // PHI destination copy. In this case, they have the same value and thus don't + // truly intersect, so we merge them into the value live at that point. + // FIXME: Is there some better way we can handle this? + for (DestCopyMap::iterator I = InsertedDestCopies.begin(), + E = InsertedDestCopies.end(); I != E; ++I) { + unsigned DestReg = I->first; + unsigned DestColor = getRegColor(DestReg); + unsigned NewReg = RegRenamingMap[DestColor]; + + LiveInterval& DestLI = LI->getInterval(DestReg); + LiveInterval& NewLI = LI->getInterval(NewReg); + + assert(DestLI.containsOneValue()); + LiveRange* DestLR = DestLI.begin(); + VNInfo* NewVNI = NewLI.getVNInfoAt(DestLR->start); + if (!NewVNI) { + NewVNI = NewLI.createValueCopy(DestLR->valno, LI->getVNInfoAllocator()); + MachineInstr* CopyInstr = I->second; + CopyInstr->getOperand(1).setIsKill(true); + } + + LiveRange NewLR(DestLR->start, DestLR->end, NewVNI); + NewLI.addRange(NewLR); + + LI->removeInterval(DestReg); + MRI->replaceRegWith(DestReg, NewReg); + } + // Adjust the live intervals of all PHI source registers to handle the case // where the PHIs in successor blocks were the only later uses of the source // register. - for (CopySet::iterator I = InsertedCopies.begin(), E = InsertedCopies.end(); - I != E; ++I) { + for (SrcCopySet::iterator I = InsertedSrcCopySet.begin(), + E = InsertedSrcCopySet.end(); I != E; ++I) { MachineBasicBlock* MBB = I->first; unsigned SrcReg = I->second; + if (unsigned RenamedRegister = RegRenamingMap[getRegColor(SrcReg)]) + SrcReg = RenamedRegister; + LiveInterval& SrcLI = LI->getInterval(SrcReg); bool isLiveOut = false; @@ -120,37 +325,376 @@ MachineOperand* LastUse = findLastUse(MBB, SrcReg); assert(LastUse); - SrcLI.removeRange(LI->getInstructionIndex(LastUse->getParent()).getDefIndex(), - LI->getMBBEndIdx(MBB)); + SlotIndex LastUseIndex = LI->getInstructionIndex(LastUse->getParent()); + SrcLI.removeRange(LastUseIndex.getDefIndex(), LI->getMBBEndIdx(MBB)); LastUse->setIsKill(true); } - // Remove all PHI instructions from the function. - bool Changed = false; + LI->renumber(); + + Allocator.Reset(); + RegNodeMap.clear(); + InsertedSrcCopySet.clear(); + InsertedSrcCopyMap.clear(); + InsertedDestCopies.clear(); + + return Changed; +} + +void StrongPHIElimination::addReg(unsigned Reg) { + if (RegNodeMap.count(Reg)) + return; + RegNodeMap[Reg] = new (Allocator) Node(Reg); +} + +StrongPHIElimination::Node* +StrongPHIElimination::Node::getLeader() { + Node* parentPointer = parent.getPointer(); + if (parentPointer == this) + return this; + Node* newParent = parentPointer->getLeader(); + parent.setPointer(newParent); + return newParent; +} + +unsigned StrongPHIElimination::getRegColor(unsigned Reg) { + DenseMap::iterator RI = RegNodeMap.find(Reg); + if (RI == RegNodeMap.end()) + return 0; + Node* Node = RI->second; + if (Node->parent.getInt() & Node::kRegisterIsolatedFlag) + return 0; + return Node->getLeader()->value; +} + +void StrongPHIElimination::unionRegs(unsigned Reg1, unsigned Reg2) { + Node* Node1 = RegNodeMap[Reg1]->getLeader(); + Node* Node2 = RegNodeMap[Reg2]->getLeader(); + + if (Node1->rank > Node2->rank) { + Node2->parent.setPointer(Node1->getLeader()); + } else if (Node1->rank < Node2->rank) { + Node1->parent.setPointer(Node2->getLeader()); + } else if (Node1 != Node2) { + Node2->parent.setPointer(Node1->getLeader()); + Node1->rank++; + } +} + +void StrongPHIElimination::isolateReg(unsigned Reg) { + Node* Node = RegNodeMap[Reg]; + Node->parent.setInt(Node->parent.getInt() | Node::kRegisterIsolatedFlag); +} + +unsigned StrongPHIElimination::getPHIColor(MachineInstr* PHI) { + assert(PHI->isPHI()); + + unsigned DestReg = PHI->getOperand(0).getReg(); + Node* DestNode = RegNodeMap[DestReg]; + if (DestNode->parent.getInt() & Node::kPHIIsolatedFlag) + return 0; + + for (unsigned i = 1; i < PHI->getNumOperands(); i += 2) { + unsigned SrcColor = getRegColor(PHI->getOperand(i).getReg()); + if (SrcColor) + return SrcColor; + } + return 0; +} + +void StrongPHIElimination::isolatePHI(MachineInstr* PHI) { + assert(PHI->isPHI()); + Node* Node = RegNodeMap[PHI->getOperand(0).getReg()]; + Node->parent.setInt(Node->parent.getInt() | Node::kPHIIsolatedFlag); +} + +void StrongPHIElimination::PartitionRegisters(MachineFunction& MF) { for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { - MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); - while (BBI != BBE && BBI->isPHI()) { - MachineInstr* PHI = BBI; - ++BBI; - LI->RemoveMachineInstrFromMaps(PHI); - PHI->eraseFromParent(); - Changed = true; + for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); + BBI != BBE && BBI->isPHI(); ++BBI) { + unsigned DestReg = BBI->getOperand(0).getReg(); + addReg(DestReg); + + for (unsigned i = 1; i < BBI->getNumOperands(); i += 2) { + unsigned SrcReg = BBI->getOperand(i).getReg(); + addReg(SrcReg); + unionRegs(DestReg, SrcReg); + } } } +} - LI->renumber(); - MF.verify(this); +/// SplitInterferencesForBasicBlock - traverses a basic block, splitting any +/// interferences found between registers in the same congruence class. It +/// takes two DenseMaps as arguments that it also updates: +/// +/// 1) CurrentDominatingParent, which maps a color to the register in that +/// congruence class whose definition was most recently seen. +/// +/// 2) ImmediateDominatingParent, which maps a register to the register in the +/// same congruence class that most immediately dominates it. +/// +/// This function assumes that it is being called in a depth-first traversal +/// of the dominator tree. +/// +/// The algorithm used here is a generalization of the dominance-based SSA test +/// for two variables. If there are variables a_1, ..., a_n such that +/// +/// def(a_1) dom ... dom def(a_n), +/// +/// then we can test for an interference between any two a_i by only using O(n) +/// interference tests between pairs of variables. If i < j and a_i and a_j +/// interfere, then a_i is alive at def(a_j), so it is also alive at def(a_i+1). +/// Thus, in order to test for an interference involving a_i, we need only check +/// for a potential interference with a_i+1. +/// +/// This method can be generalized to arbitrary sets of variables by performing +/// a depth-first traversal of the dominator tree. As we traverse down a branch +/// of the dominator tree, we keep track of the current dominating variable and +/// only perform an interference test with that variable. However, when we go to +/// another branch of the dominator tree, the definition of the current dominating +/// variable may no longer dominate the current block. In order to correct this, +/// we need to use a stack of past choices of the current dominating variable +/// and pop from this stack until we find a variable whose definition actually +/// dominates the current block. +/// +/// There will be one push on this stack for each variable that has become the +/// current dominating variable, so instead of using an explicit stack we can +/// simply associate the previous choice for a current dominating variable with +/// the new choice. This works better in our implementation, where we test for +/// interference in multiple distinct sets at once. +void +StrongPHIElimination::SplitInterferencesForBasicBlock( + MachineBasicBlock& MBB, + DenseMap& CurrentDominatingParent, + DenseMap& ImmediateDominatingParent) { + for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end(); + BBI != BBE; ++BBI) { + for (unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) { + MachineOperand& MO = BBI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) + continue; + + unsigned DestReg = MO.getReg(); + if (!DestReg || !TargetRegisterInfo::isVirtualRegister(DestReg)) + continue; + + // If the virtual register being defined is not used in any PHI or has + // already been isolated, then there are no more interferences to check. + unsigned DestColor = getRegColor(DestReg); + if (!DestColor) + continue; + + // The input to this pass sometimes is not in SSA form in every basic + // block, as some virtual registers have redefinitions. We could eliminate + // this by fixing the passes that generate the non-SSA code, or we could + // handle it here by tracking defining machine instructions rather than + // virtual registers. For now, we just handle the situation conservatively + // in a way that will possibly lead to false interferences. + unsigned NewParent = CurrentDominatingParent[DestColor]; + if (NewParent == DestReg) + continue; + + // Pop registers from the stack represented by ImmediateDominatingParent + // until we find a parent that dominates the current instruction. + while (NewParent && (!DT->dominates(MRI->getVRegDef(NewParent), BBI) + || !getRegColor(NewParent))) + NewParent = ImmediateDominatingParent[NewParent]; + + // If NewParent is nonzero, then its definition dominates the current + // instruction, so it is only necessary to check for the liveness of + // NewParent in order to check for an interference. + if (NewParent + && LI->getInterval(NewParent).liveAt(LI->getInstructionIndex(BBI))) { + // If there is an interference, always isolate the new register. This + // could be improved by using a heuristic that decides which of the two + // registers to isolate. + isolateReg(DestReg); + CurrentDominatingParent[DestColor] = NewParent; + } else { + // If there is no interference, update ImmediateDominatingParent and set + // the CurrentDominatingParent for this color to the current register. + ImmediateDominatingParent[DestReg] = NewParent; + CurrentDominatingParent[DestColor] = DestReg; + } + } + } - InsertedCopies.clear(); + // We now walk the PHIs in successor blocks and check for interferences. This + // is necesary because the use of a PHI's operands are logically contained in + // the predecessor block. The def of a PHI's destination register is processed + // along with the other defs in a basic block. + + // The map CurrentPHIForColor maps a color to a pair of a MachineInstr* and a + // virtual register, which is the operand of that PHI corresponding to the + // current basic block. + // FIXME: This should use a container that doesn't always perform heap + // allocation. + DenseMap > CurrentPHIForColor; + + for (MachineBasicBlock::succ_iterator SI = MBB.succ_begin(), + SE = MBB.succ_end(); SI != SE; ++SI) { + for (MachineBasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); + BBI != BBE && BBI->isPHI(); ++BBI) { + MachineInstr* PHI = BBI; - return Changed; + // If a PHI is already isolated, either by being isolated directly or + // having all of its operands isolated, ignore it. + unsigned Color = getPHIColor(PHI); + if (!Color) + continue; + + // Find the index of the PHI operand that corresponds to this basic block. + unsigned PredIndex; + for (PredIndex = 1; PredIndex < PHI->getNumOperands(); PredIndex += 2) { + if (PHI->getOperand(PredIndex + 1).getMBB() == &MBB) + break; + } + assert(PredIndex < PHI->getNumOperands()); + unsigned PredOperandReg = PHI->getOperand(PredIndex).getReg(); + + // Pop registers from the stack represented by ImmediateDominatingParent + // until we find a parent that dominates the current instruction. + unsigned NewParent = CurrentDominatingParent[Color]; + while (NewParent + && (!DT->dominates(MRI->getVRegDef(NewParent)->getParent(), &MBB) + || !getRegColor(NewParent))) + NewParent = ImmediateDominatingParent[NewParent]; + CurrentDominatingParent[Color] = NewParent; + + // If there is an interference with a register, always isolate the + // register rather than the PHI. It is also possible to isolate the + // PHI, but that introduces copies for all of the registers involved + // in that PHI. + if (NewParent && LI->isLiveOutOfMBB(LI->getInterval(NewParent), &MBB) + && NewParent != PredOperandReg) + isolateReg(NewParent); + + std::pair CurrentPHI = CurrentPHIForColor[Color]; + + // If two PHIs have the same operand from every shared predecessor, then + // they don't actually interfere. Otherwise, isolate the current PHI. This + // could possibly be improved, e.g. we could isolate the PHI with the + // fewest operands. + if (CurrentPHI.first && CurrentPHI.second != PredOperandReg) + isolatePHI(PHI); + else + CurrentPHIForColor[Color] = std::make_pair(PHI, PredOperandReg); + } + } } void StrongPHIElimination::InsertCopiesForPHI(MachineInstr* PHI, MachineBasicBlock* MBB) { assert(PHI->isPHI()); + unsigned PHIColor = getPHIColor(PHI); + + for (unsigned i = 1; i < PHI->getNumOperands(); i += 2) { + MachineOperand& SrcMO = PHI->getOperand(i); + + // If a source is defined by an implicit def, there is no need to insert a + // copy in the predecessor. + if (SrcMO.isUndef()) + continue; + + unsigned SrcReg = SrcMO.getReg(); + assert(TargetRegisterInfo::isVirtualRegister(SrcReg) && + "Machine PHI Operands must all be virtual registers!"); + + MachineBasicBlock* PredBB = PHI->getOperand(i + 1).getMBB(); + unsigned SrcColor = getRegColor(SrcReg); + + // If neither the PHI nor the operand were isolated, then we only need to + // set the phi-kill flag on the VNInfo at this PHI. + if (PHIColor && SrcColor == PHIColor) { + LiveInterval& SrcInterval = LI->getInterval(SrcReg); + SlotIndex PredIndex = LI->getMBBEndIdx(PredBB); + VNInfo* SrcVNI = SrcInterval.getVNInfoAt(PredIndex.getPrevIndex()); + assert(SrcVNI); + SrcVNI->setHasPHIKill(true); + continue; + } + + unsigned CopyReg = 0; + if (PHIColor) { + SrcCopyMap::const_iterator I + = InsertedSrcCopyMap.find(std::make_pair(PredBB, PHIColor)); + CopyReg + = I != InsertedSrcCopyMap.end() ? I->second->getOperand(0).getReg() : 0; + } + + if (!CopyReg) { + const TargetRegisterClass* RC = MRI->getRegClass(SrcReg); + CopyReg = MRI->createVirtualRegister(RC); + + MachineBasicBlock::iterator + CopyInsertPoint = findPHICopyInsertPoint(PredBB, MBB, SrcReg); + unsigned SrcSubReg = SrcMO.getSubReg(); + MachineInstr* CopyInstr = BuildMI(*PredBB, + CopyInsertPoint, + PHI->getDebugLoc(), + TII->get(TargetOpcode::COPY), + CopyReg).addReg(SrcReg, 0, SrcSubReg); + LI->InsertMachineInstrInMaps(CopyInstr); + + // addLiveRangeToEndOfBlock() also adds the phikill flag to the VNInfo for + // the newly added range. + LI->addLiveRangeToEndOfBlock(CopyReg, CopyInstr); + InsertedSrcCopySet.insert(std::make_pair(PredBB, SrcReg)); + + addReg(CopyReg); + if (PHIColor) { + unionRegs(PHIColor, CopyReg); + assert(getRegColor(CopyReg) != CopyReg); + } else { + PHIColor = CopyReg; + assert(getRegColor(CopyReg) == CopyReg); + } + + if (!InsertedSrcCopyMap.count(std::make_pair(PredBB, PHIColor))) + InsertedSrcCopyMap[std::make_pair(PredBB, PHIColor)] = CopyInstr; + } + + SrcMO.setReg(CopyReg); + + // If SrcReg is not live beyond the PHI, trim its interval so that it is no + // longer live-in to MBB. Note that SrcReg may appear in other PHIs that are + // processed later, but this is still correct to do at this point because we + // never rely on LiveIntervals being correct while inserting copies. + // FIXME: Should this just count uses at PHIs like the normal PHIElimination + // pass does? + LiveInterval& SrcLI = LI->getInterval(SrcReg); + SlotIndex MBBStartIndex = LI->getMBBStartIdx(MBB); + SlotIndex PHIIndex = LI->getInstructionIndex(PHI); + SlotIndex NextInstrIndex = PHIIndex.getNextIndex(); + if (SrcLI.liveAt(MBBStartIndex) && SrcLI.expiredAt(NextInstrIndex)) + SrcLI.removeRange(MBBStartIndex, PHIIndex, true); + } + unsigned DestReg = PHI->getOperand(0).getReg(); + unsigned DestColor = getRegColor(DestReg); + + if (PHIColor && DestColor == PHIColor) { + LiveInterval& DestLI = LI->getInterval(DestReg); + + // Set the phi-def flag for the VN at this PHI. + SlotIndex PHIIndex = LI->getInstructionIndex(PHI); + VNInfo* DestVNI = DestLI.getVNInfoAt(PHIIndex.getDefIndex()); + assert(DestVNI); + DestVNI->setIsPHIDef(true); + + // Prior to PHI elimination, the live ranges of PHIs begin at their defining + // instruction. After PHI elimination, PHI instructions are replaced by VNs + // with the phi-def flag set, and the live ranges of these VNs start at the + // beginning of the basic block. + SlotIndex MBBStartIndex = LI->getMBBStartIdx(MBB); + DestVNI->def = MBBStartIndex; + DestLI.addRange(LiveRange(MBBStartIndex, + PHIIndex.getDefIndex(), + DestVNI)); + return; + } const TargetRegisterClass* RC = MRI->getRegClass(DestReg); unsigned CopyReg = MRI->createVirtualRegister(RC); @@ -161,7 +705,7 @@ TII->get(TargetOpcode::COPY), DestReg).addReg(CopyReg); LI->InsertMachineInstrInMaps(CopyInstr); - CopyInstr->getOperand(1).setIsKill(true); + PHI->getOperand(0).setReg(CopyReg); // Add the region from the beginning of MBB to the copy instruction to // CopyReg's live interval, and give the VNInfo the phidef flag. @@ -186,53 +730,35 @@ assert(DestVNI); DestVNI->def = DestCopyIndex.getDefIndex(); - SmallPtrSet MBBsInsertedInto; - for (unsigned i = 1; i < PHI->getNumOperands(); i += 2) { - MachineOperand& SrcMO = PHI->getOperand(i); - - // If a source is defined by an implicit def, there is no need to insert a - // copy in the predecessor. - if (SrcMO.isUndef()) - continue; - - unsigned SrcReg = SrcMO.getReg(); - unsigned SrcSubReg = SrcMO.getSubReg(); - - assert(TargetRegisterInfo::isVirtualRegister(SrcReg) && - "Machine PHI Operands must all be virtual registers!"); - - MachineBasicBlock* PredBB = PHI->getOperand(i + 1).getMBB(); - - // A copy may have already been inserted in the predecessor in the case of a - // block with multiple incoming edges. - if (!MBBsInsertedInto.insert(PredBB)) - continue; + InsertedDestCopies[CopyReg] = CopyInstr; +} - MachineBasicBlock::iterator - CopyInsertPoint = findPHICopyInsertPoint(PredBB, MBB, SrcReg); - MachineInstr* CopyInstr = BuildMI(*PredBB, - CopyInsertPoint, - PHI->getDebugLoc(), - TII->get(TargetOpcode::COPY), - CopyReg).addReg(SrcReg, 0, SrcSubReg); - LI->InsertMachineInstrInMaps(CopyInstr); - - // addLiveRangeToEndOfBlock() also adds the phikill flag to the VNInfo for - // the newly added range. - LI->addLiveRangeToEndOfBlock(CopyReg, CopyInstr); - InsertedCopies.insert(std::make_pair(PredBB, SrcReg)); +void StrongPHIElimination::MergeLIsAndRename(unsigned Reg, unsigned NewReg) { + if (Reg == NewReg) + return; + + LiveInterval& OldLI = LI->getInterval(Reg); + LiveInterval& NewLI = LI->getInterval(NewReg); + + // Merge the live ranges of the two registers. + DenseMap VNMap; + for (LiveInterval::iterator LRI = OldLI.begin(), LRE = OldLI.end(); + LRI != LRE; ++LRI) { + LiveRange OldLR = *LRI; + VNInfo* OldVN = OldLR.valno; + + VNInfo*& NewVN = VNMap[OldVN]; + if (!NewVN) { + NewVN = NewLI.createValueCopy(OldVN, LI->getVNInfoAllocator()); + VNMap[OldVN] = NewVN; + } - // If SrcReg is not live beyond the PHI, trim its interval so that it is no - // longer live-in to MBB. Note that SrcReg may appear in other PHIs that are - // processed later, but this is still correct to do at this point because we - // never rely on LiveIntervals being correct while inserting copies. - // FIXME: Should this just count uses at PHIs like the normal PHIElimination - // pass does? - LiveInterval& SrcLI = LI->getInterval(SrcReg); - SlotIndex MBBStartIndex = LI->getMBBStartIdx(MBB); - SlotIndex PHIIndex = LI->getInstructionIndex(PHI); - SlotIndex NextInstrIndex = PHIIndex.getNextIndex(); - if (SrcLI.liveAt(MBBStartIndex) && SrcLI.expiredAt(NextInstrIndex)) - SrcLI.removeRange(MBBStartIndex, PHIIndex, true); + LiveRange LR(OldLR.start, OldLR.end, NewVN); + NewLI.addRange(LR); } + + // Remove the LiveInterval for the register being renamed and replace all + // of its defs and uses with the new register. + LI->removeInterval(Reg); + MRI->replaceRegWith(Reg, NewReg); } From daniel at zuster.org Mon Dec 27 08:49:49 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 27 Dec 2010 14:49:49 -0000 Subject: [llvm-commits] [llvm] r122583 - in /llvm/trunk: lib/MC/MachObjectWriter.cpp test/MC/MachO/darwin-Thumb-reloc.s Message-ID: <20101227144949.4B15B2A6C12C@llvm.org> Author: ddunbar Date: Mon Dec 27 08:49:49 2010 New Revision: 122583 URL: http://llvm.org/viewvc/llvm-project?rev=122583&view=rev Log: MC/Mach-O/Thumb: Select appropriate relocation types for Thumb. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122583&r1=122582&r2=122583&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Mon Dec 27 08:49:49 2010 @@ -820,9 +820,9 @@ Relocations[Fragment->getParent()].push_back(MRE); } - static bool getARMFixupKindMachOInfo(unsigned Kind, bool &Is24BitBranch, + static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, unsigned &Log2Size) { - Is24BitBranch = false; + RelocType = unsigned(macho::RIT_Vanilla); Log2Size = ~0U; switch (Kind) { @@ -847,21 +847,24 @@ case ARM::fixup_arm_pcrel_10: case ARM::fixup_arm_adr_pcrel_12: case ARM::fixup_arm_branch: - Is24BitBranch = true; + RelocType = unsigned(macho::RIT_ARM_Branch24Bit); // Report as 'long', even though that is not quite accurate. Log2Size = llvm::Log2_32(4); return true; // Handle Thumb branches. case ARM::fixup_arm_thumb_br: + RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit); Log2Size = llvm::Log2_32(2); return true; case ARM::fixup_arm_thumb_bl: + RelocType = unsigned(macho::RIT_ARM_ThumbBranch32Bit); Log2Size = llvm::Log2_32(4); return true; case ARM::fixup_arm_thumb_blx: + RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit); // Report as 'long', even though that is not quite accurate. Log2Size = llvm::Log2_32(4); return true; @@ -872,8 +875,8 @@ MCValue Target, uint64_t &FixedValue) { unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); unsigned Log2Size; - bool Is24BitBranch; - if (!getARMFixupKindMachOInfo(Fixup.getKind(), Is24BitBranch, Log2Size)) { + unsigned RelocType = macho::RIT_Vanilla; + if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) { report_fatal_error("unknown ARM fixup kind!"); return; } @@ -896,7 +899,7 @@ // // Is this right for ARM? uint32_t Offset = Target.getConstant(); - if (IsPCRel && !Is24BitBranch) + if (IsPCRel && RelocType == macho::RIT_Vanilla) Offset += 1 << Log2Size; if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) return RecordARMScatteredRelocation(Asm, Layout, Fragment, Fixup, @@ -940,9 +943,8 @@ if (IsPCRel) FixedValue -= getSectionAddress(Fragment->getParent()); - // Determine the appropriate type based on the fixup kind. - Type = Is24BitBranch ? (unsigned)macho::RIT_ARM_Branch24Bit : - (unsigned)macho::RIT_Vanilla; + // The type is determined by the fixup kind. + Type = RelocType; } // struct relocation_info (8 bytes) Modified: llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s?rev=122583&r1=122582&r2=122583&view=diff ============================================================================== --- llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s (original) +++ llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s Mon Dec 27 08:49:49 2010 @@ -64,7 +64,7 @@ @ CHECK: ('word-1', 0x0)), @ CHECK: # Relocation 2 @ CHECK: (('word-0', 0x0), -@ CHECK-FIXME: ('word-1', 0x6d000001)), +@ CHECK: ('word-1', 0x6d000001)), @ CHECK: ]) @ CHECK-FIXME: ('_section_data', 'fff7feef 04000000') @ CHECK: # Section 1 From rafael.espindola at gmail.com Mon Dec 27 09:56:22 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 27 Dec 2010 15:56:22 -0000 Subject: [llvm-commits] [llvm] r122584 - in /llvm/trunk: include/llvm/MC/MCDwarf.h include/llvm/MC/MCStreamer.h lib/MC/MCAsmStreamer.cpp lib/MC/MCDwarf.cpp lib/MC/MCParser/AsmParser.cpp lib/MC/MCStreamer.cpp test/MC/ELF/cfi.s Message-ID: <20101227155623.0FAFC2A6C12C@llvm.org> Author: rafael Date: Mon Dec 27 09:56:22 2010 New Revision: 122584 URL: http://llvm.org/viewvc/llvm-project?rev=122584&view=rev Log: Add support for .cfi_lsda. Modified: llvm/trunk/include/llvm/MC/MCDwarf.h llvm/trunk/include/llvm/MC/MCStreamer.h llvm/trunk/lib/MC/MCAsmStreamer.cpp llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCParser/AsmParser.cpp llvm/trunk/lib/MC/MCStreamer.cpp llvm/trunk/test/MC/ELF/cfi.s Modified: llvm/trunk/include/llvm/MC/MCDwarf.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=122584&r1=122583&r2=122584&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCDwarf.h (original) +++ llvm/trunk/include/llvm/MC/MCDwarf.h Mon Dec 27 09:56:22 2010 @@ -232,6 +232,7 @@ const MCSymbol *Personality; const MCSymbol *Lsda; unsigned PersonalityEncoding; + unsigned LsdaEncoding; }; class MCDwarfFrameEmitter { Modified: llvm/trunk/include/llvm/MC/MCStreamer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=122584&r1=122583&r2=122584&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCStreamer.h (original) +++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Dec 27 09:56:22 2010 @@ -396,7 +396,7 @@ virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); virtual bool EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); - virtual bool EmitCFILsda(const MCSymbol *Sym); + virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); /// EmitInstruction - Emit the given @p Instruction into the current /// section. Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=122584&r1=122583&r2=122584&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Mon Dec 27 09:56:22 2010 @@ -190,7 +190,7 @@ virtual bool EmitCFIDefCfaRegister(int64_t Register); virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); virtual bool EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); - virtual bool EmitCFILsda(const MCSymbol *Sym); + virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); virtual void EmitInstruction(const MCInst &Inst); @@ -769,11 +769,11 @@ return false; } -bool MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym) { - if (this->MCStreamer::EmitCFILsda(Sym)) +bool MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { + if (this->MCStreamer::EmitCFILsda(Sym, Encoding)) return true; - OS << ".cfi_lsda 0, " << *Sym; + OS << ".cfi_lsda " << Encoding << ", " << *Sym; EmitEOL(); return false; Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122584&r1=122583&r2=122584&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Mon Dec 27 09:56:22 2010 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/FoldingSet.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCAssembler.h" @@ -508,9 +509,53 @@ } } +static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, + unsigned symbolEncoding) { + MCContext &context = streamer.getContext(); + const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); + unsigned format = symbolEncoding & 0x0f; + unsigned application = symbolEncoding & 0xf0; + unsigned size; + switch (format) { + default: + assert(0 && "Unknown Encoding"); + break; + case dwarf::DW_EH_PE_absptr: + case dwarf::DW_EH_PE_signed: + size = asmInfo.getPointerSize(); + break; + case dwarf::DW_EH_PE_udata2: + case dwarf::DW_EH_PE_sdata2: + size = 2; + break; + case dwarf::DW_EH_PE_udata4: + case dwarf::DW_EH_PE_sdata4: + size = 4; + break; + case dwarf::DW_EH_PE_udata8: + case dwarf::DW_EH_PE_sdata8: + size = 8; + break; + } + switch (application) { + default: + assert(0 && "Unknown Encoding"); + break; + case 0: + case dwarf::DW_EH_PE_indirect: + streamer.EmitSymbolValue(&symbol, size); + break; + case dwarf::DW_EH_PE_pcrel: + streamer.EmitPCRelSymbolValue(&symbol, size); + break; + } +} + static const MCSymbol &EmitCIE(MCStreamer &streamer, const MCSymbol *personality, - unsigned personalityEncoding) { + unsigned personalityEncoding, + const MCSymbol *lsda, + unsigned lsdaEncoding) { MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); const MCSection §ion = *asmInfo.getEHFrameSection(); @@ -535,6 +580,8 @@ Augmentation += "z"; if (personality) Augmentation += "P"; + if (lsda) + Augmentation += "L"; Augmentation += "R"; streamer.EmitBytes(Augmentation.str(), 0); streamer.EmitIntValue(0, 1); @@ -562,42 +609,11 @@ // Personality Encoding streamer.EmitIntValue(personalityEncoding, 1); // Personality - unsigned format = personalityEncoding & 0x0f; - unsigned application = personalityEncoding & 0xf0; - unsigned size; - switch (format) { - default: - assert(0 && "Unknown Encoding"); - break; - case dwarf::DW_EH_PE_absptr: - case dwarf::DW_EH_PE_signed: - size = asmInfo.getPointerSize(); - break; - case dwarf::DW_EH_PE_udata2: - case dwarf::DW_EH_PE_sdata2: - size = 2; - break; - case dwarf::DW_EH_PE_udata4: - case dwarf::DW_EH_PE_sdata4: - size = 4; - break; - case dwarf::DW_EH_PE_udata8: - case dwarf::DW_EH_PE_sdata8: - size = 8; - break; - } - switch (application) { - default: - assert(0 && "Unknown Encoding"); - break; - case 0: - case dwarf::DW_EH_PE_indirect: - streamer.EmitSymbolValue(personality, size); - break; - case dwarf::DW_EH_PE_pcrel: - streamer.EmitPCRelSymbolValue(personality, size); - break; - } + EmitSymbol(streamer, *personality, personalityEncoding); + } + if (lsda) { + // LSDA Encoding + streamer.EmitIntValue(lsdaEncoding, 1); } // Encoding of the FDE pointers streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1); @@ -619,8 +635,9 @@ static MCSymbol *EmitFDE(MCStreamer &streamer, const MCSymbol &cieStart, const MCDwarfFrameInfo &frame) { - MCSymbol *fdeStart = streamer.getContext().CreateTempSymbol(); - MCSymbol *fdeEnd = streamer.getContext().CreateTempSymbol(); + MCContext &context = streamer.getContext(); + MCSymbol *fdeStart = context.CreateTempSymbol(); + MCSymbol *fdeEnd = context.CreateTempSymbol(); // Length const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0); @@ -641,9 +658,18 @@ streamer.EmitValue(Range, 4); // Augmentation Data Length - streamer.EmitULEB128IntValue(0); + MCSymbol *augmentationStart = streamer.getContext().CreateTempSymbol(); + MCSymbol *augmentationEnd = streamer.getContext().CreateTempSymbol(); + const MCExpr *augmentationLength = MakeStartMinusEndExpr(streamer, + *augmentationStart, + *augmentationEnd, 0); + streamer.EmitULEB128Value(augmentationLength); // Augmentation Data + streamer.EmitLabel(augmentationStart); + if (frame.Lsda) + EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding); + streamer.EmitLabel(augmentationEnd); // Call Frame Instructions // Padding @@ -652,20 +678,63 @@ return fdeEnd; } +struct CIEKey { + static const CIEKey EmptyKey; + static const CIEKey TombstoneKey; + + CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_, + unsigned LsdaEncoding_) : Personality(Personality_), + PersonalityEncoding(PersonalityEncoding_), + LsdaEncoding(LsdaEncoding_) { + } + const MCSymbol* Personality; + unsigned PersonalityEncoding; + unsigned LsdaEncoding; +}; + +const CIEKey CIEKey::EmptyKey(0, 0, -1); +const CIEKey CIEKey::TombstoneKey(0, -1, 0); + +namespace llvm { + template <> + struct DenseMapInfo { + static CIEKey getEmptyKey() { + return CIEKey::EmptyKey; + } + static CIEKey getTombstoneKey() { + return CIEKey::TombstoneKey; + } + static unsigned getHashValue(const CIEKey &Key) { + FoldingSetNodeID ID; + ID.AddPointer(Key.Personality); + ID.AddInteger(Key.PersonalityEncoding); + ID.AddInteger(Key.LsdaEncoding); + return ID.ComputeHash(); + } + static bool isEqual(const CIEKey &LHS, + const CIEKey &RHS) { + return LHS.Personality == RHS.Personality && + LHS.PersonalityEncoding == RHS.PersonalityEncoding && + LHS.LsdaEncoding == RHS.LsdaEncoding; + } + }; +} + void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) { const MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); MCSymbol *fdeEnd = NULL; - typedef std::pair personalityKey; - DenseMap personalities; + DenseMap CIEStarts; for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); - personalityKey key(frame.Personality, frame.PersonalityEncoding); - const MCSymbol *&cieStart = personalities[key]; + CIEKey key(frame.Personality, frame.PersonalityEncoding, + frame.LsdaEncoding); + const MCSymbol *&cieStart = CIEStarts[key]; if (!cieStart) cieStart = &EmitCIE(streamer, frame.Personality, - frame.PersonalityEncoding); + frame.PersonalityEncoding, frame.Lsda, + frame.LsdaEncoding); fdeEnd = EmitFDE(streamer, *cieStart, frame); if (i != n - 1) streamer.EmitLabel(fdeEnd); Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122584&r1=122583&r2=122584&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Mon Dec 27 09:56:22 2010 @@ -2257,7 +2257,7 @@ return getStreamer().EmitCFIPersonality(Sym, Encoding); else { assert(IDVal == ".cfi_lsda"); - return getStreamer().EmitCFILsda(Sym); + return getStreamer().EmitCFILsda(Sym, Encoding); } } Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122584&r1=122583&r2=122584&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Mon Dec 27 09:56:22 2010 @@ -157,7 +157,7 @@ report_fatal_error("Starting a frame before finishing the previous one!"); return true; } - MCDwarfFrameInfo Frame = {0, 0, 0, 0}; + MCDwarfFrameInfo Frame = {0, 0, 0, 0, 0, 0}; Frame.Begin = getContext().CreateTempSymbol(); EmitLabel(Frame.Begin); FrameInfos.push_back(Frame); @@ -196,10 +196,11 @@ return false; } -bool MCStreamer::EmitCFILsda(const MCSymbol *Sym) { +bool MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { EnsureValidFrame(); MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); CurFrame->Lsda = Sym; + CurFrame->LsdaEncoding = Encoding; return false; } Modified: llvm/trunk/test/MC/ELF/cfi.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi.s?rev=122584&r1=122583&r2=122584&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi.s (original) +++ llvm/trunk/test/MC/ELF/cfi.s Mon Dec 27 09:56:22 2010 @@ -2,23 +2,27 @@ f1: .cfi_startproc + .cfi_lsda 0x3, bar nop .cfi_endproc f2: .cfi_startproc .cfi_personality 0x00, foo + .cfi_lsda 0x3, bar nop .cfi_endproc f3: .cfi_startproc + .cfi_lsda 0x3, bar nop .cfi_endproc f4: .cfi_startproc .cfi_personality 0x00, foo + .cfi_lsda 0x2, bar nop .cfi_endproc @@ -165,12 +169,12 @@ // CHECK-NEXT: ('sh_flags', 0x00000002) // CHECK-NEXT: ('sh_addr', 0x00000000) // CHECK-NEXT: ('sh_offset', 0x00000060) -// CHECK-NEXT: ('sh_size', 0x00000508) +// CHECK-NEXT: ('sh_size', 0x00000538) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000000) -// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 10000000 1c000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a000000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 10000000 64000000 00000000 01000000 00000000 10000000 4c000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04020000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06030000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a040000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 040a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 060b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a0c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a080000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a100000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04120000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06130000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a140000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 041a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 061b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a1c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a180000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a800000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04820000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06830000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a840000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 048a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 068b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a8c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a880000 00000000 00001b0c 07089001 14000000 24000000 00000000 01000000 00000000 00000000') +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a4c52 00017810 02031b0c 07089001 14000000 1c000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000003 1b0c0708 90010000 14000000 28000000 00000000 01000000 04000000 00000000 14000000 70000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000002 1b0c0708 90010000 10000000 28000000 00000000 01000000 02000000 18000000 00000000 017a5052 00017810 04020000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06030000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a040000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 040a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 060b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a0c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a080000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a100000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04120000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06130000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a140000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 041a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 061b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a1c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a180000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a800000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04820000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06830000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a840000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 048a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 068b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a8c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a88000 0 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000') // CHECK-NEXT: ), // CHECK: # Section 0x00000008 @@ -178,8 +182,8 @@ // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000930) -// CHECK-NEXT: ('sh_size', 0x000004c8) +// CHECK-NEXT: ('sh_offset', 0x00000980) +// CHECK-NEXT: ('sh_size', 0x00000540) // CHECK-NEXT: ('sh_link', 0x00000006) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) @@ -192,301 +196,331 @@ // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x0000003e) +// CHECK-NEXT: (('r_offset', 0x00000029) // CHECK-NEXT: ('r_sym', 0x00000020) -// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000002 -// CHECK-NEXT: (('r_offset', 0x00000054) +// CHECK-NEXT: (('r_offset', 0x00000043) +// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000003 +// CHECK-NEXT: (('r_offset', 0x0000005c) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000001) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000003 -// CHECK-NEXT: (('r_offset', 0x00000068) +// CHECK-NEXT: # Relocation 0x00000004 +// CHECK-NEXT: (('r_offset', 0x00000065) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000005 +// CHECK-NEXT: (('r_offset', 0x00000074) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000002) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000004 -// CHECK-NEXT: (('r_offset', 0x0000007c) +// CHECK-NEXT: # Relocation 0x00000006 +// CHECK-NEXT: (('r_offset', 0x0000007d) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000007 +// CHECK-NEXT: (('r_offset', 0x00000097) +// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000008 +// CHECK-NEXT: (('r_offset', 0x000000b0) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000003) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000005 -// CHECK-NEXT: (('r_offset', 0x0000009a) +// CHECK-NEXT: # Relocation 0x00000009 +// CHECK-NEXT: (('r_offset', 0x000000b9) // CHECK-NEXT: ('r_sym', 0x00000020) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000006 -// CHECK-NEXT: (('r_offset', 0x000000ac) +// CHECK-NEXT: # Relocation 0x0000000a +// CHECK-NEXT: (('r_offset', 0x000000ce) +// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_type', 0x0000000c) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000000b +// CHECK-NEXT: (('r_offset', 0x000000e0) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000004) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000007 -// CHECK-NEXT: (('r_offset', 0x000000ca) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x0000000c +// CHECK-NEXT: (('r_offset', 0x000000fe) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000008 -// CHECK-NEXT: (('r_offset', 0x000000dc) +// CHECK-NEXT: # Relocation 0x0000000d +// CHECK-NEXT: (('r_offset', 0x00000110) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000005) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000009 -// CHECK-NEXT: (('r_offset', 0x000000fa) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x0000000e +// CHECK-NEXT: (('r_offset', 0x0000012e) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000a -// CHECK-NEXT: (('r_offset', 0x00000110) +// CHECK-NEXT: # Relocation 0x0000000f +// CHECK-NEXT: (('r_offset', 0x00000144) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000006) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000b -// CHECK-NEXT: (('r_offset', 0x0000012e) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000010 +// CHECK-NEXT: (('r_offset', 0x00000162) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000c -// CHECK-NEXT: (('r_offset', 0x00000140) +// CHECK-NEXT: # Relocation 0x00000011 +// CHECK-NEXT: (('r_offset', 0x00000174) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000007) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000d -// CHECK-NEXT: (('r_offset', 0x0000015e) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000012 +// CHECK-NEXT: (('r_offset', 0x00000192) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000e -// CHECK-NEXT: (('r_offset', 0x00000170) +// CHECK-NEXT: # Relocation 0x00000013 +// CHECK-NEXT: (('r_offset', 0x000001a4) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000008) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000f -// CHECK-NEXT: (('r_offset', 0x0000018e) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000014 +// CHECK-NEXT: (('r_offset', 0x000001c2) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000010 -// CHECK-NEXT: (('r_offset', 0x000001a4) +// CHECK-NEXT: # Relocation 0x00000015 +// CHECK-NEXT: (('r_offset', 0x000001d8) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000009) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000011 -// CHECK-NEXT: (('r_offset', 0x000001c2) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000016 +// CHECK-NEXT: (('r_offset', 0x000001f6) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000012 -// CHECK-NEXT: (('r_offset', 0x000001d8) +// CHECK-NEXT: # Relocation 0x00000017 +// CHECK-NEXT: (('r_offset', 0x0000020c) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000a) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000013 -// CHECK-NEXT: (('r_offset', 0x000001f6) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000018 +// CHECK-NEXT: (('r_offset', 0x0000022a) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000018) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000014 -// CHECK-NEXT: (('r_offset', 0x0000020c) +// CHECK-NEXT: # Relocation 0x00000019 +// CHECK-NEXT: (('r_offset', 0x00000240) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000b) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000015 -// CHECK-NEXT: (('r_offset', 0x0000022a) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x0000001a +// CHECK-NEXT: (('r_offset', 0x0000025e) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000d) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000016 -// CHECK-NEXT: (('r_offset', 0x0000023c) +// CHECK-NEXT: # Relocation 0x0000001b +// CHECK-NEXT: (('r_offset', 0x00000270) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000c) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000017 -// CHECK-NEXT: (('r_offset', 0x0000025a) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x0000001c +// CHECK-NEXT: (('r_offset', 0x0000028e) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000018 -// CHECK-NEXT: (('r_offset', 0x0000026c) +// CHECK-NEXT: # Relocation 0x0000001d +// CHECK-NEXT: (('r_offset', 0x000002a0) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000d) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000019 -// CHECK-NEXT: (('r_offset', 0x0000028a) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x0000001e +// CHECK-NEXT: (('r_offset', 0x000002be) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000018) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001a -// CHECK-NEXT: (('r_offset', 0x000002a0) +// CHECK-NEXT: # Relocation 0x0000001f +// CHECK-NEXT: (('r_offset', 0x000002d4) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000e) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001b -// CHECK-NEXT: (('r_offset', 0x000002be) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000020 +// CHECK-NEXT: (('r_offset', 0x000002f2) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000d) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001c -// CHECK-NEXT: (('r_offset', 0x000002d0) +// CHECK-NEXT: # Relocation 0x00000021 +// CHECK-NEXT: (('r_offset', 0x00000304) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000f) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001d -// CHECK-NEXT: (('r_offset', 0x000002ee) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000022 +// CHECK-NEXT: (('r_offset', 0x00000322) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001e -// CHECK-NEXT: (('r_offset', 0x00000300) +// CHECK-NEXT: # Relocation 0x00000023 +// CHECK-NEXT: (('r_offset', 0x00000334) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000010) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001f -// CHECK-NEXT: (('r_offset', 0x0000031e) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000024 +// CHECK-NEXT: (('r_offset', 0x00000352) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000018) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000020 -// CHECK-NEXT: (('r_offset', 0x00000334) +// CHECK-NEXT: # Relocation 0x00000025 +// CHECK-NEXT: (('r_offset', 0x00000368) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000011) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000021 -// CHECK-NEXT: (('r_offset', 0x00000352) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000026 +// CHECK-NEXT: (('r_offset', 0x00000386) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000018) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000022 -// CHECK-NEXT: (('r_offset', 0x00000368) +// CHECK-NEXT: # Relocation 0x00000027 +// CHECK-NEXT: (('r_offset', 0x0000039c) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000012) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000023 -// CHECK-NEXT: (('r_offset', 0x00000386) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000028 +// CHECK-NEXT: (('r_offset', 0x000003ba) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000024 -// CHECK-NEXT: (('r_offset', 0x0000039c) +// CHECK-NEXT: # Relocation 0x00000029 +// CHECK-NEXT: (('r_offset', 0x000003d0) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000013) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000025 -// CHECK-NEXT: (('r_offset', 0x000003ba) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x0000002a +// CHECK-NEXT: (('r_offset', 0x000003ee) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000026 -// CHECK-NEXT: (('r_offset', 0x000003cc) +// CHECK-NEXT: # Relocation 0x0000002b +// CHECK-NEXT: (('r_offset', 0x00000400) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000014) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000027 -// CHECK-NEXT: (('r_offset', 0x000003ea) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x0000002c +// CHECK-NEXT: (('r_offset', 0x0000041e) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000028 -// CHECK-NEXT: (('r_offset', 0x000003fc) +// CHECK-NEXT: # Relocation 0x0000002d +// CHECK-NEXT: (('r_offset', 0x00000430) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000015) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000029 -// CHECK-NEXT: (('r_offset', 0x0000041a) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x0000002e +// CHECK-NEXT: (('r_offset', 0x0000044e) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002a -// CHECK-NEXT: (('r_offset', 0x00000430) +// CHECK-NEXT: # Relocation 0x0000002f +// CHECK-NEXT: (('r_offset', 0x00000464) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000016) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002b -// CHECK-NEXT: (('r_offset', 0x0000044e) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000030 +// CHECK-NEXT: (('r_offset', 0x00000482) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002c -// CHECK-NEXT: (('r_offset', 0x00000460) +// CHECK-NEXT: # Relocation 0x00000031 +// CHECK-NEXT: (('r_offset', 0x00000494) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000017) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002d -// CHECK-NEXT: (('r_offset', 0x0000047e) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000032 +// CHECK-NEXT: (('r_offset', 0x000004b2) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002e -// CHECK-NEXT: (('r_offset', 0x00000490) +// CHECK-NEXT: # Relocation 0x00000033 +// CHECK-NEXT: (('r_offset', 0x000004c4) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000018) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002f -// CHECK-NEXT: (('r_offset', 0x000004ae) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000034 +// CHECK-NEXT: (('r_offset', 0x000004e2) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000030 -// CHECK-NEXT: (('r_offset', 0x000004c4) +// CHECK-NEXT: # Relocation 0x00000035 +// CHECK-NEXT: (('r_offset', 0x000004f8) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000019) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000031 -// CHECK-NEXT: (('r_offset', 0x000004e2) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: # Relocation 0x00000036 +// CHECK-NEXT: (('r_offset', 0x00000516) +// CHECK-NEXT: ('r_sym', 0x00000021) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000032 -// CHECK-NEXT: (('r_offset', 0x000004f8) +// CHECK-NEXT: # Relocation 0x00000037 +// CHECK-NEXT: (('r_offset', 0x0000052c) // CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000001a) From grosser at fim.uni-passau.de Mon Dec 27 10:45:33 2010 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Mon, 27 Dec 2010 11:45:33 -0500 Subject: [llvm-commits] [PATCH] Two minor LNT improvements Message-ID: <4D18C2AD.6050901@fim.uni-passau.de> Hi, I like to commit those to changes to LNT: * LNT: verify that --cc (and --cxx if provided) are valid paths * LNT: Do not require the gcc extras string to be empty Instead detect any gcc that is not an llvm-gcc. The case that triggered this bug was a gcc with the following version string: gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 It was not detected as a supported compiler, as cc_extra was ' ' instead of the required ''. Now everything is allowed in cc_extra, just llvm-gcc is filtered out and handled separately. Patches attached. OK to commit? Cheers Tobi -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-LNT-Do-not-require-the-gcc-extras-string-to-be-empty.patch Type: text/x-diff Size: 2386 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101227/74a0a872/attachment.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-LNT-verify-that-cc-and-cxx-if-provided-are-valid-pat.patch Type: text/x-diff Size: 1978 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101227/74a0a872/attachment-0001.bin From sabre at nondot.org Mon Dec 27 12:39:08 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 27 Dec 2010 18:39:08 -0000 Subject: [llvm-commits] [llvm] r122585 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20101227183908.4F9612A6C12C@llvm.org> Author: lattner Date: Mon Dec 27 12:39:08 2010 New Revision: 122585 URL: http://llvm.org/viewvc/llvm-project?rev=122585&view=rev Log: fix some issues Frits noticed, add AliasAnalysis as a dependency Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122585&r1=122584&r2=122585&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Mon Dec 27 12:39:08 2010 @@ -15,6 +15,7 @@ #define DEBUG_TYPE "loop-idiom" #include "llvm/Transforms/Scalar.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ScalarEvolutionExpander.h" @@ -59,6 +60,8 @@ AU.addPreservedID(LoopSimplifyID); AU.addRequiredID(LCSSAID); AU.addPreservedID(LCSSAID); + AU.addRequired(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); @@ -73,6 +76,7 @@ INITIALIZE_PASS_DEPENDENCY(LoopSimplify) INITIALIZE_PASS_DEPENDENCY(LCSSA) INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) +INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_END(LoopIdiomRecognize, "loop-idiom", "Recognize loop idioms", false, false) @@ -141,13 +145,15 @@ StoreInst *SI = dyn_cast(I++); if (SI == 0 || SI->isVolatile()) continue; - WeakVH InstPtr; - if (processLoopStore(SI, BECount)) { - // If processing the store invalidated our iterator, start over from the - // head of the loop. - if (InstPtr == 0) - I = BB->begin(); - } + WeakVH InstPtr(SI); + if (!processLoopStore(SI, BECount)) continue; + + MadeChange = true; + + // If processing the store invalidated our iterator, start over from the + // head of the loop. + if (InstPtr == 0) + I = BB->begin(); } return MadeChange; @@ -204,6 +210,10 @@ // would be unsafe to do if there is anything else in the loop that may read // or write to the aliased location. Check for an alias. + // FIXME: Need to get a base pointer that is valid. + // if (LoopCanModRefLocation(SI->getPointerOperand()) + + // FIXME: TODO safety check. // Okay, everything looks good, insert the memset. From clattner at apple.com Mon Dec 27 12:42:56 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 27 Dec 2010 10:42:56 -0800 Subject: [llvm-commits] [llvm] r122576 - in /llvm/trunk: include/llvm/Transforms/Utils/BuildLibCalls.h lib/Transforms/Utils/BuildLibCalls.cpp In-Reply-To: <20101227002532.352D52A6C12C@llvm.org> References: <20101227002532.352D52A6C12C@llvm.org> Message-ID: On Dec 26, 2010, at 4:25 PM, Benjamin Kramer wrote: > Author: d0k > Date: Sun Dec 26 18:25:32 2010 > New Revision: 122576 > > URL: http://llvm.org/viewvc/llvm-project?rev=122576&view=rev > Log: > BuildLibCalls: Nuke EmitMemCpy, EmitMemMove and EmitMemSet. They are dead and superseded by IRBuilder. Nice! -Chris From stoklund at 2pi.dk Mon Dec 27 15:30:03 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 27 Dec 2010 13:30:03 -0800 Subject: [llvm-commits] [llvm] r122581 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp In-Reply-To: <20101227051723.525822A6C12C@llvm.org> References: <20101227051723.525822A6C12C@llvm.org> Message-ID: <9BA8C891-0699-4BA1-A7BD-85875BC7CC10@2pi.dk> On Dec 26, 2010, at 9:17 PM, Cameron Zwarich wrote: > Author: zwarich > Date: Sun Dec 26 23:17:23 2010 > New Revision: 122581 > > URL: http://llvm.org/viewvc/llvm-project?rev=122581&view=rev > Log: > Add knowledge of phi-def and phi-kill valnos to MachineVerifier's predecessor > valno verification. The "Different value live out of predecessor" check is > incorrect in the case of phi-def valnos, so just skip that check for phi-def > valnos and instead check that all of the valnos for predecessors have phi-kill. > Fixes PR8863. Thanks, Cameron! > + if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) { One thing is still missing: In this case, it is also legal for the live interval not to be live out of the predecessor. That can happen if a PHI operand was . /jakob -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101227/d3963ec0/attachment.bin From zwarich at apple.com Mon Dec 27 15:56:40 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 27 Dec 2010 13:56:40 -0800 Subject: [llvm-commits] [llvm] r122581 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp In-Reply-To: <9BA8C891-0699-4BA1-A7BD-85875BC7CC10@2pi.dk> References: <20101227051723.525822A6C12C@llvm.org> <9BA8C891-0699-4BA1-A7BD-85875BC7CC10@2pi.dk> Message-ID: <0DA2AB59-C261-4812-BE75-DC610CA59CAC@apple.com> On Dec 27, 2010, at 1:30 PM, Jakob Stoklund Olesen wrote: >> + if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) { > > One thing is still missing: In this case, it is also legal for the live interval not to be live out of the predecessor. That can happen if a PHI operand was . What's an easy test-case for this? I don't think I saw it trigger on any of the existing tests. Cameron From zwarich at apple.com Mon Dec 27 16:08:42 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 27 Dec 2010 22:08:42 -0000 Subject: [llvm-commits] [llvm] r122586 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101227220842.45C1A2A6C12C@llvm.org> Author: zwarich Date: Mon Dec 27 16:08:42 2010 New Revision: 122586 URL: http://llvm.org/viewvc/llvm-project?rev=122586&view=rev Log: Change an assertion to assert what the code actually relies upon. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122586&r1=122585&r2=122586&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Dec 27 16:08:42 2010 @@ -283,7 +283,7 @@ LiveInterval& DestLI = LI->getInterval(DestReg); LiveInterval& NewLI = LI->getInterval(NewReg); - assert(DestLI.containsOneValue()); + assert(DestLI.ranges.size() == 1); LiveRange* DestLR = DestLI.begin(); VNInfo* NewVNI = NewLI.getVNInfoAt(DestLR->start); if (!NewVNI) { From stoklund at 2pi.dk Mon Dec 27 18:11:50 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 27 Dec 2010 16:11:50 -0800 Subject: [llvm-commits] [llvm] r122581 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp In-Reply-To: <0DA2AB59-C261-4812-BE75-DC610CA59CAC@apple.com> References: <20101227051723.525822A6C12C@llvm.org> <9BA8C891-0699-4BA1-A7BD-85875BC7CC10@2pi.dk> <0DA2AB59-C261-4812-BE75-DC610CA59CAC@apple.com> Message-ID: On Dec 27, 2010, at 1:56 PM, Cameron Zwarich wrote: > On Dec 27, 2010, at 1:30 PM, Jakob Stoklund Olesen wrote: > >>> + if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) { >> >> One thing is still missing: In this case, it is also legal for the live interval not to be live out of the predecessor. That can happen if a PHI operand was . > > What's an easy test-case for this? I don't think I saw it trigger on any of the existing tests. It usually shows up when you are using bugpoint. It tends to insert lots of undefs. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101227/729864ec/attachment.bin From zwarich at apple.com Mon Dec 27 19:43:27 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 27 Dec 2010 17:43:27 -0800 Subject: [llvm-commits] [llvm] r122581 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp In-Reply-To: References: <20101227051723.525822A6C12C@llvm.org> <9BA8C891-0699-4BA1-A7BD-85875BC7CC10@2pi.dk> <0DA2AB59-C261-4812-BE75-DC610CA59CAC@apple.com> Message-ID: <918BD683-B01D-4C80-8ACF-70F8852DD0F5@apple.com> On Dec 27, 2010, at 4:11 PM, Jakob Stoklund Olesen wrote: > > On Dec 27, 2010, at 1:56 PM, Cameron Zwarich wrote: > >> On Dec 27, 2010, at 1:30 PM, Jakob Stoklund Olesen wrote: >> >>>> + if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) { >>> >>> One thing is still missing: In this case, it is also legal for the live interval not to be live out of the predecessor. That can happen if a PHI operand was . >> >> What's an easy test-case for this? I don't think I saw it trigger on any of the existing tests. > > It usually shows up when you are using bugpoint. It tends to insert lots of undefs. There's one in CodeGen/X86/2008-05-21-CoalescerBug.ll, but it never triggers the false error. After phi elimination (either normal or strong), there is no live range or VN for the undef value, so the error is never emitted. If I run the verifier between LiveIntervals and StrongPHIElimination, it does give a false error in checkPHIOps. I could fix that one. Right now, the verifier isn't really meant to run between LiveIntervals and phi elimination, but I should probably go through and fix all of the issues so that works right. Cameron From bigcheesegs at gmail.com Mon Dec 27 19:49:01 2010 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Tue, 28 Dec 2010 01:49:01 -0000 Subject: [llvm-commits] [llvm] r122587 - in /llvm/trunk: include/llvm/Support/FileSystem.h lib/Support/PathV2.cpp Message-ID: <20101228014901.3DD722A6C12C@llvm.org> Author: mspencer Date: Mon Dec 27 19:49:01 2010 New Revision: 122587 URL: http://llvm.org/viewvc/llvm-project?rev=122587&view=rev Log: Support/PathV2: Implement has_magic. Modified: llvm/trunk/include/llvm/Support/FileSystem.h llvm/trunk/lib/Support/PathV2.cpp Modified: llvm/trunk/include/llvm/Support/FileSystem.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileSystem.h?rev=122587&r1=122586&r2=122587&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/FileSystem.h (original) +++ llvm/trunk/include/llvm/Support/FileSystem.h Mon Dec 27 19:49:01 2010 @@ -448,7 +448,7 @@ /// @param magic Byte sequence to compare \a path's first len(magic) bytes to. /// @results errc::success if result has been successfully set, otherwise a /// platform specific error_code. -error_code has_magic(const Twine &path, const Twine &magic); +error_code has_magic(const Twine &path, const Twine &magic, bool &result); /// @brief Get \a path's first \a len bytes. /// Modified: llvm/trunk/lib/Support/PathV2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PathV2.cpp?rev=122587&r1=122586&r2=122587&view=diff ============================================================================== --- llvm/trunk/lib/Support/PathV2.cpp (original) +++ llvm/trunk/lib/Support/PathV2.cpp Mon Dec 27 19:49:01 2010 @@ -15,6 +15,8 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/ErrorHandling.h" #include +#include +#include namespace { using llvm::StringRef; @@ -659,6 +661,42 @@ SymlinkStatus = symlink_st; } +error_code has_magic(const Twine &path, const Twine &magic, bool &result) { + SmallString<128> PathStorage; + SmallString<32> MagicStorage; + StringRef Path = path.toNullTerminatedStringRef(PathStorage); + StringRef Magic = magic.toNullTerminatedStringRef(MagicStorage); + + assert(Magic.size() > 0 && "magic must be non-empty!"); + + SmallString<32> BufferStorage; + BufferStorage.reserve(Magic.size()); + + // Open file. + std::FILE *file = std::fopen(Path.data(), "rb"); + if (file == 0) + return error_code(errno, posix_category()); + int size = ::fread(BufferStorage.data(), 1, Magic.size(), file); + if (size != Magic.size()) { + int error = errno; + bool eof = std::feof(file) != 0; + std::fclose(file); + if (eof) { + // EOF, return false. + result = false; + return success; + } + return error_code(error, posix_category()); + } + std::fclose(file); + + if (std::memcmp(BufferStorage.data(), Magic.data(), Magic.size()) != 0) + result = false; + else + result = true; + return success; +} + } // end namespace fs } // end namespace sys } // end namespace llvm From bigcheesegs at gmail.com Mon Dec 27 19:49:10 2010 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Tue, 28 Dec 2010 01:49:10 -0000 Subject: [llvm-commits] [llvm] r122588 - /llvm/trunk/include/llvm/Support/PathV1.h Message-ID: <20101228014910.2F6D12A6C12C@llvm.org> Author: mspencer Date: Mon Dec 27 19:49:10 2010 New Revision: 122588 URL: http://llvm.org/viewvc/llvm-project?rev=122588&view=rev Log: Fix typo. Modified: llvm/trunk/include/llvm/Support/PathV1.h Modified: llvm/trunk/include/llvm/Support/PathV1.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PathV1.h?rev=122588&r1=122587&r2=122588&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PathV1.h (original) +++ llvm/trunk/include/llvm/Support/PathV1.h Mon Dec 27 19:49:10 2010 @@ -21,7 +21,7 @@ #include #include -#define LLVMV_PATH_DEPRECATED_MSG(replacement) \ +#define LLVM_PATH_DEPRECATED_MSG(replacement) \ "PathV1 has been deprecated and will be removed as soon as all LLVM and" \ " Clang clients have been moved over to PathV2. Please use `" #replacement \ "` from PathV2 instead." @@ -99,7 +99,7 @@ /// what the root directory is or none at all. In that case, a consistent /// default root directory will be used. LLVM_ATTRIBUTE_DEPRECATED(static Path GetRootDirectory(), - LLVMV_PATH_DEPRECATED_MSG(NOTHING)); + LLVM_PATH_DEPRECATED_MSG(NOTHING)); /// Construct a path to a unique temporary directory that is created in /// a "standard" place for the operating system. The directory is @@ -268,7 +268,7 @@ /// @brief Returns the last component of the path name. LLVM_ATTRIBUTE_DEPRECATED( StringRef getLast() const, - LLVMV_PATH_DEPRECATED_MSG(path::filename)); + LLVM_PATH_DEPRECATED_MSG(path::filename)); /// This function strips off the path and suffix of the file or directory /// name and returns just the basename. For example /a/foo.bar would cause @@ -276,12 +276,12 @@ /// @returns StringRef containing the basename of the path /// @brief Get the base name of the path LLVM_ATTRIBUTE_DEPRECATED(StringRef getBasename() const, - LLVMV_PATH_DEPRECATED_MSG(path::stem)); + LLVM_PATH_DEPRECATED_MSG(path::stem)); /// This function strips off the suffix of the path beginning with the /// path separator ('/' on Unix, '\' on Windows) and returns the result. LLVM_ATTRIBUTE_DEPRECATED(StringRef getDirname() const, - LLVMV_PATH_DEPRECATED_MSG(path::parent_path)); + LLVM_PATH_DEPRECATED_MSG(path::parent_path)); /// This function strips off the path and basename(up to and /// including the last dot) of the file or directory name and @@ -290,7 +290,7 @@ /// @returns StringRef containing the suffix of the path /// @brief Get the suffix of the path LLVM_ATTRIBUTE_DEPRECATED(StringRef getSuffix() const, - LLVMV_PATH_DEPRECATED_MSG(path::extension)); + LLVM_PATH_DEPRECATED_MSG(path::extension)); /// Obtain a 'C' string for the path name. /// @returns a 'C' string containing the path name. @@ -321,7 +321,7 @@ /// @brief Determine if the path is absolute. LLVM_ATTRIBUTE_DEPRECATED( static bool isAbsolute(const char *NameStart, unsigned NameLen), - LLVMV_PATH_DEPRECATED_MSG(path::is_absolute)); + LLVM_PATH_DEPRECATED_MSG(path::is_absolute)); /// This function opens the file associated with the path name provided by /// the Path object and reads its magic number. If the magic number at the @@ -497,7 +497,7 @@ /// current working directory if necessary. LLVM_ATTRIBUTE_DEPRECATED( void makeAbsolute(), - LLVMV_PATH_DEPRECATED_MSG(fs::make_absolute)); + LLVM_PATH_DEPRECATED_MSG(fs::make_absolute)); /// @} /// @name Disk Mutators @@ -629,7 +629,7 @@ /// efficiency. First, the file status requires additional space and the space /// is incorporated directly into PathWithStatus without an additional malloc. /// Second, obtaining status information is an expensive operation on most - /// operating systems so we want to be careful and explicity about where we + /// operating systems so we want to be careful and explicit about where we /// allow this operation in LLVM. /// @brief Path with file status class. class PathWithStatus : public Path { From bigcheesegs at gmail.com Mon Dec 27 19:49:21 2010 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Tue, 28 Dec 2010 01:49:21 -0000 Subject: [llvm-commits] [llvm] r122589 - in /llvm/trunk: include/llvm/Support/PathV1.h lib/Support/Path.cpp Message-ID: <20101228014921.C95742A6C12C@llvm.org> Author: mspencer Date: Mon Dec 27 19:49:21 2010 New Revision: 122589 URL: http://llvm.org/viewvc/llvm-project?rev=122589&view=rev Log: Support/Path: Deprecate Path::hasMagicNumber and replace all uses with fs::has_magic. Modified: llvm/trunk/include/llvm/Support/PathV1.h llvm/trunk/lib/Support/Path.cpp Modified: llvm/trunk/include/llvm/Support/PathV1.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PathV1.h?rev=122589&r1=122588&r2=122589&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PathV1.h (original) +++ llvm/trunk/include/llvm/Support/PathV1.h Mon Dec 27 19:49:21 2010 @@ -329,7 +329,8 @@ /// cases (file not found, file not accessible, etc.) it returns false. /// @returns true if the magic number of the file matches \p magic. /// @brief Determine if file has a specific magic number - bool hasMagicNumber(StringRef magic) const; + LLVM_ATTRIBUTE_DEPRECATED(bool hasMagicNumber(StringRef magic) const, + LLVM_PATH_DEPRECATED_MSG(fs::has_magic)); /// This function retrieves the first \p len bytes of the file associated /// with \p this. These bytes are returned as the "magic number" in the Modified: llvm/trunk/lib/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Path.cpp?rev=122589&r1=122588&r2=122589&view=diff ============================================================================== --- llvm/trunk/lib/Support/Path.cpp (original) +++ llvm/trunk/lib/Support/Path.cpp Mon Dec 27 19:49:21 2010 @@ -140,7 +140,11 @@ bool Path::isArchive() const { - return hasMagicNumber("!\012"); + std::string Magic; + if (getMagicNumber(Magic, 8)) + if (IdentifyFileType(Magic.c_str(), Magic.length()) == Archive_FileType) + return true; + return false; } bool From rafael.espindola at gmail.com Mon Dec 27 22:15:37 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 28 Dec 2010 04:15:37 -0000 Subject: [llvm-commits] [llvm] r122590 - in /llvm/trunk: include/llvm/MC/MCDwarf.h lib/MC/MCDwarf.cpp lib/MC/MCStreamer.cpp test/MC/ELF/cfi-def-cfa-offset.s Message-ID: <20101228041537.53DF62A6C12C@llvm.org> Author: rafael Date: Mon Dec 27 22:15:37 2010 New Revision: 122590 URL: http://llvm.org/viewvc/llvm-project?rev=122590&view=rev Log: Start adding basic support for emitting the call frame instructions. Added: llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s Modified: llvm/trunk/include/llvm/MC/MCDwarf.h llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCStreamer.cpp Modified: llvm/trunk/include/llvm/MC/MCDwarf.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=122590&r1=122589&r2=122590&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCDwarf.h (original) +++ llvm/trunk/include/llvm/MC/MCDwarf.h Mon Dec 27 22:15:37 2010 @@ -16,6 +16,7 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineLocation.h" // FIXME #include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Dwarf.h" @@ -227,10 +228,13 @@ }; struct MCDwarfFrameInfo { + MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), Moves(), + PersonalityEncoding(0), LsdaEncoding(0) {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *Personality; const MCSymbol *Lsda; + std::vector Moves; unsigned PersonalityEncoding; unsigned LsdaEncoding; }; Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122590&r1=122589&r2=122590&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Mon Dec 27 22:15:37 2010 @@ -460,9 +460,11 @@ if (BaseLabel && Label) { MCSymbol *ThisSym = Label; if (ThisSym != BaseLabel) { + // FIXME: We should relax this instead of using a DW_CFA_advance_loc4 + // for every address change! streamer.EmitIntValue(dwarf::DW_CFA_advance_loc4, 1); const MCExpr *Length = MakeStartMinusEndExpr(streamer, *BaseLabel, - *ThisSym, 4); + *ThisSym, 0); streamer.EmitValue(Length, 4); BaseLabel = ThisSym; } @@ -672,6 +674,8 @@ streamer.EmitLabel(augmentationEnd); // Call Frame Instructions + EmitFrameMoves(streamer, frame.Moves, frame.Begin, true); + // Padding streamer.EmitValueToAlignment(4); Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122590&r1=122589&r2=122590&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Mon Dec 27 22:15:37 2010 @@ -157,7 +157,7 @@ report_fatal_error("Starting a frame before finishing the previous one!"); return true; } - MCDwarfFrameInfo Frame = {0, 0, 0, 0, 0, 0}; + MCDwarfFrameInfo Frame; Frame.Begin = getContext().CreateTempSymbol(); EmitLabel(Frame.Begin); FrameInfos.push_back(Frame); @@ -174,6 +174,13 @@ bool MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + MCSymbol *Label = getContext().CreateTempSymbol(); + EmitLabel(Label); + MachineLocation Dest(MachineLocation::VirtualFP); + MachineLocation Source(MachineLocation::VirtualFP, -Offset); + MachineMove Move(Label, Dest, Source); + CurFrame->Moves.push_back(Move); return false; } Added: llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s?rev=122590&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s (added) +++ llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s Mon Dec 27 22:15:37 2010 @@ -0,0 +1,49 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +f: + .cfi_startproc + subq $8, %rsp + .cfi_def_cfa_offset 16 + nop + addq $8, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc + +// FIXME: This is a correct but really inefficient coding since +// we use a CFA_advance_loc4 for every address change! + +// CHECK: # Section 0x00000004 +// CHECK-NEXT: (('sh_name', 0x00000012) # '.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000001) +// CHECK-NEXT: ('sh_flags', 0x00000002) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000050) +// CHECK-NEXT: ('sh_size', 0x00000038) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 1c000000 1c000000 00000000 0a000000 00040400 00000e10 04050000 000e0800') +// CHECK-NEXT: ), + +// CHECK: # Section 0x00000008 +// CHECK-NEXT: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000168) +// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_info', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) +// CHECK-NEXT: ), From rafael.espindola at gmail.com Mon Dec 27 23:39:27 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 28 Dec 2010 05:39:27 -0000 Subject: [llvm-commits] [llvm] r122591 - in /llvm/trunk: include/llvm/MC/MCAssembler.h include/llvm/MC/MCDwarf.h include/llvm/MC/MCObjectStreamer.h include/llvm/MC/MCStreamer.h lib/MC/MCAssembler.cpp lib/MC/MCDwarf.cpp lib/MC/MCObjectStreamer.cpp test/MC/ELF/cfi-def-cfa-offset.s Message-ID: <20101228053927.EE0352A6C12C@llvm.org> Author: rafael Date: Mon Dec 27 23:39:27 2010 New Revision: 122591 URL: http://llvm.org/viewvc/llvm-project?rev=122591&view=rev Log: Relax address updates in the eh_frame section. Modified: llvm/trunk/include/llvm/MC/MCAssembler.h llvm/trunk/include/llvm/MC/MCDwarf.h llvm/trunk/include/llvm/MC/MCObjectStreamer.h llvm/trunk/include/llvm/MC/MCStreamer.h llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCObjectStreamer.cpp llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s Modified: llvm/trunk/include/llvm/MC/MCAssembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=122591&r1=122590&r2=122591&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCAssembler.h (original) +++ llvm/trunk/include/llvm/MC/MCAssembler.h Mon Dec 27 23:39:27 2010 @@ -52,6 +52,7 @@ FT_Inst, FT_Org, FT_Dwarf, + FT_DwarfFrame, FT_LEB }; @@ -369,7 +370,7 @@ public: MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, - MCSectionData *SD = 0) + MCSectionData *SD) : MCFragment(FT_Dwarf, SD), LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); } @@ -391,6 +392,34 @@ static bool classof(const MCDwarfLineAddrFragment *) { return true; } }; +class MCDwarfCallFrameFragment : public MCFragment { + /// AddrDelta - The expression for the difference of the two symbols that + /// make up the address delta between two .cfi_* dwarf directives. + const MCExpr *AddrDelta; + + SmallString<8> Contents; + +public: + MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD) + : MCFragment(FT_DwarfFrame, SD), + AddrDelta(&_AddrDelta) { Contents.push_back(0); } + + /// @name Accessors + /// @{ + + const MCExpr &getAddrDelta() const { return *AddrDelta; } + + SmallString<8> &getContents() { return Contents; } + const SmallString<8> &getContents() const { return Contents; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_DwarfFrame; + } + static bool classof(const MCDwarfCallFrameFragment *) { return true; } +}; + // FIXME: Should this be a separate class, or just merged into MCSection? Since // we anticipate the fast path being through an MCAssembler, the only reason to // keep it out is for API abstraction. @@ -705,6 +734,8 @@ bool RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); bool RelaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); + bool RelaxDwarfCallFrameFragment(MCAsmLayout &Layout, + MCDwarfCallFrameFragment &DF); /// FinishLayout - Finalize a layout, including fragment lowering. void FinishLayout(MCAsmLayout &Layout); Modified: llvm/trunk/include/llvm/MC/MCDwarf.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=122591&r1=122590&r2=122591&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCDwarf.h (original) +++ llvm/trunk/include/llvm/MC/MCDwarf.h Mon Dec 27 23:39:27 2010 @@ -25,6 +25,7 @@ namespace llvm { class MachineMove; class MCContext; + class MCExpr; class MCSection; class MCSectionData; class MCStreamer; @@ -245,6 +246,8 @@ // This emits the frame info section. // static void Emit(MCStreamer &streamer); + static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta); + static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS); }; } // end namespace llvm Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=122591&r1=122590&r2=122591&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original) +++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Mon Dec 27 23:39:27 2010 @@ -71,6 +71,8 @@ virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label); + virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label); virtual void Finish(); /// @} Modified: llvm/trunk/include/llvm/MC/MCStreamer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=122591&r1=122590&r2=122591&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCStreamer.h (original) +++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Dec 27 23:39:27 2010 @@ -386,6 +386,10 @@ const MCSymbol *LastLabel, const MCSymbol *Label) = 0; + virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label) { + } + void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label, int PointerSize); Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=122591&r1=122590&r2=122591&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Dec 27 23:39:27 2010 @@ -323,6 +323,8 @@ case MCFragment::FT_Dwarf: return cast(F).getContents().size(); + case MCFragment::FT_DwarfFrame: + return cast(F).getContents().size(); } assert(0 && "invalid fragment kind"); @@ -453,6 +455,11 @@ OW->WriteBytes(OF.getContents().str()); break; } + case MCFragment::FT_DwarfFrame: { + const MCDwarfCallFrameFragment &CF = cast(F); + OW->WriteBytes(CF.getContents().str()); + break; + } } assert(OW->getStream().tell() - Start == FragmentSize); @@ -712,6 +719,21 @@ return OldSize != Data.size(); } +bool MCAssembler::RelaxDwarfCallFrameFragment(MCAsmLayout &Layout, + MCDwarfCallFrameFragment &DF) { + int64_t AddrDelta = 0; + uint64_t OldSize = DF.getContents().size(); + bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout); + (void)IsAbs; + assert(IsAbs); + SmallString<8> &Data = DF.getContents(); + Data.clear(); + raw_svector_ostream OSE(Data); + MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OSE); + OSE.flush(); + return OldSize != Data.size(); +} + bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { MCFragment *FirstInvalidFragment = NULL; @@ -730,9 +752,14 @@ relaxedFrag = RelaxDwarfLineAddr(Layout, *cast(it2)); break; - case MCFragment::FT_LEB: - relaxedFrag = RelaxLEB(Layout, *cast(it2)); - break; + case MCFragment::FT_DwarfFrame: + relaxedFrag = + RelaxDwarfCallFrameFragment(Layout, + *cast(it2)); + break; + case MCFragment::FT_LEB: + relaxedFrag = RelaxLEB(Layout, *cast(it2)); + break; } // Update the layout, and remember that we relaxed. if (relaxedFrag && !FirstInvalidFragment) @@ -789,6 +816,7 @@ case MCFragment::FT_Inst: OS << "MCInstFragment"; break; case MCFragment::FT_Org: OS << "MCOrgFragment"; break; case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break; + case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break; case MCFragment::FT_LEB: OS << "MCLEBFragment"; break; } @@ -855,6 +883,12 @@ << " LineDelta:" << OF->getLineDelta(); break; } + case MCFragment::FT_DwarfFrame: { + const MCDwarfCallFrameFragment *CF = cast(this); + OS << "\n "; + OS << " AddrDelta:" << CF->getAddrDelta(); + break; + } case MCFragment::FT_LEB: { const MCLEBFragment *LF = cast(this); OS << "\n "; Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122591&r1=122590&r2=122591&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Mon Dec 27 23:39:27 2010 @@ -460,12 +460,7 @@ if (BaseLabel && Label) { MCSymbol *ThisSym = Label; if (ThisSym != BaseLabel) { - // FIXME: We should relax this instead of using a DW_CFA_advance_loc4 - // for every address change! - streamer.EmitIntValue(dwarf::DW_CFA_advance_loc4, 1); - const MCExpr *Length = MakeStartMinusEndExpr(streamer, *BaseLabel, - *ThisSym, 0); - streamer.EmitValue(Length, 4); + streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym); BaseLabel = ThisSym; } } @@ -748,3 +743,30 @@ if (fdeEnd) streamer.EmitLabel(fdeEnd); } + +void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer, + uint64_t AddrDelta) { + SmallString<256> Tmp; + raw_svector_ostream OS(Tmp); + MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OS); + Streamer.EmitBytes(OS.str(), /*AddrSpace=*/0); +} + +void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta, + raw_ostream &OS) { + // FIXME: Assumes the code alignment factor is 1. + if (isUIntN(6, AddrDelta)) { + uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta; + OS << Opcode; + } else if (isUInt<8>(AddrDelta)) { + OS << uint8_t(dwarf::DW_CFA_advance_loc1); + OS << uint8_t(AddrDelta); + } else if (isUInt<16>(AddrDelta)) { + OS << uint8_t(dwarf::DW_CFA_advance_loc2); + OS << uint16_t(AddrDelta); + } else { + assert(isUInt<32>(AddrDelta)); + OS << uint8_t(dwarf::DW_CFA_advance_loc4); + OS << uint32_t(AddrDelta); + } +} Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=122591&r1=122590&r2=122591&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Mon Dec 27 23:39:27 2010 @@ -190,6 +190,28 @@ getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); } +static const MCExpr *BuildSymbolDiff(MCContext &Context, + const MCSymbol *A, const MCSymbol *B) { + MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; + const MCExpr *ARef = + MCSymbolRefExpr::Create(A, Variant, Context); + const MCExpr *BRef = + MCSymbolRefExpr::Create(B, Variant, Context); + const MCExpr *AddrDelta = + MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context); + return AddrDelta; +} + +static const MCExpr *ForceExpAbs(MCObjectStreamer *Streamer, + MCContext &Context, const MCExpr* Expr) { + if (Context.getAsmInfo().hasAggressiveSymbolFolding()) + return Expr; + + MCSymbol *ABS = Context.CreateTempSymbol(); + Streamer->EmitAssignment(ABS, Expr); + return MCSymbolRefExpr::Create(ABS, Context); +} + void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label) { @@ -198,27 +220,28 @@ EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); return; } - MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; - const MCExpr *LabelRef = - MCSymbolRefExpr::Create(Label, Variant, getContext()); - const MCExpr *LastLabelRef = - MCSymbolRefExpr::Create(LastLabel, Variant, getContext()); - const MCExpr *AddrDelta = - MCBinaryExpr::Create(MCBinaryExpr::Sub, LabelRef, LastLabelRef, - getContext()); + const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); int64_t Res; if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { MCDwarfLineAddr::Emit(this, LineDelta, Res); return; } - if (!getContext().getAsmInfo().hasAggressiveSymbolFolding()) { - MCSymbol *ABS = getContext().CreateTempSymbol(); - EmitAssignment(ABS, AddrDelta); - AddrDelta = MCSymbolRefExpr::Create(ABS, getContext()); - } + AddrDelta = ForceExpAbs(this, getContext(), AddrDelta); new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); } +void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label) { + const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); + int64_t Res; + if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { + MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); + return; + } + AddrDelta = ForceExpAbs(this, getContext(), AddrDelta); + new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); +} + void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) { new MCOrgFragment(*Offset, Value, getCurrentSectionData()); Modified: llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s?rev=122591&r1=122590&r2=122591&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s (original) +++ llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s Mon Dec 27 23:39:27 2010 @@ -10,21 +10,18 @@ ret .cfi_endproc -// FIXME: This is a correct but really inefficient coding since -// we use a CFA_advance_loc4 for every address change! - // CHECK: # Section 0x00000004 // CHECK-NEXT: (('sh_name', 0x00000012) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) // CHECK-NEXT: ('sh_flags', 0x00000002) // CHECK-NEXT: ('sh_addr', 0x00000000) // CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000038) +// CHECK-NEXT: ('sh_size', 0x00000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000000) -// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 1c000000 1c000000 00000000 0a000000 00040400 00000e10 04050000 000e0800') +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 0a000000 00440e10 450e0800') // CHECK-NEXT: ), // CHECK: # Section 0x00000008 @@ -32,7 +29,7 @@ // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000168) +// CHECK-NEXT: ('sh_offset', 0x00000160) // CHECK-NEXT: ('sh_size', 0x00000018) // CHECK-NEXT: ('sh_link', 0x00000006) // CHECK-NEXT: ('sh_info', 0x00000004) From baldrick at free.fr Mon Dec 27 07:50:07 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 27 Dec 2010 14:50:07 +0100 Subject: [llvm-commits] [llvm] r122399 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombine.h lib/Transforms/InstCombine/InstCombineAddSub.cpp lib/Transforms/InstCombine/InstCombineAndOrXor.cpp lib/Transforms/InstCombine/InstCombineMulDivRem.cpp lib/Transforms/InstCombine/InstructionCombining.cpp test/Transforms/InstCombine/2010-11-23-Distributed.ll In-Reply-To: <497F8B4E-2BB3-4369-B210-763F329968F6@apple.com> References: <20101222133608.914332A6C12C@llvm.org> <497F8B4E-2BB3-4369-B210-763F329968F6@apple.com> Message-ID: <4D18998F.7000101@free.fr> Hi Chris, >> Add a generic expansion transform: A op (B op' C) -> (A op B) op' (A op C) >> if both A op B and A op C simplify. This fires fairly often but doesn't >> make that much difference. On gcc-as-one-file it removes two "and"s and >> turns one branch into a select. > > Hi Duncan, > > I'm a bit concerned about the compile time cost of this. If this isn't kicking in much, is it really worth it? Have you looked to see if this causes a compile time hit? I checked compilation time on gcc-as-one-big-file and I didn't see any significant difference in compile time. If anything instcombine is faster with this change! That's actually possible: the new logic fires quite often but doesn't make much difference because the existing logic caught most of the cases already some other way. If the new logic gets them faster/cheaper than the old logic, for example in one step rather than after several, then that would result in a speedup. But as I said, the difference isn't statistically significant. Ciao, Duncan. From baldrick at free.fr Tue Dec 28 03:25:25 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 28 Dec 2010 10:25:25 +0100 Subject: [llvm-commits] [llvm] r122567 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp In-Reply-To: <7CF76E3A-19BA-4B23-B9FB-EAA223BDDCA8@apple.com> References: <20101226204546.0E4402A6C12C@llvm.org> <4D17AEB8.5040402@free.fr> <7CF76E3A-19BA-4B23-B9FB-EAA223BDDCA8@apple.com> Message-ID: <4D19AD05.7010102@free.fr> Hi Chris, >>> + // Check to see if the store updates all bits in memory. We don't want to >>> + // process things like a store of i3. We also require that the store be a >>> + // multiple of a byte. >>> + uint64_t SizeInBits = TD->getTypeSizeInBits(StoredVal->getType()); >>> + if ((SizeInBits& 7) || (SizeInBits>> 32) != 0 || >>> + SizeInBits != TD->getTypeStoreSizeInBits(StoredVal->getType())) >>> + return false; >> >> will this catch the case of storing a first class struct or array? > > I'm not sure what you mean. My intent is to start simple and just handle strided stores that satisfy isBytewiseValue. There are many interesting forms of loops that aren't like this, they will be added over time. suppose that the store is of a first class value. The above test is not sufficient to check that the store updates all bits in memory in this case. It is true that isBytewiseValue will return false for a first class struct, so it doesn't matter much. However if you are going to test that a store updates all bits it seems wiser to me to catch all cases. On the other hand you could just drop that part of the test and rely on isBytewiseValue. After all it returns false for i3 too. Ciao, Duncan. From baldrick at free.fr Tue Dec 28 03:41:15 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 28 Dec 2010 09:41:15 -0000 Subject: [llvm-commits] [llvm] r122593 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20101228094115.7F77A2A6C12C@llvm.org> Author: baldrick Date: Tue Dec 28 03:41:15 2010 New Revision: 122593 URL: http://llvm.org/viewvc/llvm-project?rev=122593&view=rev Log: Silence gcc warning about an unused variable when doing a release build. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122593&r1=122592&r2=122593&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Tue Dec 28 03:41:15 2010 @@ -254,6 +254,7 @@ DEBUG(dbgs() << " Formed memset: " << *NewCall << "\n" << " from store to: " << *Ev << " at: " << *SI << "\n"); + (void)NewCall; // Okay, the memset has been formed. Zap the original store and anything that // feeds into it. From baldrick at free.fr Tue Dec 28 04:02:42 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 28 Dec 2010 10:02:42 -0000 Subject: [llvm-commits] [llvm] r122594 - /llvm/trunk/lib/MC/MCDwarf.cpp Message-ID: <20101228100242.5F2AC2A6C12C@llvm.org> Author: baldrick Date: Tue Dec 28 04:02:42 2010 New Revision: 122594 URL: http://llvm.org/viewvc/llvm-project?rev=122594&view=rev Log: Fix warning about size potentially being used uninitialized when doing a release build. Modified: llvm/trunk/lib/MC/MCDwarf.cpp Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122594&r1=122593&r2=122594&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Dec 28 04:02:42 2010 @@ -516,7 +516,6 @@ switch (format) { default: assert(0 && "Unknown Encoding"); - break; case dwarf::DW_EH_PE_absptr: case dwarf::DW_EH_PE_signed: size = asmInfo.getPointerSize(); From baldrick at free.fr Tue Dec 28 04:07:15 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 28 Dec 2010 10:07:15 -0000 Subject: [llvm-commits] [llvm] r122595 - /llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Message-ID: <20101228100715.3974A2A6C12C@llvm.org> Author: baldrick Date: Tue Dec 28 04:07:15 2010 New Revision: 122595 URL: http://llvm.org/viewvc/llvm-project?rev=122595&view=rev Log: Pacify the compiler. BestWeight cannot in fact be used uninitialized in this function, but the compiler was warning that it might be when doing a release build. Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=122595&r1=122594&r2=122595&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Tue Dec 28 04:07:15 2010 @@ -379,7 +379,7 @@ SmallVectorImpl &NewVRegs) { NamedRegionTimer T("Spill Interference", TimerGroupName, TimePassesIsEnabled); unsigned BestPhys = 0; - float BestWeight; + float BestWeight = 0; Order.rewind(); while (unsigned PhysReg = Order.next()) { From zwarich at apple.com Tue Dec 28 04:49:33 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 10:49:33 -0000 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101228104933.E73A82A6C12C@llvm.org> Author: zwarich Date: Tue Dec 28 04:49:33 2010 New Revision: 122596 URL: http://llvm.org/viewvc/llvm-project?rev=122596&view=rev Log: Avoid iterating every operand of an instruction in StrongPHIElimination, since we are only interested in the defs when discovering interferences. This is a 28% speedup running StrongPHIElimination on 403.gcc. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122596&r1=122595&r2=122596&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Dec 28 04:49:33 2010 @@ -471,10 +471,9 @@ DenseMap& ImmediateDominatingParent) { for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end(); BBI != BBE; ++BBI) { - for (unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) { - MachineOperand& MO = BBI->getOperand(i); - if (!MO.isReg() || !MO.isDef()) - continue; + for (MachineInstr::const_mop_iterator I = BBI->operands_begin(), + E = BBI->operands_end(); I != E && I->isReg() && I->isDef(); ++I) { + const MachineOperand& MO = *I; unsigned DestReg = MO.getReg(); if (!DestReg || !TargetRegisterInfo::isVirtualRegister(DestReg)) From benny.kra at googlemail.com Tue Dec 28 07:05:13 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 28 Dec 2010 13:05:13 -0000 Subject: [llvm-commits] [llvm] r122597 - /llvm/trunk/lib/Support/PathV2.cpp Message-ID: <20101228130513.D64132A6C12C@llvm.org> Author: d0k Date: Tue Dec 28 07:05:13 2010 New Revision: 122597 URL: http://llvm.org/viewvc/llvm-project?rev=122597&view=rev Log: Fix a signed/unsigned comparison warning. Modified: llvm/trunk/lib/Support/PathV2.cpp Modified: llvm/trunk/lib/Support/PathV2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PathV2.cpp?rev=122597&r1=122596&r2=122597&view=diff ============================================================================== --- llvm/trunk/lib/Support/PathV2.cpp (original) +++ llvm/trunk/lib/Support/PathV2.cpp Tue Dec 28 07:05:13 2010 @@ -676,7 +676,7 @@ std::FILE *file = std::fopen(Path.data(), "rb"); if (file == 0) return error_code(errno, posix_category()); - int size = ::fread(BufferStorage.data(), 1, Magic.size(), file); + size_t size = ::fread(BufferStorage.data(), 1, Magic.size(), file); if (size != Magic.size()) { int error = errno; bool eof = std::feof(file) != 0; From benny.kra at googlemail.com Tue Dec 28 07:52:53 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 28 Dec 2010 13:52:53 -0000 Subject: [llvm-commits] [llvm] r122598 - in /llvm/trunk/lib: Analysis/InstructionSimplify.cpp MC/TargetAsmBackend.cpp Message-ID: <20101228135253.16B452A6C12C@llvm.org> Author: d0k Date: Tue Dec 28 07:52:52 2010 New Revision: 122598 URL: http://llvm.org/viewvc/llvm-project?rev=122598&view=rev Log: Cast away "comparison between signed and unsigned integer" warnings. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/MC/TargetAsmBackend.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122598&r1=122597&r2=122598&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Dec 28 07:52:52 2010 @@ -71,8 +71,9 @@ /// Also performs the transform "(A op' B) op C" -> "(A op C) op' (B op C)". /// Returns the simplified value, or null if no simplification was performed. static Value *ExpandBinOp(unsigned Opcode, Value *LHS, Value *RHS, - unsigned OpcodeToExpand, const TargetData *TD, + unsigned OpcToExpand, const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { + Instruction::BinaryOps OpcodeToExpand = (Instruction::BinaryOps)OpcToExpand; // Recursion is always used, so bail out at once if we already hit the limit. if (!MaxRecurse--) return 0; @@ -133,8 +134,9 @@ /// OpCodeToExtract is Mul then this tries to turn "(A*B)+(A*C)" into "A*(B+C)". /// Returns the simplified value, or null if no simplification was performed. static Value *FactorizeBinOp(unsigned Opcode, Value *LHS, Value *RHS, - unsigned OpcodeToExtract, const TargetData *TD, + unsigned OpcToExtract, const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { + Instruction::BinaryOps OpcodeToExtract = (Instruction::BinaryOps)OpcToExtract; // Recursion is always used, so bail out at once if we already hit the limit. if (!MaxRecurse--) return 0; @@ -201,10 +203,11 @@ /// SimplifyAssociativeBinOp - Generic simplifications for associative binary /// operations. Returns the simpler value, or null if none was found. -static Value *SimplifyAssociativeBinOp(unsigned Opcode, Value *LHS, Value *RHS, +static Value *SimplifyAssociativeBinOp(unsigned Opc, Value *LHS, Value *RHS, const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { + Instruction::BinaryOps Opcode = (Instruction::BinaryOps)Opc; assert(Instruction::isAssociative(Opcode) && "Not an associative operation!"); // Recursion is always used, so bail out at once if we already hit the limit. Modified: llvm/trunk/lib/MC/TargetAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/TargetAsmBackend.cpp?rev=122598&r1=122597&r2=122598&view=diff ============================================================================== --- llvm/trunk/lib/MC/TargetAsmBackend.cpp (original) +++ llvm/trunk/lib/MC/TargetAsmBackend.cpp Tue Dec 28 07:52:52 2010 @@ -31,7 +31,7 @@ { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel } }; - assert(Kind <= sizeof(Builtins) / sizeof(Builtins[0]) && + assert((size_t)Kind <= sizeof(Builtins) / sizeof(Builtins[0]) && "Unknown fixup kind"); return Builtins[Kind]; } From baldrick at free.fr Tue Dec 28 11:53:35 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 28 Dec 2010 18:53:35 +0100 Subject: [llvm-commits] [llvm] r122598 - in /llvm/trunk/lib: Analysis/InstructionSimplify.cpp MC/TargetAsmBackend.cpp In-Reply-To: <20101228135253.16B452A6C12C@llvm.org> References: <20101228135253.16B452A6C12C@llvm.org> Message-ID: <4D1A241F.6050202@free.fr> Hi Benjamin, > Cast away "comparison between signed and unsigned integer" warnings. ... > @@ -71,8 +71,9 @@ > /// Also performs the transform "(A op' B) op C" -> "(A op C) op' (B op C)". > /// Returns the simplified value, or null if no simplification was performed. > static Value *ExpandBinOp(unsigned Opcode, Value *LHS, Value *RHS, > - unsigned OpcodeToExpand, const TargetData *TD, > + unsigned OpcToExpand, const TargetData *TD, > const DominatorTree *DT, unsigned MaxRecurse) { > + Instruction::BinaryOps OpcodeToExpand = (Instruction::BinaryOps)OpcToExpand; for what it's worth, recent versions of gcc (eg: gcc-4.5) do not warn about this (comparing an unsigned value with an enum). Ciao, Duncan. From baldrick at free.fr Tue Dec 28 12:00:24 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 28 Dec 2010 18:00:24 -0000 Subject: [llvm-commits] [llvm] r122600 - /llvm/trunk/include/llvm/Analysis/LoopInfo.h Message-ID: <20101228180024.EF1AB2A6C12C@llvm.org> Author: baldrick Date: Tue Dec 28 12:00:24 2010 New Revision: 122600 URL: http://llvm.org/viewvc/llvm-project?rev=122600&view=rev Log: Small optimization to speed up replacementPreservesLCSSAForm. Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=122600&r1=122599&r2=122600&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Tue Dec 28 12:00:24 2010 @@ -1029,6 +1029,10 @@ // instruction. Instruction *I = dyn_cast(To); if (!I) return true; + // If both instructions are defined in the same basic block then replacement + // cannot break LCSSA form. + if (I->getParent() == From->getParent()) + return true; // If the instruction is not defined in a loop then it can safely replace // anything. Loop *ToLoop = getLoopFor(I->getParent()); From baldrick at free.fr Tue Dec 28 12:01:19 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 28 Dec 2010 18:01:19 -0000 Subject: [llvm-commits] [llvm] r122601 - /llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Message-ID: <20101228180119.F02842A6C12C@llvm.org> Author: baldrick Date: Tue Dec 28 12:01:19 2010 New Revision: 122601 URL: http://llvm.org/viewvc/llvm-project?rev=122601&view=rev Log: Clarify that InstructionSimplify only returns values that dominate the original instruction. Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=122601&r1=122600&r2=122601&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original) +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Tue Dec 28 12:01:19 2010 @@ -11,7 +11,8 @@ // that do not require creating new instructions. This does constant folding // ("add i32 1, 1" -> "2") but can also handle non-constant operands, either // returning a constant ("and i32 %x, 0" -> "0") or an already existing value -// ("and i32 %x, %x" -> "%x"). +// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction +// then it dominates the original instruction. // //===----------------------------------------------------------------------===// From rafael.espindola at gmail.com Tue Dec 28 12:36:23 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 28 Dec 2010 18:36:23 -0000 Subject: [llvm-commits] [llvm] r122602 - in /llvm/trunk: include/llvm/MC/MCDwarf.h include/llvm/MC/MCStreamer.h lib/MC/MCDwarf.cpp lib/MC/MCParser/AsmParser.cpp lib/MC/MCStreamer.cpp test/MC/ELF/cfi-remember.s Message-ID: <20101228183623.65ADC2A6C12C@llvm.org> Author: rafael Date: Tue Dec 28 12:36:23 2010 New Revision: 122602 URL: http://llvm.org/viewvc/llvm-project?rev=122602&view=rev Log: Implement .cfi_remember_state and .cfi_restore_state. Added: llvm/trunk/test/MC/ELF/cfi-remember.s Modified: llvm/trunk/include/llvm/MC/MCDwarf.h llvm/trunk/include/llvm/MC/MCStreamer.h llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCParser/AsmParser.cpp llvm/trunk/lib/MC/MCStreamer.cpp Modified: llvm/trunk/include/llvm/MC/MCDwarf.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=122602&r1=122601&r2=122602&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCDwarf.h (original) +++ llvm/trunk/include/llvm/MC/MCDwarf.h Tue Dec 28 12:36:23 2010 @@ -228,14 +228,39 @@ int64_t LineDelta, uint64_t AddrDelta); }; + class MCCFIInstruction { + public: + enum OpType { Remember, Restore, Move }; + private: + OpType Operation; + MCSymbol *Label; + // Move to & from location. + MachineLocation Destination; + MachineLocation Source; + public: + MCCFIInstruction(OpType Op, MCSymbol *L) + : Operation(Op), Label(L) { + assert(Op == Remember || Op == Restore); + } + MCCFIInstruction(MCSymbol *L, const MachineLocation &D, + const MachineLocation &S) + : Operation(Move), Label(L), Destination(D), Source(S) { + } + OpType getOperation() const { return Operation; } + MCSymbol *getLabel() const { return Label; } + const MachineLocation &getDestination() const { return Destination; } + const MachineLocation &getSource() const { return Source; } + }; + struct MCDwarfFrameInfo { - MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), Moves(), - PersonalityEncoding(0), LsdaEncoding(0) {} + MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), + Instructions(), PersonalityEncoding(0), + LsdaEncoding(0) {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *Personality; const MCSymbol *Lsda; - std::vector Moves; + std::vector Instructions; unsigned PersonalityEncoding; unsigned LsdaEncoding; }; Modified: llvm/trunk/include/llvm/MC/MCStreamer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=122602&r1=122601&r2=122602&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCStreamer.h (original) +++ llvm/trunk/include/llvm/MC/MCStreamer.h Tue Dec 28 12:36:23 2010 @@ -401,6 +401,8 @@ virtual bool EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); + virtual bool EmitCFIRememberState(); + virtual bool EmitCFIRestoreState(); /// EmitInstruction - Emit the given @p Instruction into the current /// section. Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122602&r1=122601&r2=122602&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Dec 28 12:36:23 2010 @@ -18,6 +18,7 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetAsmBackend.h" #include "llvm/Target/TargetAsmInfo.h" @@ -438,71 +439,89 @@ return -size; } -/// EmitFrameMoves - Emit frame instructions to describe the layout of the -/// frame. -static void EmitFrameMoves(MCStreamer &streamer, - const std::vector &Moves, - MCSymbol *BaseLabel, bool isEH) { - MCContext &context = streamer.getContext(); +static void EmitCFIInstruction(MCStreamer &Streamer, + const MCCFIInstruction &Instr, + bool isEH) { + MCContext &context = Streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); - int dataAlignmentFactor = getDataAlignmentFactor(streamer); - - for (unsigned i = 0, N = Moves.size(); i < N; ++i) { - const MachineMove &Move = Moves[i]; - MCSymbol *Label = Move.getLabel(); - // Throw out move if the label is invalid. - if (Label && !Label->isDefined()) continue; // Not emitted, in dead code. - - const MachineLocation &Dst = Move.getDestination(); - const MachineLocation &Src = Move.getSource(); + int dataAlignmentFactor = getDataAlignmentFactor(Streamer); - // Advance row if new location. - if (BaseLabel && Label) { - MCSymbol *ThisSym = Label; - if (ThisSym != BaseLabel) { - streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym); - BaseLabel = ThisSym; - } - } + switch (Instr.getOperation()) { + case MCCFIInstruction::Move: { + const MachineLocation &Dst = Instr.getDestination(); + const MachineLocation &Src = Instr.getSource(); // If advancing cfa. if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) { assert(!Src.isReg() && "Machine move not supported yet."); if (Src.getReg() == MachineLocation::VirtualFP) { - streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1); + Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1); } else { - streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); - streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(), + Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); + Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(), isEH)); } - streamer.EmitULEB128IntValue(-Src.getOffset(), 1); - continue; + Streamer.EmitULEB128IntValue(-Src.getOffset(), 1); + return; } if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) { assert(Dst.isReg() && "Machine move not supported yet."); - streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); - streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Dst.getReg(), isEH)); - continue; + Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); + Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Dst.getReg(), isEH)); + return; } unsigned Reg = asmInfo.getDwarfRegNum(Src.getReg(), isEH); int Offset = Dst.getOffset() / dataAlignmentFactor; if (Offset < 0) { - streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1); - streamer.EmitULEB128IntValue(Reg); - streamer.EmitSLEB128IntValue(Offset); + Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1); + Streamer.EmitULEB128IntValue(Reg); + Streamer.EmitSLEB128IntValue(Offset); } else if (Reg < 64) { - streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1); - streamer.EmitULEB128IntValue(Offset, 1); + Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1); + Streamer.EmitULEB128IntValue(Offset, 1); } else { - streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1); - streamer.EmitULEB128IntValue(Reg, 1); - streamer.EmitULEB128IntValue(Offset, 1); + Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1); + Streamer.EmitULEB128IntValue(Reg, 1); + Streamer.EmitULEB128IntValue(Offset, 1); + } + return; + } + case MCCFIInstruction::Remember: + Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1); + return; + case MCCFIInstruction::Restore: + Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1); + return; + } + llvm_unreachable("Unhandled case in switch"); +} + +/// EmitFrameMoves - Emit frame instructions to describe the layout of the +/// frame. +static void EmitCFIInstructions(MCStreamer &streamer, + const std::vector &Instrs, + MCSymbol *BaseLabel, bool isEH) { + for (unsigned i = 0, N = Instrs.size(); i < N; ++i) { + const MCCFIInstruction &Instr = Instrs[i]; + MCSymbol *Label = Instr.getLabel(); + // Throw out move if the label is invalid. + if (Label && !Label->isDefined()) continue; // Not emitted, in dead code. + + // Advance row if new location. + if (BaseLabel && Label) { + MCSymbol *ThisSym = Label; + if (ThisSym != BaseLabel) { + streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym); + BaseLabel = ThisSym; + } } + + EmitCFIInstruction(streamer, Instr, isEH); } } @@ -618,8 +637,15 @@ // Initial Instructions const std::vector Moves = asmInfo.getInitialFrameState(); + std::vector Instructions; + + for (int i = 0, n = Moves.size(); i != n; ++i) { + MCCFIInstruction Inst(Moves[i].getLabel(), Moves[i].getDestination(), + Moves[i].getSource()); + Instructions.push_back(Inst); + } - EmitFrameMoves(streamer, Moves, NULL, true); + EmitCFIInstructions(streamer, Instructions, NULL, true); // Padding streamer.EmitValueToAlignment(4); @@ -668,7 +694,7 @@ streamer.EmitLabel(augmentationEnd); // Call Frame Instructions - EmitFrameMoves(streamer, frame.Moves, frame.Begin, true); + EmitCFIInstructions(streamer, frame.Instructions, frame.Begin, true); // Padding streamer.EmitValueToAlignment(4); Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122602&r1=122601&r2=122602&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Dec 28 12:36:23 2010 @@ -254,6 +254,10 @@ &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality"); AddDirectiveHandler< &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda"); + AddDirectiveHandler< + &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state"); + AddDirectiveHandler< + &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state"); // Macro directives. AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>( @@ -278,6 +282,8 @@ bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc); + bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc); + bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc); @@ -2261,6 +2267,20 @@ } } +/// ParseDirectiveCFIRememberState +/// ::= .cfi_remember_state +bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal, + SMLoc DirectiveLoc) { + return getStreamer().EmitCFIRememberState(); +} + +/// ParseDirectiveCFIRestoreState +/// ::= .cfi_remember_state +bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal, + SMLoc DirectiveLoc) { + return getStreamer().EmitCFIRestoreState(); +} + /// ParseDirectiveMacrosOnOff /// ::= .macros_on /// ::= .macros_off Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122602&r1=122601&r2=122602&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Dec 28 12:36:23 2010 @@ -179,8 +179,8 @@ EmitLabel(Label); MachineLocation Dest(MachineLocation::VirtualFP); MachineLocation Source(MachineLocation::VirtualFP, -Offset); - MachineMove Move(Label, Dest, Source); - CurFrame->Moves.push_back(Move); + MCCFIInstruction Instruction(Label, Dest, Source); + CurFrame->Instructions.push_back(Instruction); return false; } @@ -211,6 +211,27 @@ return false; } +bool MCStreamer::EmitCFIRememberState() { + EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + MCSymbol *Label = getContext().CreateTempSymbol(); + EmitLabel(Label); + MCCFIInstruction Instruction(MCCFIInstruction::Remember, Label); + CurFrame->Instructions.push_back(Instruction); + return false; +} + +bool MCStreamer::EmitCFIRestoreState() { + // FIXME: Error if there is no matching cfi_remember_state. + EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + MCSymbol *Label = getContext().CreateTempSymbol(); + EmitLabel(Label); + MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label); + CurFrame->Instructions.push_back(Instruction); + return false; +} + /// EmitRawText - If this file is backed by an assembly streamer, this dumps /// the specified string in the output .s file. This capability is /// indicated by the hasRawTextSupport() predicate. Added: llvm/trunk/test/MC/ELF/cfi-remember.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-remember.s?rev=122602&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-remember.s (added) +++ llvm/trunk/test/MC/ELF/cfi-remember.s Tue Dec 28 12:36:23 2010 @@ -0,0 +1,45 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +f: + .cfi_startproc + nop + .cfi_remember_state + nop + .cfi_restore_state + nop + .cfi_endproc + +// CHECK: # Section 0x00000004 +// CHECK-NEXT: (('sh_name', 0x00000012) # '.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000001) +// CHECK-NEXT: ('sh_flags', 0x00000002) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000048) +// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 03000000 00410a41 0b000000') +// CHECK-NEXT: ), + +// CHECK: # Section 0x00000008 +// CHECK-NEXT: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000158) +// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_info', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) +// CHECK-NEXT: ), From clattner at apple.com Tue Dec 28 12:44:57 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 28 Dec 2010 10:44:57 -0800 Subject: [llvm-commits] [llvm] r122399 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombine.h lib/Transforms/InstCombine/InstCombineAddSub.cpp lib/Transforms/InstCombine/InstCombineAndOrXor.cpp lib/Transforms/InstCombine/InstCombineMulDivRem.cpp lib/Transforms/InstCombine/InstructionCombining.cpp test/Transforms/InstCombine/2010-11-23-Distributed.ll In-Reply-To: <4D18998F.7000101@free.fr> References: <20101222133608.914332A6C12C@llvm.org> <497F8B4E-2BB3-4369-B210-763F329968F6@apple.com> <4D18998F.7000101@free.fr> Message-ID: <8C03F891-FA86-4A03-81DF-D1131E59BA59@apple.com> On Dec 27, 2010, at 5:50 AM, Duncan Sands wrote: > Hi Chris, > >>> Add a generic expansion transform: A op (B op' C) -> (A op B) op' (A op C) >>> if both A op B and A op C simplify. This fires fairly often but doesn't >>> make that much difference. On gcc-as-one-file it removes two "and"s and >>> turns one branch into a select. >> >> Hi Duncan, >> >> I'm a bit concerned about the compile time cost of this. If this isn't kicking in much, is it really worth it? Have you looked to see if this causes a compile time hit? > > I checked compilation time on gcc-as-one-big-file and I didn't see any > significant difference in compile time. If anything instcombine is faster > with this change! That's actually possible: the new logic fires quite often > but doesn't make much difference because the existing logic caught most of the > cases already some other way. If the new logic gets them faster/cheaper than > the old logic, for example in one step rather than after several, then that > would result in a speedup. But as I said, the difference isn't statistically > significant. Ok, great! Thanks for checking, -Chris From sabre at nondot.org Tue Dec 28 12:45:02 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 28 Dec 2010 18:45:02 -0000 Subject: [llvm-commits] [llvm] r122603 - /llvm/trunk/lib/Target/README.txt Message-ID: <20101228184502.67DEB2A6C12C@llvm.org> Author: lattner Date: Tue Dec 28 12:45:02 2010 New Revision: 122603 URL: http://llvm.org/viewvc/llvm-project?rev=122603&view=rev Log: add a note from llvmdev Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=122603&r1=122602&r2=122603&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Tue Dec 28 12:45:02 2010 @@ -2065,3 +2065,14 @@ } //===---------------------------------------------------------------------===// + +This compare could fold to false: + +define i1 @g(i32 a) nounwind readnone { + %add = shl i32 %a, 1 + %mul = shl i32 %a, 1 + %cmp = icmp ugt i32 %add, %mul + ret i1 %cmp +} + +//===---------------------------------------------------------------------===// From clattner at apple.com Tue Dec 28 12:51:14 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 28 Dec 2010 10:51:14 -0800 Subject: [llvm-commits] [llvm] r122567 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp In-Reply-To: <4D19AD05.7010102@free.fr> References: <20101226204546.0E4402A6C12C@llvm.org> <4D17AEB8.5040402@free.fr> <7CF76E3A-19BA-4B23-B9FB-EAA223BDDCA8@apple.com> <4D19AD05.7010102@free.fr> Message-ID: On Dec 28, 2010, at 1:25 AM, Duncan Sands wrote: > Hi Chris, > >>>> + // Check to see if the store updates all bits in memory. We don't want to >>>> + // process things like a store of i3. We also require that the store be a >>>> + // multiple of a byte. >>>> + uint64_t SizeInBits = TD->getTypeSizeInBits(StoredVal->getType()); >>>> + if ((SizeInBits& 7) || (SizeInBits>> 32) != 0 || >>>> + SizeInBits != TD->getTypeStoreSizeInBits(StoredVal->getType())) >>>> + return false; >>> >>> will this catch the case of storing a first class struct or array? >> >> I'm not sure what you mean. My intent is to start simple and just handle strided stores that satisfy isBytewiseValue. There are many interesting forms of loops that aren't like this, they will be added over time. > > suppose that the store is of a first class value. The above test is not > sufficient to check that the store updates all bits in memory in this case. > It is true that isBytewiseValue will return false for a first class struct, > so it doesn't matter much. However if you are going to test that a store > updates all bits it seems wiser to me to catch all cases. On the other hand > you could just drop that part of the test and rely on isBytewiseValue. After > all it returns false for i3 too. Fair point, I'll rely on isBytewiseValue, thanks. -Chris From sabre at nondot.org Tue Dec 28 12:53:48 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 28 Dec 2010 18:53:48 -0000 Subject: [llvm-commits] [llvm] r122604 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20101228185348.8441A2A6C12C@llvm.org> Author: lattner Date: Tue Dec 28 12:53:48 2010 New Revision: 122604 URL: http://llvm.org/viewvc/llvm-project?rev=122604&view=rev Log: simplify this, isBytewiseValue handles the extra check. We still check for "multiple of a byte" in size to make it clear that the >> 3 below is safe. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122604&r1=122603&r2=122604&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Tue Dec 28 12:53:48 2010 @@ -164,12 +164,9 @@ Value *StoredVal = SI->getValueOperand(); Value *StorePtr = SI->getPointerOperand(); - // Check to see if the store updates all bits in memory. We don't want to - // process things like a store of i3. We also require that the store be a - // multiple of a byte. + // Reject stores that are so large that they overflow an unsigned. uint64_t SizeInBits = TD->getTypeSizeInBits(StoredVal->getType()); - if ((SizeInBits & 7) || (SizeInBits >> 32) != 0 || - SizeInBits != TD->getTypeStoreSizeInBits(StoredVal->getType())) + if ((SizeInBits & 7) || (SizeInBits >> 32) != 0) return false; // See if the pointer expression is an AddRec like {base,+,1} on the current From clattner at apple.com Tue Dec 28 13:10:53 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 28 Dec 2010 11:10:53 -0800 Subject: [llvm-commits] [PATCH] Sparc backend fixes In-Reply-To: References: Message-ID: On Dec 26, 2010, at 8:33 PM, Venkatraman Govindaraju wrote: > Hello, > > The attached path fixes the following three issues with the Sparc backend. > > 1. EmitInstrWithCustomInserter() in SparcISelLowering splices > MachineBasicBlock before inserting them into the machine function. It > corrupts the def-use chain of MachineOperand and causes a infinite > loop in llc. Now, the patch avoids this by inserting the machine > basicblocks into the machine function before splicing the original > basicblock. > > 2. When the bitcode has "select_cc", Sparc backend may not generate > correct assembly code. Since select_ccs do not have ICC/FCC as Uses, > the corresponding def of ICC/FCC can be marked as dead and removed. > Now, the select_ccs have ICC/FCC as Uses. > > 3. Sparc backend does not know about Y register. It causes the "rdy" > and "wry" instructions to be marked as dead and removed. Now it knows > about Y and generate correct code. > > Please let me know if the patch is okay to commit. Looks great to me, please commit! -Chris From bob.wilson at apple.com Tue Dec 28 13:14:58 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 28 Dec 2010 11:14:58 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <20101228104933.E73A82A6C12C@llvm.org> References: <20101228104933.E73A82A6C12C@llvm.org> Message-ID: <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> On Dec 28, 2010, at 2:49 AM, Cameron Zwarich wrote: > Author: zwarich > Date: Tue Dec 28 04:49:33 2010 > New Revision: 122596 > > URL: http://llvm.org/viewvc/llvm-project?rev=122596&view=rev > Log: > Avoid iterating every operand of an instruction in StrongPHIElimination, since > we are only interested in the defs when discovering interferences. > > This is a 28% speedup running StrongPHIElimination on 403.gcc. > > Modified: > llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp > > Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122596&r1=122595&r2=122596&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) > +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Dec 28 04:49:33 2010 > @@ -471,10 +471,9 @@ > DenseMap& ImmediateDominatingParent) { > for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end(); > BBI != BBE; ++BBI) { > - for (unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) { > - MachineOperand& MO = BBI->getOperand(i); > - if (!MO.isReg() || !MO.isDef()) > - continue; > + for (MachineInstr::const_mop_iterator I = BBI->operands_begin(), > + E = BBI->operands_end(); I != E && I->isReg() && I->isDef(); ++I) { > + const MachineOperand& MO = *I; This is relying on the register def operands being first. I'm not sure that's always true. OptionalDefOperands, like cc_out for ARM, may come later in the operand list. > > unsigned DestReg = MO.getReg(); > if (!DestReg || !TargetRegisterInfo::isVirtualRegister(DestReg)) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gkistanova at gmail.com Tue Dec 28 14:17:11 2010 From: gkistanova at gmail.com (Galina Kistanova) Date: Tue, 28 Dec 2010 20:17:11 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r122605 - /llvm-gcc-4.2/trunk/extras/llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float Message-ID: <20101228201711.8F3712A6C12C@llvm.org> Author: gkistanova Date: Tue Dec 28 14:17:11 2010 New Revision: 122605 URL: http://llvm.org/viewvc/llvm-project?rev=122605&view=rev Log: Added build script for build on i686-pc-mingw32 of cross llvm-gcc for arm-none-linux-gnueabi. Added: llvm-gcc-4.2/trunk/extras/llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float (with props) Added: llvm-gcc-4.2/trunk/extras/llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/extras/llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float?rev=122605&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/extras/llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float (added) +++ llvm-gcc-4.2/trunk/extras/llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float Tue Dec 28 14:17:11 2010 @@ -0,0 +1,237 @@ +#!/bin/bash + +set -e # Terminate script at the first line that fails. +set -o pipefail # Return the first non-zero pipe command error. +set -x # Print commands as they are executed + +# This script performs an automated build on i686-pc-mingw32 of +# cross llvm-gcc for arm-eabi-hard-float. It assumes the valid native +# compiler for i686-pc-mingw32 is in place and available as well as +# cross libraries and headers for arm-eabi. + +# --build=i686-pc-mingw32 +# --host=i686-pc-mingw32 +# --target=arm-none-linux-gnueabi + +# The usage: +# Run this build from the build from the build root directory as +# llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float [] [] + + +# Expected project tree structure: +# +# +-- ${LLVM_src} +# +-- ${LLVM_GCC_src} +# +-- ${LLVM_obj} +# +-- ${LLVM_GCC_obj} +# +-- ${INSTALL} + +LLVM_src=llvm.src # The LLVM source code root directory name. +LLVM_GCC_src=llvm-gcc.src # The LLVM-GCC source code root directory name. +LLVM_obj=llvm.obj # The LLVM build root directory name. +LLVM_GCC_obj=llvm-gcc.obj # The LLVM-GCC build root directory name. +INSTALL=install # Where the result will be installed. + +BUILD_ROOT=$PWD # Where build happens. +PRIVATE_INSTALL=${BUILD_ROOT}/${INSTALL} # Where the result will be installed. + +#------------------------------------------------------------------------------ +# Define build steps, parse and validate input parameters +#------------------------------------------------------------------------------ + +# This script supports the following steps: +do_clean=no # Clean up the build directory. +do_copy_cross_tools=no # Copy cross-tools. +do_configure_llvm=no # Configure LLVM. +do_make_llvm=no # Make LLVM. +do_install_llvm=no # Install LLVM-GCC. +do_test_llvm=no # Test LLVM. +do_configure_llvmgcc=no # Configure LLVM-GCC. +do_make_llvmgcc=no # Make LLVM-GCC. +do_install_llvmgcc=no # Install LLVM-GCC. +do_all=no # Runs all steps at once when requested. + +# Set step parameter +if (( $# == 0 )) ; then + do_all=yes +fi +# else +if (( ! $# == 0 )) ; then + # First check that the parameter actually defines a step. + case $1 in + clean | \ + copy_cross_tools | \ + configure_llvm | \ + make_llvm | \ + install_llvm | \ + test_llvm | \ + configure_llvmgcc | \ + make_llvmgcc | \ + install_llvmgcc | \ + all) + eval do_$1=yes # Set the flag for the requested step . + shift # Remove it since is is ours and already precessed. + ;; + + *) + # Not our parameter. Pass it as is. + esac +fi + +# Set all steps if do_all requested +if [ "$do_all" == "yes" ] ; then + # Set all steps to yes + do_clean=yes + do_copy_cross_tools=yes + do_configure_llvm=yes + do_make_llvm=yes + do_install_llvm=yes + do_test_llvm=yes + do_configure_llvmgcc=yes + do_make_llvmgcc=yes + do_install_llvmgcc=yes +fi + +#------------------------------------------------------------------------------ +# Step: Clean up. +#------------------------------------------------------------------------------ +if [ "$do_clean" == "yes" ] ; then + + # Remove everything from where we will be installing the result. + rm -rf ${PRIVATE_INSTALL} + mkdir -p ${PRIVATE_INSTALL} + chmod a+rx ${PRIVATE_INSTALL} + +fi + +#------------------------------------------------------------------------------ +# Step: Copy cross-tools +#------------------------------------------------------------------------------ +if [ "$do_copy_cross_tools" == "yes" ] ; then + + # We need a local copy of binutils, system libraries and headers, + # since we will be installing there. + cp -Ru /c/cross-h/* ${PRIVATE_INSTALL} + +fi + +#------------------------------------------------------------------------------ +# Step: Configure LLVM. +#------------------------------------------------------------------------------ +if [ "$do_configure_llvm" == "yes" ] ; then + + # Remove previously build files if any. + rm -rf ${BUILD_ROOT}/${LLVM_obj} + mkdir -p ${BUILD_ROOT}/${LLVM_obj} + chmod a+rx ${BUILD_ROOT}/${LLVM_obj} + cd ${BUILD_ROOT}/${LLVM_obj} + + ../${LLVM_src}/configure --prefix=${PRIVATE_INSTALL} \ + --with-sysroot=${PRIVATE_INSTALL} \ + --with-lib-path=${PRIVATE_INSTALL}/lib \ + --build=i686-pc-mingw32 \ + --host=i686-pc-mingw32 \ + --target=arm-none-linux-gnueabi \ + --disable-shared \ + --disable-multilib \ + --disable-nls \ + --disable-sjlj-exceptions \ + --with-cpu=cortex-a8 \ + --with-fpu=neon \ + --with-abi=aapcs \ + --with-float=hard \ + --disable-bootstrap \ + --with-gcc \ + --with-gnu-as \ + --with-gnu-ld \ + --disable-werror \ + $@ # Extra args if any + +fi + +#------------------------------------------------------------------------------ +# Step: Make LLVM. +#------------------------------------------------------------------------------ +if [ "$do_make_llvm" == "yes" ] ; then + + cd ${BUILD_ROOT}/${LLVM_obj} + # NOTE: Do not build with ENABLE_OPTIMIZED=1 - some test fail after it. + nice -n 20 make all VERBOSE=1 \ + $@ # Extra args if any, like -j16 for example. + +fi + +#------------------------------------------------------------------------------ +# Step: Install LLVM. +#------------------------------------------------------------------------------ +if [ "$do_install_llvm" == "yes" ] ; then + + cd ${BUILD_ROOT}/${LLVM_obj} + # NOTE: Do not build with ENABLE_OPTIMIZED=1 - some test fail after it. + nice -n 20 make install VERBOSE=1 \ + $@ # Extra args if any, like -j16 for example. + +fi + +#------------------------------------------------------------------------------ +# Step: Test LLVM. +#------------------------------------------------------------------------------ +if [ "$do_test_llvm" == "yes" ] ; then + + cd ${BUILD_ROOT}/${LLVM_obj} + make check-lit VERBOSE=1 \ + $@ # Extra args if any, like -j16 for example. + +fi + +#------------------------------------------------------------------------------ +# Step: Configure LLVM-GCC. +#------------------------------------------------------------------------------ +if [ "$do_configure_llvmgcc" == "yes" ] ; then + + # Remove previously build files if any. + rm -rf ${BUILD_ROOT}/${LLVM_GCC_obj} + mkdir -p ${BUILD_ROOT}/${LLVM_GCC_obj} + chmod a+rx ${BUILD_ROOT}/${LLVM_GCC_obj} + cd ${BUILD_ROOT}/${LLVM_GCC_obj} + + ../${LLVM_GCC_src}/configure --prefix=${PRIVATE_INSTALL} \ + --build=i686-pc-mingw32 \ + --host=i686-pc-mingw32 \ + --target=arm-none-linux-gnueabi \ + --disable-nls \ + --enable-languages=c,c++ \ + --enable-llvm=${BUILD_ROOT}/${LLVM_obj} \ + --enable-checking \ + --program-prefix=llvm- \ + --disable-bootstrap \ + --with-cpu=cortex-a8 \ + --with-fpu=neon \ + --with-float=hard \ + --with-abi=aapcs \ + --disable-shared \ + $@ # Extra args if any + +fi + +#------------------------------------------------------------------------------ +# Step: Make LLVM-GCC. +#------------------------------------------------------------------------------ +if [ "$do_make_llvmgcc" == "yes" ] ; then + + cd ${BUILD_ROOT}/${LLVM_GCC_obj} + nice -n 20 make all \ + $@ # Extra args if any + +fi + +#------------------------------------------------------------------------------ +# Step: Install LLVM-GCC. +#------------------------------------------------------------------------------ +if [ "$do_install_llvmgcc" == "yes" ] ; then + + cd ${BUILD_ROOT}/${LLVM_GCC_obj} + nice -n 20 make install \ + $@ # Extra args if any + +fi Propchange: llvm-gcc-4.2/trunk/extras/llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float ------------------------------------------------------------------------------ svn:executable = * From grosser at fim.uni-passau.de Tue Dec 28 14:29:31 2010 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Tue, 28 Dec 2010 20:29:31 -0000 Subject: [llvm-commits] [llvm] r122606 - /llvm/trunk/docs/LangRef.html Message-ID: <20101228202932.338992A6C12C@llvm.org> Author: grosser Date: Tue Dec 28 14:29:31 2010 New Revision: 122606 URL: http://llvm.org/viewvc/llvm-project?rev=122606&view=rev Log: Integers are primitive types. Update the documentation to state this This was done for label, void, floating point, x86mmx, metadata, just not integer. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=122606&r1=122605&r2=122606&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Dec 28 14:29:31 2010 @@ -1496,6 +1496,7 @@ primitive label, void, + integer, floating point, x86mmx, metadata. From venkatra at cs.wisc.edu Tue Dec 28 14:39:17 2010 From: venkatra at cs.wisc.edu (Venkatraman Govindaraju) Date: Tue, 28 Dec 2010 20:39:17 -0000 Subject: [llvm-commits] [llvm] r122607 - in /llvm/trunk/lib/Target/Sparc: SparcISelLowering.cpp SparcInstrInfo.td SparcRegisterInfo.td Message-ID: <20101228203917.A9D442A6C12C@llvm.org> Author: venkatra Date: Tue Dec 28 14:39:17 2010 New Revision: 122607 URL: http://llvm.org/viewvc/llvm-project?rev=122607&view=rev Log: Multiple SPARC backend fixes: added Y register; updated select_cc, subx, subxcc defs/uses; and fixed CustomInserter. Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=122607&r1=122606&r2=122607&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Tue Dec 28 14:39:17 2010 @@ -1012,6 +1012,8 @@ MachineFunction *F = BB->getParent(); MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, copy0MBB); + F->insert(It, sinkMBB); // Transfer the remainder of BB and its successor edges to sinkMBB. sinkMBB->splice(sinkMBB->begin(), BB, @@ -1024,8 +1026,6 @@ BB->addSuccessor(sinkMBB); BuildMI(BB, dl, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC); - F->insert(It, copy0MBB); - F->insert(It, sinkMBB); // copy0MBB: // %FalseValue = ... Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=122607&r1=122606&r2=122607&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original) +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Tue Dec 28 14:39:17 2010 @@ -233,7 +233,8 @@ // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after // instruction selection into a branch sequence. This has to handle all // permutations of selection between i32/f32/f64 on ICC and FCC. -let usesCustomInserter = 1 in { // Expanded after instruction selection. +let Uses = [ICC], + usesCustomInserter = 1 in { // Expanded after instruction selection. def SELECT_CC_Int_ICC : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_ICC PSEUDO!", @@ -244,6 +245,9 @@ "; SELECT_CC_Int_FCC PSEUDO!", [(set IntRegs:$dst, (SPselectfcc IntRegs:$T, IntRegs:$F, imm:$Cond))]>; +} + +let usesCustomInserter = 1, Uses = [FCC] in { def SELECT_CC_FP_ICC : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), "; SELECT_CC_FP_ICC PSEUDO!", @@ -440,24 +444,29 @@ // Section B.15 - Subtract Instructions, p. 110 defm SUB : F3_12 <"sub" , 0b000100, sub>; -defm SUBX : F3_12 <"subx" , 0b001100, sube>; +let Uses = [ICC] in + defm SUBX : F3_12 <"subx" , 0b001100, sube>; -let Defs = [ICC] in { +let Defs = [ICC] in defm SUBCC : F3_12 <"subcc", 0b010100, SPcmpicc>; +let Uses = [ICC], Defs = [ICC] in def SUBXCCrr: F3_1<2, 0b011100, (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), "subxcc $b, $c, $dst", []>; -} -// Section B.18 - Multiply Instructions, p. 113 -defm UMUL : F3_12np<"umul", 0b001010>; -defm SMUL : F3_12 <"smul", 0b001011, mul>; +// Section B.18 - Multiply Instructions, p. 113 +let Defs = [Y] in { + defm UMUL : F3_12np<"umul", 0b001010>; + defm SMUL : F3_12 <"smul", 0b001011, mul>; +} // Section B.19 - Divide Instructions, p. 115 -defm UDIV : F3_12np<"udiv", 0b001110>; -defm SDIV : F3_12np<"sdiv", 0b001111>; +let Defs = [Y] in { + defm UDIV : F3_12np<"udiv", 0b001110>; + defm SDIV : F3_12np<"sdiv", 0b001111>; +} // Section B.20 - SAVE and RESTORE, p. 117 defm SAVE : F3_12np<"save" , 0b111100>; @@ -527,18 +536,20 @@ } // Section B.28 - Read State Register Instructions -def RDY : F3_1<2, 0b101000, - (outs IntRegs:$dst), (ins), - "rd %y, $dst", []>; +let Uses = [Y] in + def RDY : F3_1<2, 0b101000, + (outs IntRegs:$dst), (ins), + "rd %y, $dst", []>; // Section B.29 - Write State Register Instructions -def WRYrr : F3_1<2, 0b110000, - (outs), (ins IntRegs:$b, IntRegs:$c), - "wr $b, $c, %y", []>; -def WRYri : F3_2<2, 0b110000, - (outs), (ins IntRegs:$b, i32imm:$c), - "wr $b, $c, %y", []>; - +let Defs = [Y] in { + def WRYrr : F3_1<2, 0b110000, + (outs), (ins IntRegs:$b, IntRegs:$c), + "wr $b, $c, %y", []>; + def WRYri : F3_2<2, 0b110000, + (outs), (ins IntRegs:$b, i32imm:$c), + "wr $b, $c, %y", []>; +} // Convert Integer to Floating-point Instructions, p. 141 def FITOS : F3_3<2, 0b110100, 0b011000100, (outs FPRegs:$dst), (ins FPRegs:$src), Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td?rev=122607&r1=122606&r2=122607&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td Tue Dec 28 14:39:17 2010 @@ -45,6 +45,9 @@ def ICC : SparcCtrlReg<"ICC">; def FCC : SparcCtrlReg<"FCC">; +// Y register +def Y : SparcCtrlReg<"Y">; + // Integer registers def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>; def G1 : Ri< 1, "G1">, DwarfRegNum<[1]>; From zwarich at apple.com Tue Dec 28 14:46:27 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 12:46:27 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> References: <20101228104933.E73A82A6C12C@llvm.org> <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> Message-ID: <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> On Dec 28, 2010, at 11:14 AM, Bob Wilson wrote: > On Dec 28, 2010, at 2:49 AM, Cameron Zwarich wrote: > >> Author: zwarich >> Date: Tue Dec 28 04:49:33 2010 >> New Revision: 122596 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122596&view=rev >> Log: >> Avoid iterating every operand of an instruction in StrongPHIElimination, since >> we are only interested in the defs when discovering interferences. >> >> This is a 28% speedup running StrongPHIElimination on 403.gcc. >> >> Modified: >> llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >> >> Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122596&r1=122595&r2=122596&view=diff >> ============================================================================== >> --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) >> +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Dec 28 04:49:33 2010 >> @@ -471,10 +471,9 @@ >> DenseMap& ImmediateDominatingParent) { >> for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end(); >> BBI != BBE; ++BBI) { >> - for (unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) { >> - MachineOperand& MO = BBI->getOperand(i); >> - if (!MO.isReg() || !MO.isDef()) >> - continue; >> + for (MachineInstr::const_mop_iterator I = BBI->operands_begin(), >> + E = BBI->operands_end(); I != E && I->isReg() && I->isDef(); ++I) { >> + const MachineOperand& MO = *I; > > This is relying on the register def operands being first. I'm not sure that's always true. OptionalDefOperands, like cc_out for ARM, may come later in the operand list. Aren't optional defs only for physical registers? This code is only interested in defs of registers that appear in phis. Cameron From stoklund at 2pi.dk Tue Dec 28 14:51:54 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 28 Dec 2010 12:51:54 -0800 Subject: [llvm-commits] [llvm] r122581 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp In-Reply-To: <918BD683-B01D-4C80-8ACF-70F8852DD0F5@apple.com> References: <20101227051723.525822A6C12C@llvm.org> <9BA8C891-0699-4BA1-A7BD-85875BC7CC10@2pi.dk> <0DA2AB59-C261-4812-BE75-DC610CA59CAC@apple.com> <918BD683-B01D-4C80-8ACF-70F8852DD0F5@apple.com> Message-ID: <2D9BDD22-8226-4CFE-8C6B-332577D416CF@2pi.dk> On Dec 27, 2010, at 5:43 PM, Cameron Zwarich wrote: > On Dec 27, 2010, at 4:11 PM, Jakob Stoklund Olesen wrote: > >> >> On Dec 27, 2010, at 1:56 PM, Cameron Zwarich wrote: >> >>> On Dec 27, 2010, at 1:30 PM, Jakob Stoklund Olesen wrote: >>> >>>>> + if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) { >>>> >>>> One thing is still missing: In this case, it is also legal for the live interval not to be live out of the predecessor. That can happen if a PHI operand was . >>> >>> What's an easy test-case for this? I don't think I saw it trigger on any of the existing tests. >> >> It usually shows up when you are using bugpoint. It tends to insert lots of undefs. > > There's one in CodeGen/X86/2008-05-21-CoalescerBug.ll, but it never triggers the false error. After phi elimination (either normal or strong), there is no live range or VN for the undef value, so the error is never emitted. You get this code after coalescing: ********** INTERVALS ********** %reg16393,0.000000e+00 = [76d,96L:0)[96L,188d:1) 0 at 76d-phikill 1 at 96L-phidef %reg16385,0.000000e+00 = [48L,76d:0)[100d,152L:0) 0 at 100d %reg16392,0.000000e+00 = [12d,48L:0)[60d,96L:2)[96L,100d:1) 0 at 12d-phikill 1 at 96L-phidef 2 at 60d-phikill %reg16394,0.000000e+00 = [4d,48L:0)[52d,96L:2)[96L,156d:1) 0 at 4d-phikill 1 at 96L-phidef 2 at 52d-phikill ********** MACHINEINSTRS ********** # Machine code for function tree_redirect_edge_and_branch: Frame Objects: fi#-2: size=4, align=4, fixed, at location [SP+8] fi#-1: size=4, align=16, fixed, at location [SP+4] 0L BB#0: derived from LLVM BB %entry 4L %reg16394 = MOV8ri 1; GR8:%reg16394 12L %reg16392 = MOV32r0 %EFLAGS; GR32:%reg16392 36L JMP_4 Successors according to CFG: BB#2 48L BB#1: derived from LLVM BB %bb483 Predecessors according to CFG: BB#2 52L %reg16394 = MOV8r0 %EFLAGS; GR8:%reg16394 60L %reg16392 = MOV32rm %reg0, 1, %reg0, 0, %reg0; mem:LD4[null] GR32:%reg16392 76L %reg16393 = COPY %reg16385; GR32:%reg16393,16385 Successors according to CFG: BB#2 96L BB#2: derived from LLVM BB %bb497 Predecessors according to CFG: BB#0 BB#1 100L %reg16385 = COPY %reg16392; GR32:%reg16385,16392 124L TEST8ri %reg16394, 1, %EFLAGS; GR8:%reg16394 132L JNE_4 , %EFLAGS 140L JMP_4 Successors according to CFG: BB#1 BB#3 Note the live range for %reg16393: Valno 0 is live out of BB#1, but there is no value live out of BB#0. I don't know why the verifier fails to falsely report this. /jakob -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/b74627e7/attachment.bin From stoklund at 2pi.dk Tue Dec 28 14:55:23 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 28 Dec 2010 12:55:23 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> References: <20101228104933.E73A82A6C12C@llvm.org> <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> Message-ID: <8443CA3E-D7F9-4DE1-B8FD-C25AB0C36CE0@2pi.dk> On Dec 28, 2010, at 12:46 PM, Cameron Zwarich wrote: > On Dec 28, 2010, at 11:14 AM, Bob Wilson wrote: > >> On Dec 28, 2010, at 2:49 AM, Cameron Zwarich wrote: >>> - for (unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) { >>> - MachineOperand& MO = BBI->getOperand(i); >>> - if (!MO.isReg() || !MO.isDef()) >>> - continue; >>> + for (MachineInstr::const_mop_iterator I = BBI->operands_begin(), >>> + E = BBI->operands_end(); I != E && I->isReg() && I->isDef(); ++I) { >>> + const MachineOperand& MO = *I; >> >> This is relying on the register def operands being first. I'm not sure that's always true. OptionalDefOperands, like cc_out for ARM, may come later in the operand list. > > Aren't optional defs only for physical registers? This code is only interested in defs of registers that appear in phis. I wouldn't count on it, there are also variadic instructions. Even if no current targets produce such instructions before register allocation, future targets might. /jakob -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/b3c2e861/attachment.bin From zwarich at apple.com Tue Dec 28 15:03:00 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 13:03:00 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <8443CA3E-D7F9-4DE1-B8FD-C25AB0C36CE0@2pi.dk> References: <20101228104933.E73A82A6C12C@llvm.org> <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> <8443CA3E-D7F9-4DE1-B8FD-C25AB0C36CE0@2pi.dk> Message-ID: <153E5FFF-5A54-4B05-A7B2-ED1484022A54@apple.com> On Dec 28, 2010, at 12:55 PM, Jakob Stoklund Olesen wrote: > On Dec 28, 2010, at 12:46 PM, Cameron Zwarich wrote: > >> On Dec 28, 2010, at 11:14 AM, Bob Wilson wrote: >> >>> On Dec 28, 2010, at 2:49 AM, Cameron Zwarich wrote: >>>> - for (unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) { >>>> - MachineOperand& MO = BBI->getOperand(i); >>>> - if (!MO.isReg() || !MO.isDef()) >>>> - continue; >>>> + for (MachineInstr::const_mop_iterator I = BBI->operands_begin(), >>>> + E = BBI->operands_end(); I != E && I->isReg() && I->isDef(); ++I) { >>>> + const MachineOperand& MO = *I; >>> >>> This is relying on the register def operands being first. I'm not sure that's always true. OptionalDefOperands, like cc_out for ARM, may come later in the operand list. >> >> Aren't optional defs only for physical registers? This code is only interested in defs of registers that appear in phis. > > I wouldn't count on it, there are also variadic instructions. > > Even if no current targets produce such instructions before register allocation, future targets might. What's the format of variadic instructions? Wouldn't all of the explicit defs appear at the front? Cameron From stoklund at 2pi.dk Tue Dec 28 15:28:16 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 28 Dec 2010 13:28:16 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <153E5FFF-5A54-4B05-A7B2-ED1484022A54@apple.com> References: <20101228104933.E73A82A6C12C@llvm.org> <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> <8443CA3E-D7F9-4DE1-B8FD-C25AB0C36CE0@2pi.dk> <153E5FFF-5A54-4B05-A7B2-ED1484022A54@apple.com> Message-ID: On Dec 28, 2010, at 1:03 PM, Cameron Zwarich wrote: > On Dec 28, 2010, at 12:55 PM, Jakob Stoklund Olesen wrote: > >> On Dec 28, 2010, at 12:46 PM, Cameron Zwarich wrote: >> >>> On Dec 28, 2010, at 11:14 AM, Bob Wilson wrote: >>> >>>> On Dec 28, 2010, at 2:49 AM, Cameron Zwarich wrote: >>>>> - for (unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) { >>>>> - MachineOperand& MO = BBI->getOperand(i); >>>>> - if (!MO.isReg() || !MO.isDef()) >>>>> - continue; >>>>> + for (MachineInstr::const_mop_iterator I = BBI->operands_begin(), >>>>> + E = BBI->operands_end(); I != E && I->isReg() && I->isDef(); ++I) { >>>>> + const MachineOperand& MO = *I; >>>> >>>> This is relying on the register def operands being first. I'm not sure that's always true. OptionalDefOperands, like cc_out for ARM, may come later in the operand list. >>> >>> Aren't optional defs only for physical registers? This code is only interested in defs of registers that appear in phis. >> >> I wouldn't count on it, there are also variadic instructions. >> >> Even if no current targets produce such instructions before register allocation, future targets might. > > > What's the format of variadic instructions? Wouldn't all of the explicit defs appear at the front? No, they look like: , , , The variadic operands can be uses or defs. For instance, ARM's LDM instructions have a variable number of defs. /jakob -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/53fe11ef/attachment-0001.bin From zwarich at apple.com Tue Dec 28 15:38:04 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 13:38:04 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: References: <20101228104933.E73A82A6C12C@llvm.org> <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> <8443CA3E-D7F9-4DE1-B8FD-C25AB0C36CE0@2pi.dk> <153E5FFF-5A54-4B05-A7B2-ED1484022A54@apple.com> Message-ID: <90F15B7D-C61B-47E0-BC4A-5139EB28AE56@apple.com> On Dec 28, 2010, at 1:28 PM, Jakob Stoklund Olesen wrote: > On Dec 28, 2010, at 1:03 PM, Cameron Zwarich wrote: > >> What's the format of variadic instructions? Wouldn't all of the explicit defs appear at the front? > > No, they look like: > > , , , > > The variadic operands can be uses or defs. For instance, ARM's LDM instructions have a variable number of defs. Ah, okay. I could check whether the instruction is variadic before bailing out early after the last explicit def, but maybe I should just roll it out for now. 28% is a nice speedup though. ;-) Cameron -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/6c2fbe32/attachment.html From zwarich at apple.com Tue Dec 28 16:47:32 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 14:47:32 -0800 Subject: [llvm-commits] [llvm] r122581 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp In-Reply-To: <2D9BDD22-8226-4CFE-8C6B-332577D416CF@2pi.dk> References: <20101227051723.525822A6C12C@llvm.org> <9BA8C891-0699-4BA1-A7BD-85875BC7CC10@2pi.dk> <0DA2AB59-C261-4812-BE75-DC610CA59CAC@apple.com> <918BD683-B01D-4C80-8ACF-70F8852DD0F5@apple.com> <2D9BDD22-8226-4CFE-8C6B-332577D416CF@2pi.dk> Message-ID: <0FAB6694-3C19-4B2F-9633-6DC0589490E1@apple.com> On Dec 28, 2010, at 12:51 PM, Jakob Stoklund Olesen wrote: > On Dec 27, 2010, at 5:43 PM, Cameron Zwarich wrote: > >> On Dec 27, 2010, at 4:11 PM, Jakob Stoklund Olesen wrote: >> >> There's one in CodeGen/X86/2008-05-21-CoalescerBug.ll, but it never triggers the false error. After phi elimination (either normal or strong), there is no live range or VN for the undef value, so the error is never emitted. > > You get this code after coalescing: > > ********** INTERVALS ********** > %reg16393,0.000000e+00 = [76d,96L:0)[96L,188d:1) 0 at 76d-phikill 1 at 96L-phidef > %reg16385,0.000000e+00 = [48L,76d:0)[100d,152L:0) 0 at 100d > %reg16392,0.000000e+00 = [12d,48L:0)[60d,96L:2)[96L,100d:1) 0 at 12d-phikill 1 at 96L-phidef 2 at 60d-phikill > %reg16394,0.000000e+00 = [4d,48L:0)[52d,96L:2)[96L,156d:1) 0 at 4d-phikill 1 at 96L-phidef 2 at 52d-phikill > ********** MACHINEINSTRS ********** > # Machine code for function tree_redirect_edge_and_branch: > Frame Objects: > fi#-2: size=4, align=4, fixed, at location [SP+8] > fi#-1: size=4, align=16, fixed, at location [SP+4] > > 0L BB#0: derived from LLVM BB %entry > 4L %reg16394 = MOV8ri 1; GR8:%reg16394 > 12L %reg16392 = MOV32r0 %EFLAGS; GR32:%reg16392 > 36L JMP_4 > Successors according to CFG: BB#2 > > 48L BB#1: derived from LLVM BB %bb483 > Predecessors according to CFG: BB#2 > 52L %reg16394 = MOV8r0 %EFLAGS; GR8:%reg16394 > 60L %reg16392 = MOV32rm %reg0, 1, %reg0, 0, %reg0; mem:LD4[null] GR32:%reg16392 > 76L %reg16393 = COPY %reg16385; GR32:%reg16393,16385 > Successors according to CFG: BB#2 > > 96L BB#2: derived from LLVM BB %bb497 > Predecessors according to CFG: BB#0 BB#1 > 100L %reg16385 = COPY %reg16392; GR32:%reg16385,16392 > 124L TEST8ri %reg16394, 1, %EFLAGS; GR8:%reg16394 > 132L JNE_4 , %EFLAGS > 140L JMP_4 > Successors according to CFG: BB#1 BB#3 > > Note the live range for %reg16393: Valno 0 is live out of BB#1, but there is no value live out of BB#0. > > I don't know why the verifier fails to falsely report this. Here's a patch that fixes both issues. It won't catch any more errors, but it is arguably a bit clearer. Should I land it? -------------- next part -------------- A non-text attachment was scrubbed... Name: skip-phidef.patch Type: application/octet-stream Size: 2120 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/00ebcb16/attachment.obj -------------- next part -------------- Cameron From stoklund at 2pi.dk Tue Dec 28 17:05:03 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 28 Dec 2010 15:05:03 -0800 Subject: [llvm-commits] [llvm] r122581 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp In-Reply-To: <0FAB6694-3C19-4B2F-9633-6DC0589490E1@apple.com> References: <20101227051723.525822A6C12C@llvm.org> <9BA8C891-0699-4BA1-A7BD-85875BC7CC10@2pi.dk> <0DA2AB59-C261-4812-BE75-DC610CA59CAC@apple.com> <918BD683-B01D-4C80-8ACF-70F8852DD0F5@apple.com> <2D9BDD22-8226-4CFE-8C6B-332577D416CF@2pi.dk> <0FAB6694-3C19-4B2F-9633-6DC0589490E1@apple.com> Message-ID: <654776B9-D9ED-447D-9559-F0B4AE9E8256@2pi.dk> On Dec 28, 2010, at 2:47 PM, Cameron Zwarich wrote: > On Dec 28, 2010, at 12:51 PM, Jakob Stoklund Olesen wrote: > >> On Dec 27, 2010, at 5:43 PM, Cameron Zwarich wrote: >> >>> On Dec 27, 2010, at 4:11 PM, Jakob Stoklund Olesen wrote: >>> >>> There's one in CodeGen/X86/2008-05-21-CoalescerBug.ll, but it never triggers the false error. After phi elimination (either normal or strong), there is no live range or VN for the undef value, so the error is never emitted. > > Here's a patch that fixes both issues. It won't catch any more errors, but it is arguably a bit clearer. Should I land it? Please do, thanks! /jakob -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/fd31977d/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/fd31977d/attachment.bin From zwarich at apple.com Tue Dec 28 17:02:56 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 23:02:56 -0000 Subject: [llvm-commits] [llvm] r122608 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101228230256.A4FA82A6C12C@llvm.org> Author: zwarich Date: Tue Dec 28 17:02:56 2010 New Revision: 122608 URL: http://llvm.org/viewvc/llvm-project?rev=122608&view=rev Log: Revert the optimization in r122596. It is correct for all current targets, but it relies on assumptions that may not be true in the future. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122608&r1=122607&r2=122608&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Dec 28 17:02:56 2010 @@ -472,9 +472,16 @@ for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end(); BBI != BBE; ++BBI) { for (MachineInstr::const_mop_iterator I = BBI->operands_begin(), - E = BBI->operands_end(); I != E && I->isReg() && I->isDef(); ++I) { + E = BBI->operands_end(); I != E; ++I) { const MachineOperand& MO = *I; + // FIXME: This would be faster if it were possible to bail out of checking + // an instruction's operands after the explicit defs, but this is incorrect + // for variadic instructions, which may appear before register allocation + // in the future. + if (!MO.isReg() || !MO.isDef()) + continue; + unsigned DestReg = MO.getReg(); if (!DestReg || !TargetRegisterInfo::isVirtualRegister(DestReg)) continue; From stoklund at 2pi.dk Tue Dec 28 17:08:16 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 28 Dec 2010 15:08:16 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <90F15B7D-C61B-47E0-BC4A-5139EB28AE56@apple.com> References: <20101228104933.E73A82A6C12C@llvm.org> <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> <8443CA3E-D7F9-4DE1-B8FD-C25AB0C36CE0@2pi.dk> <153E5FFF-5A54-4B05-A7B2-ED1484022A54@apple.com> <90F15B7D-C61B-47E0-BC4A-5139EB28AE56@apple.com> Message-ID: <72680009-B7D5-4298-AAB4-929D31EE10C5@2pi.dk> On Dec 28, 2010, at 1:38 PM, Cameron Zwarich wrote: > On Dec 28, 2010, at 1:28 PM, Jakob Stoklund Olesen wrote: > >> On Dec 28, 2010, at 1:03 PM, Cameron Zwarich wrote: >> >>> What's the format of variadic instructions? Wouldn't all of the explicit defs appear at the front? >> >> No, they look like: >> >> , , , >> >> The variadic operands can be uses or defs. For instance, ARM's LDM instructions have a variable number of defs. > > Ah, okay. I could check whether the instruction is variadic before bailing out early after the last explicit def, but maybe I should just roll it out for now. 28% is a nice speedup though. ;-) Maybe you are going about this the wrong way. The majority of virtual registers are never involved with PHIs, so StrongPHIElimination shouldn't have to look at them at all. Yet, here you are iterating over all operands in the machine code. Perhaps you could keep track of the virtual registers that are used or defined by PHI instructions and use their use-def chains instead? /jakob -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/f0f5ac27/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/f0f5ac27/attachment.bin From zwarich at apple.com Tue Dec 28 17:31:33 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 15:31:33 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <72680009-B7D5-4298-AAB4-929D31EE10C5@2pi.dk> References: <20101228104933.E73A82A6C12C@llvm.org> <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> <8443CA3E-D7F9-4DE1-B8FD-C25AB0C36CE0@2pi.dk> <153E5FFF-5A54-4B05-A7B2-ED1484022A54@apple.com> <90F15B7D-C61B-47E0-BC4A-5139EB28AE56@apple.com> <72680009-B7D5-4298-AAB4-929D31EE10C5@2pi.dk> Message-ID: <4B117FE9-BA19-4F37-BDE4-C9ECC57166E0@apple.com> On Dec 28, 2010, at 3:08 PM, Jakob Stoklund Olesen wrote: > On Dec 28, 2010, at 1:38 PM, Cameron Zwarich wrote: > >> Ah, okay. I could check whether the instruction is variadic before bailing out early after the last explicit def, but maybe I should just roll it out for now. 28% is a nice speedup though. ;-) > > Maybe you are going about this the wrong way. The majority of virtual registers are never involved with PHIs, so StrongPHIElimination shouldn't have to look at them at all. Yet, here you are iterating over all operands in the machine code. > > Perhaps you could keep track of the virtual registers that are used or defined by PHI instructions and use their use-def chains instead? It needs to visit the instructions in dominance order. I guess I could build parallel blocks of instructions containing only the defs of variables appearing in phis. I suspect that the overhead of doing this would exceed any potential benefit. At first glance, you need to maintain dominance order inside of each basic block as well, but I am pretty sure that the code could be modified to work without this constraint. Maybe I'll try it just to see. Cameron From rafael.espindola at gmail.com Tue Dec 28 17:38:03 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 28 Dec 2010 23:38:03 -0000 Subject: [llvm-commits] [llvm] r122609 - in /llvm/trunk: lib/MC/MCDwarf.cpp test/MC/ELF/cfi-zero-addr-delta.s Message-ID: <20101228233803.6F4B32A6C12C@llvm.org> Author: rafael Date: Tue Dec 28 17:38:03 2010 New Revision: 122609 URL: http://llvm.org/viewvc/llvm-project?rev=122609&view=rev Log: Don't produce a "DW_CFA_advance_loc 0". Added: llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s Modified: llvm/trunk/lib/MC/MCDwarf.cpp Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122609&r1=122608&r2=122609&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Dec 28 17:38:03 2010 @@ -780,7 +780,8 @@ void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS) { // FIXME: Assumes the code alignment factor is 1. - if (isUIntN(6, AddrDelta)) { + if (AddrDelta == 0) { + } else if (isUIntN(6, AddrDelta)) { uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta; OS << Opcode; } else if (isUInt<8>(AddrDelta)) { Added: llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s?rev=122609&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s (added) +++ llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s Tue Dec 28 17:38:03 2010 @@ -0,0 +1,48 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +// Test that we don't produce a DW_CFA_advance_loc 0 + +f: + .cfi_startproc + nop + .cfi_def_cfa_offset 16 + nop + .cfi_remember_state + .cfi_def_cfa_offset 8 + nop + .cfi_restore_state + nop + .cfi_endproc + +// CHECK: (('sh_name', 0x00000012) # '.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000001) +// CHECK-NEXT: ('sh_flags', 0x00000002) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000048) +// CHECK-NEXT: ('sh_size', 0x00000038) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 1c000000 1c000000 00000000 04000000 00410e10 410a0e08 410b0000 00000000') +// CHECK-NEXT: ), + +// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000160) +// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_info', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) +// CHECK-NEXT: ), From venkatra at cs.wisc.edu Tue Dec 28 16:18:01 2010 From: venkatra at cs.wisc.edu (Venkatraman Govindaraju) Date: Tue, 28 Dec 2010 16:18:01 -0600 Subject: [llvm-commits] [PATCH] SPARC backend - Passing arguments Message-ID: Hello, This patch makes the SPARC backend to generate correct assembly for the code below. Before the changes, the seventh parameter (double %arg1) passed through stack using "std %f0, [%sp+92]" (store-double) instruction. Since %sp+92 is not aligned to double word, the instruction causes a "Bus Error". Please let me know whether it is okay to commit. Thanks, Venkatraman ; ModuleID = 'arg7.c' target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f128:64:64-n32" target triple = "sparc-sun-solaris2.11" @d = global double 0x40934CEFDB09A672 define i32 @test1(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, double %arg1) nounwind readnone noinline { entry: ret i32 0 } define i32 @main() nounwind readonly { entry: %0 = load double* @d, align 8 %1 = tail call i32 @test1(i32 1, i32 2, i32 3, i32 4, i32 5, i32 10, double %0) nounwind noinline ret i32 %1 } -------------- next part -------------- A non-text attachment was scrubbed... Name: sparc-arg6.patch Type: text/x-patch Size: 4857 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101228/889e549b/attachment.bin From zwarich at apple.com Tue Dec 28 17:45:38 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 23:45:38 -0000 Subject: [llvm-commits] [llvm] r122610 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp Message-ID: <20101228234538.AF2012A6C12C@llvm.org> Author: zwarich Date: Tue Dec 28 17:45:38 2010 New Revision: 122610 URL: http://llvm.org/viewvc/llvm-project?rev=122610&view=rev Log: Simplify some code in MachineVerifier that was doing the correct thing, but not in the most obvious way. Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineVerifier.cpp?rev=122610&r1=122609&r2=122610&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineVerifier.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp Tue Dec 28 17:45:38 2010 @@ -1118,8 +1118,8 @@ // Now check all the basic blocks in this live segment. MachineFunction::const_iterator MFI = MBB; - // Is LI live-in to MBB and not a PHIDef? - if (I->start == VNI->def) { + // Is this live range the beginning of a non-PHIDef VN? + if (I->start == VNI->def && !VNI->isPHIDef()) { // Not live-in to any blocks. if (MBB == EndMBB) continue; @@ -1141,16 +1141,9 @@ PE = MFI->pred_end(); PI != PE; ++PI) { SlotIndex PEnd = LiveInts->getMBBEndIdx(*PI).getPrevSlot(); const VNInfo *PVNI = LI.getVNInfoAt(PEnd); - if (!PVNI) { - report("Register not marked live out of predecessor", *PI); - *OS << "Valno #" << VNI->id << " live into BB#" << MFI->getNumber() - << '@' << LiveInts->getMBBStartIdx(MFI) << ", not live at " - << PEnd << " in " << LI << '\n'; - continue; - } if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) { - if (!PVNI->hasPHIKill()) { + if (PVNI && !PVNI->hasPHIKill()) { report("Value live out of predecessor doesn't have PHIKill", MF); *OS << "Valno #" << PVNI->id << " live out of BB#" << (*PI)->getNumber() << '@' << PEnd @@ -1162,6 +1155,14 @@ continue; } + if (!PVNI) { + report("Register not marked live out of predecessor", *PI); + *OS << "Valno #" << VNI->id << " live into BB#" << MFI->getNumber() + << '@' << LiveInts->getMBBStartIdx(MFI) << ", not live at " + << PEnd << " in " << LI << '\n'; + continue; + } + if (PVNI != VNI) { report("Different value live out of predecessor", *PI); *OS << "Valno #" << PVNI->id << " live out of BB#" From rafael.espindola at gmail.com Tue Dec 28 18:09:59 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 29 Dec 2010 00:09:59 -0000 Subject: [llvm-commits] [llvm] r122611 - in /llvm/trunk: lib/MC/MCStreamer.cpp test/MC/ELF/cfi-offset.s Message-ID: <20101229000959.CCC7D2A6C12C@llvm.org> Author: rafael Date: Tue Dec 28 18:09:59 2010 New Revision: 122611 URL: http://llvm.org/viewvc/llvm-project?rev=122611&view=rev Log: Initial .cfi_offset implementation. Added: llvm/trunk/test/MC/ELF/cfi-offset.s Modified: llvm/trunk/lib/MC/MCStreamer.cpp Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122611&r1=122610&r2=122611&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Dec 28 18:09:59 2010 @@ -191,6 +191,13 @@ bool MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + MCSymbol *Label = getContext().CreateTempSymbol(); + EmitLabel(Label); + MachineLocation Dest(Register, Offset); + MachineLocation Source(Register, Offset); + MCCFIInstruction Instruction(Label, Dest, Source); + CurFrame->Instructions.push_back(Instruction); return false; } Added: llvm/trunk/test/MC/ELF/cfi-offset.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-offset.s?rev=122611&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-offset.s (added) +++ llvm/trunk/test/MC/ELF/cfi-offset.s Tue Dec 28 18:09:59 2010 @@ -0,0 +1,42 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +f: + .cfi_startproc + nop + .cfi_offset 6, -16 + nop + .cfi_endproc + +// CHECK: (('sh_name', 0x00000012) # '.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000001) +// CHECK-NEXT: ('sh_flags', 0x00000002) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000048) +// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00418602 00000000') +// CHECK-NEXT: ), + + +// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000158) +// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_info', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) +// CHECK-NEXT: ), From rafael.espindola at gmail.com Tue Dec 28 18:26:06 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 29 Dec 2010 00:26:06 -0000 Subject: [llvm-commits] [llvm] r122612 - in /llvm/trunk: lib/MC/MCStreamer.cpp test/MC/ELF/cfi-def-cfa-register.s Message-ID: <20101229002607.055202A6C12C@llvm.org> Author: rafael Date: Tue Dec 28 18:26:06 2010 New Revision: 122612 URL: http://llvm.org/viewvc/llvm-project?rev=122612&view=rev Log: Implement cfi_def_cfa_register. Added: llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s Modified: llvm/trunk/lib/MC/MCStreamer.cpp Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122612&r1=122611&r2=122612&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Dec 28 18:26:06 2010 @@ -186,6 +186,14 @@ bool MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + MCSymbol *Label = getContext().CreateTempSymbol(); + EmitLabel(Label); + MachineLocation Dest(Register); + MachineLocation Source(MachineLocation::VirtualFP); + MCCFIInstruction Instruction(Label, Dest, Source); + CurFrame->Instructions.push_back(Instruction); + return false; return false; } Added: llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s?rev=122612&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s (added) +++ llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s Tue Dec 28 18:26:06 2010 @@ -0,0 +1,41 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +f: + .cfi_startproc + nop + .cfi_def_cfa_register 6 + nop + .cfi_endproc + +// CHECK: (('sh_name', 0x00000012) # '.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000001) +// CHECK-NEXT: ('sh_flags', 0x00000002) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000048) +// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00410d06 00000000') +// CHECK-NEXT: ), + +// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000158) +// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_info', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) +// CHECK-NEXT: ), From sabre at nondot.org Tue Dec 28 19:33:36 2010 From: sabre at nondot.org (Chris Lattner) Date: Wed, 29 Dec 2010 01:33:36 -0000 Subject: [llvm-commits] [llvm] r122613 - in /llvm/trunk: lib/VMCore/ConstantFold.cpp unittests/VMCore/ConstantsTest.cpp Message-ID: <20101229013336.8862F2A6C12C@llvm.org> Author: lattner Date: Tue Dec 28 19:33:36 2010 New Revision: 122613 URL: http://llvm.org/viewvc/llvm-project?rev=122613&view=rev Log: fix PR8867: a crash handling fp128. Thanks to Nick for the testcase. Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp llvm/trunk/unittests/VMCore/ConstantsTest.cpp Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=122613&r1=122612&r2=122613&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Tue Dec 28 19:33:36 2010 @@ -637,7 +637,7 @@ case Instruction::SIToFP: if (ConstantInt *CI = dyn_cast(V)) { APInt api = CI->getValue(); - APFloat apf(APInt::getNullValue(DestTy->getPrimitiveSizeInBits())); + APFloat apf(APInt::getNullValue(DestTy->getPrimitiveSizeInBits()), true); (void)apf.convertFromAPInt(api, opc==Instruction::SIToFP, APFloat::rmNearestTiesToEven); Modified: llvm/trunk/unittests/VMCore/ConstantsTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/ConstantsTest.cpp?rev=122613&r1=122612&r2=122613&view=diff ============================================================================== --- llvm/trunk/unittests/VMCore/ConstantsTest.cpp (original) +++ llvm/trunk/unittests/VMCore/ConstantsTest.cpp Tue Dec 28 19:33:36 2010 @@ -109,5 +109,14 @@ EXPECT_EQ(0x3b, ConstantInt::get(Int8Ty, 0x13b)->getSExtValue()); } +TEST(ConstantsTest, FP128Test) { + const Type *FP128Ty = Type::getFP128Ty(getGlobalContext()); + + const IntegerType *Int128Ty = Type::getIntNTy(getGlobalContext(), 128); + Constant *Zero128 = Constant::getNullValue(Int128Ty); + Constant *X = ConstantExpr::getUIToFP(Zero128, FP128Ty); + EXPECT_TRUE(isa(X)); +} + } // end anonymous namespace } // end namespace llvm From clattner at apple.com Tue Dec 28 19:39:35 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 28 Dec 2010 17:39:35 -0800 Subject: [llvm-commits] [PATCH] SPARC backend - Passing arguments In-Reply-To: References: Message-ID: <5D6D6475-A5C8-4D13-8C5B-0F5368C3BC3B@apple.com> On Dec 28, 2010, at 2:18 PM, Venkatraman Govindaraju wrote: > Hello, > > This patch makes the SPARC backend to generate correct assembly for > the code below. Before the changes, the seventh parameter (double > %arg1) passed through stack using "std %f0, [%sp+92]" (store-double) > instruction. Since %sp+92 is not aligned to double word, the > instruction causes a "Bus Error". > > Please let me know whether it is okay to commit. Looks good to me. You seem to have a good handle on the SPARC backend, please feel free to commit without pre-review with nice testcases like this. I'll review the patches after the fact. Thanks Venkatraman! -Chris > > Thanks, > Venkatraman > > > ; ModuleID = 'arg7.c' > target datalayout = > "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f128:64:64-n32" > target triple = "sparc-sun-solaris2.11" > > @d = global double 0x40934CEFDB09A672 > > define i32 @test1(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, > double %arg1) nounwind readnone noinline { > entry: > ret i32 0 > } > > define i32 @main() nounwind readonly { > entry: > %0 = load double* @d, align 8 > %1 = tail call i32 @test1(i32 1, i32 2, i32 3, i32 4, i32 5, i32 10, > double %0) nounwind noinline > ret i32 %1 > } > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From rafael.espindola at gmail.com Tue Dec 28 19:42:57 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 29 Dec 2010 01:42:57 -0000 Subject: [llvm-commits] [llvm] r122614 - in /llvm/trunk: include/llvm/MC/MCStreamer.h lib/MC/MCDwarf.cpp lib/MC/MCParser/AsmParser.cpp lib/MC/MCStreamer.cpp test/MC/ELF/cfi-def-cfa.s Message-ID: <20101229014257.213242A6C12C@llvm.org> Author: rafael Date: Tue Dec 28 19:42:56 2010 New Revision: 122614 URL: http://llvm.org/viewvc/llvm-project?rev=122614&view=rev Log: Implement cfi_def_cfa. Also don't convert to dwarf reg numbers twice. Looks like 6 is a fixed point of that and so the previous tests were OK :-) Added: llvm/trunk/test/MC/ELF/cfi-def-cfa.s Modified: llvm/trunk/include/llvm/MC/MCStreamer.h llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCParser/AsmParser.cpp llvm/trunk/lib/MC/MCStreamer.cpp Modified: llvm/trunk/include/llvm/MC/MCStreamer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=122614&r1=122613&r2=122614&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCStreamer.h (original) +++ llvm/trunk/include/llvm/MC/MCStreamer.h Tue Dec 28 19:42:56 2010 @@ -395,6 +395,7 @@ virtual bool EmitCFIStartProc(); virtual bool EmitCFIEndProc(); + virtual bool EmitCFIDefCfa(int64_t Register, int64_t Offset); virtual bool EmitCFIDefCfaOffset(int64_t Offset); virtual bool EmitCFIDefCfaRegister(int64_t Register); virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122614&r1=122613&r2=122614&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Dec 28 19:42:56 2010 @@ -440,10 +440,7 @@ } static void EmitCFIInstruction(MCStreamer &Streamer, - const MCCFIInstruction &Instr, - bool isEH) { - MCContext &context = Streamer.getContext(); - const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); + const MCCFIInstruction &Instr) { int dataAlignmentFactor = getDataAlignmentFactor(Streamer); switch (Instr.getOperation()) { @@ -459,8 +456,7 @@ Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1); } else { Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); - Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(), - isEH)); + Streamer.EmitULEB128IntValue(Src.getReg()); } Streamer.EmitULEB128IntValue(-Src.getOffset(), 1); @@ -470,11 +466,11 @@ if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) { assert(Dst.isReg() && "Machine move not supported yet."); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); - Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Dst.getReg(), isEH)); + Streamer.EmitULEB128IntValue(Dst.getReg()); return; } - unsigned Reg = asmInfo.getDwarfRegNum(Src.getReg(), isEH); + unsigned Reg = Src.getReg(); int Offset = Dst.getOffset() / dataAlignmentFactor; if (Offset < 0) { @@ -505,7 +501,7 @@ /// frame. static void EmitCFIInstructions(MCStreamer &streamer, const std::vector &Instrs, - MCSymbol *BaseLabel, bool isEH) { + MCSymbol *BaseLabel) { for (unsigned i = 0, N = Instrs.size(); i < N; ++i) { const MCCFIInstruction &Instr = Instrs[i]; MCSymbol *Label = Instr.getLabel(); @@ -521,7 +517,7 @@ } } - EmitCFIInstruction(streamer, Instr, isEH); + EmitCFIInstruction(streamer, Instr); } } @@ -566,6 +562,17 @@ } } +static const MachineLocation TranslateMachineLocation( + const TargetAsmInfo &AsmInfo, + const MachineLocation &Loc) { + unsigned Reg = Loc.getReg() == MachineLocation::VirtualFP ? + MachineLocation::VirtualFP : + unsigned(AsmInfo.getDwarfRegNum(Loc.getReg(), true)); + const MachineLocation &NewLoc = Loc.isReg() ? + MachineLocation(Reg) : MachineLocation(Reg, Loc.getOffset()); + return NewLoc; +} + static const MCSymbol &EmitCIE(MCStreamer &streamer, const MCSymbol *personality, unsigned personalityEncoding, @@ -640,12 +647,16 @@ std::vector Instructions; for (int i = 0, n = Moves.size(); i != n; ++i) { - MCCFIInstruction Inst(Moves[i].getLabel(), Moves[i].getDestination(), - Moves[i].getSource()); + MCSymbol *Label = Moves[i].getLabel(); + const MachineLocation &Dst = + TranslateMachineLocation(asmInfo, Moves[i].getDestination()); + const MachineLocation &Src = + TranslateMachineLocation(asmInfo, Moves[i].getSource()); + MCCFIInstruction Inst(Label, Dst, Src); Instructions.push_back(Inst); } - EmitCFIInstructions(streamer, Instructions, NULL, true); + EmitCFIInstructions(streamer, Instructions, NULL); // Padding streamer.EmitValueToAlignment(4); @@ -694,7 +705,7 @@ streamer.EmitLabel(augmentationEnd); // Call Frame Instructions - EmitCFIInstructions(streamer, frame.Instructions, frame.Begin, true); + EmitCFIInstructions(streamer, frame.Instructions, frame.Begin); // Padding streamer.EmitValueToAlignment(4); Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122614&r1=122613&r2=122614&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Dec 28 19:42:56 2010 @@ -244,6 +244,8 @@ ".cfi_startproc"); AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>( ".cfi_endproc"); + AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>( + ".cfi_def_cfa"); AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>( ".cfi_def_cfa_offset"); AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>( @@ -278,6 +280,7 @@ bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc); + bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc); @@ -2172,6 +2175,25 @@ return getStreamer().EmitCFIEndProc(); } +/// ParseDirectiveCFIDefCfa +/// ::= .cfi_def_cfa register, offset +bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef, + SMLoc DirectiveLoc) { + int64_t Register = 0; + if (getParser().ParseAbsoluteExpression(Register)) + return true; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + + int64_t Offset = 0; + if (getParser().ParseAbsoluteExpression(Offset)) + return true; + + return getStreamer().EmitCFIDefCfa(Register, Offset); +} + /// ParseDirectiveCFIDefCfaOffset /// ::= .cfi_def_cfa_offset offset bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef, Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122614&r1=122613&r2=122614&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Dec 28 19:42:56 2010 @@ -172,6 +172,18 @@ return false; } +bool MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { + EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + MCSymbol *Label = getContext().CreateTempSymbol(); + EmitLabel(Label); + MachineLocation Dest(MachineLocation::VirtualFP); + MachineLocation Source(Register, -Offset); + MCCFIInstruction Instruction(Label, Dest, Source); + CurFrame->Instructions.push_back(Instruction); + return false; +} + bool MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { EnsureValidFrame(); MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); Added: llvm/trunk/test/MC/ELF/cfi-def-cfa.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-def-cfa.s?rev=122614&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-def-cfa.s (added) +++ llvm/trunk/test/MC/ELF/cfi-def-cfa.s Tue Dec 28 19:42:56 2010 @@ -0,0 +1,42 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +f: + .cfi_startproc + nop + .cfi_def_cfa 7, 8 + nop + .cfi_endproc + +// CHECK: (('sh_name', 0x00000012) # '.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000001) +// CHECK-NEXT: ('sh_flags', 0x00000002) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000048) +// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00410c07 08000000') +// CHECK-NEXT: ), + + +// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000158) +// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_info', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) +// CHECK-NEXT: ), From wendling at apple.com Tue Dec 28 20:10:53 2010 From: wendling at apple.com (Bill Wendling) Date: Tue, 28 Dec 2010 18:10:53 -0800 Subject: [llvm-commits] [PATCH] Add some options to configure for Cygming In-Reply-To: References: Message-ID: <4DCB677B-A351-40B3-ADDD-2E5543CBF2B3@apple.com> Hi Nakamura, These look fine to me. Go ahead and commit them, if you haven't all ready. -bw On Dec 26, 2010, at 5:31 PM, NAKAMURA Takumi wrote: > Ping. Regenerated patches attached. > > > * 0001-autoconf-PR7874-Add-disable-pthreads-to-suppress.patch.txt > > --enable-pthreads=yes by default. > It would be needed to build pthread*.dll-free binaries on mingw. > Without this patch, it would be impossible to build with > ENABLE_THREADS=1 without pthread.h and pthread*.dll, > [PR7874] > > > * 0003-autoconf-Add-disable-embed-stdcxx-to-suppress-li.patch.txt > > --enable-embed-stdcxx=yes by default. Use with --enable-shared. > By default, tools/llvm-shlib does not use stdc++.dll but link > stdc++.a included into llvm*.dll. > > Cygwin-1.7's gcc-4.4 has its own stdc++.dll and is applicable. > With --disable-embed-stdcxx, tools/llvm-shlib uses distro's stdc++.dll. > > > * 0002-configure-Regenerated-for-disable-pthreads.patch.txt > * 0004-configure-Regenerated-for-disable-embed-stdcxx.patch.txt > > Regenerated patches. > > > ...Takumi > <0001-autoconf-PR7874-Add-disable-pthreads-to-suppress.patch.txt><0002-configure-Regenerated-for-disable-pthreads.patch.txt><0003-autoconf-Add-disable-embed-stdcxx-to-suppress-li.patch.txt><0004-configure-Regenerated-for-disable-embed-stdcxx.patch.txt>_______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From wendling at apple.com Tue Dec 28 20:15:19 2010 From: wendling at apple.com (Bill Wendling) Date: Tue, 28 Dec 2010 18:15:19 -0800 Subject: [llvm-commits] [llvm] r122586 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <20101227220842.45C1A2A6C12C@llvm.org> References: <20101227220842.45C1A2A6C12C@llvm.org> Message-ID: <52B39F5D-46A8-4869-83F4-D7BA324C9493@apple.com> On Dec 27, 2010, at 2:08 PM, Cameron Zwarich wrote: > Author: zwarich > Date: Mon Dec 27 16:08:42 2010 > New Revision: 122586 > > URL: http://llvm.org/viewvc/llvm-project?rev=122586&view=rev > Log: > Change an assertion to assert what the code actually relies upon. > > Modified: > llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp > > Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122586&r1=122585&r2=122586&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) > +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Dec 27 16:08:42 2010 > @@ -283,7 +283,7 @@ > LiveInterval& DestLI = LI->getInterval(DestReg); > LiveInterval& NewLI = LI->getInterval(NewReg); > > - assert(DestLI.containsOneValue()); > + assert(DestLI.ranges.size() == 1); Could you add a string saying why it should be 1? Something like: assert(DestLI.ranges.size() == 1 && "One is the loneliest number!"); -bw From wendling at apple.com Tue Dec 28 20:23:33 2010 From: wendling at apple.com (Bill Wendling) Date: Tue, 28 Dec 2010 18:23:33 -0800 Subject: [llvm-commits] [llvm] r122612 - in /llvm/trunk: lib/MC/MCStreamer.cpp test/MC/ELF/cfi-def-cfa-register.s In-Reply-To: <20101229002607.055202A6C12C@llvm.org> References: <20101229002607.055202A6C12C@llvm.org> Message-ID: <32285F88-C8C1-4216-9873-C689898E5E92@apple.com> On Dec 28, 2010, at 4:26 PM, Rafael Espindola wrote: > Author: rafael > Date: Tue Dec 28 18:26:06 2010 > New Revision: 122612 > > URL: http://llvm.org/viewvc/llvm-project?rev=122612&view=rev > Log: > Implement cfi_def_cfa_register. > > Added: > llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s > Modified: > llvm/trunk/lib/MC/MCStreamer.cpp > > Modified: llvm/trunk/lib/MC/MCStreamer.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122612&r1=122611&r2=122612&view=diff > ============================================================================== > --- llvm/trunk/lib/MC/MCStreamer.cpp (original) > +++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Dec 28 18:26:06 2010 > @@ -186,6 +186,14 @@ > > bool MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { > EnsureValidFrame(); > + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); > + MCSymbol *Label = getContext().CreateTempSymbol(); > + EmitLabel(Label); > + MachineLocation Dest(Register); > + MachineLocation Source(MachineLocation::VirtualFP); > + MCCFIInstruction Instruction(Label, Dest, Source); > + CurFrame->Instructions.push_back(Instruction); > + return false; > return false; You have two returns here. :-) -bw From rafael.espindola at gmail.com Tue Dec 28 20:30:49 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 29 Dec 2010 02:30:49 -0000 Subject: [llvm-commits] [llvm] r122615 - in /llvm/trunk: lib/MC/MCDwarf.cpp test/MC/ELF/cfi-advance-loc2.s Message-ID: <20101229023049.943EF2A6C12C@llvm.org> Author: rafael Date: Tue Dec 28 20:30:49 2010 New Revision: 122615 URL: http://llvm.org/viewvc/llvm-project?rev=122615&view=rev Log: Fix bug when trying to output uint16_t or uint32_t. Added: llvm/trunk/test/MC/ELF/cfi-advance-loc2.s Modified: llvm/trunk/lib/MC/MCDwarf.cpp Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122615&r1=122614&r2=122615&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Dec 28 20:30:49 2010 @@ -799,11 +799,18 @@ OS << uint8_t(dwarf::DW_CFA_advance_loc1); OS << uint8_t(AddrDelta); } else if (isUInt<16>(AddrDelta)) { + // FIXME: check what is the correct behavior on a big endian machine. OS << uint8_t(dwarf::DW_CFA_advance_loc2); - OS << uint16_t(AddrDelta); + OS << uint8_t( AddrDelta & 0xff); + OS << uint8_t((AddrDelta >> 8) & 0xff); } else { + // FIXME: check what is the correct behavior on a big endian machine. assert(isUInt<32>(AddrDelta)); OS << uint8_t(dwarf::DW_CFA_advance_loc4); - OS << uint32_t(AddrDelta); + OS << uint8_t( AddrDelta & 0xff); + OS << uint8_t((AddrDelta >> 8) & 0xff); + OS << uint8_t((AddrDelta >> 16) & 0xff); + OS << uint8_t((AddrDelta >> 24) & 0xff); + } } Added: llvm/trunk/test/MC/ELF/cfi-advance-loc2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-advance-loc2.s?rev=122615&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-advance-loc2.s (added) +++ llvm/trunk/test/MC/ELF/cfi-advance-loc2.s Tue Dec 28 20:30:49 2010 @@ -0,0 +1,45 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +// test that this produces a correctly encoded cfi_advance_loc2 + +f: + .cfi_startproc + nop + .zero 255, 0x90 + .cfi_def_cfa_offset 8 + nop + .cfi_endproc + +// CHECK: (('sh_name', 0x00000012) # '.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000001) +// CHECK-NEXT: ('sh_flags', 0x00000002) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000148) +// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 01010000 00030001 0e080000') +// CHECK-NEXT: ), + + +// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000258) +// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_info', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x00000008) +// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) +// CHECK-NEXT: ), From rafael.espindola at gmail.com Tue Dec 28 20:42:33 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 29 Dec 2010 02:42:33 -0000 Subject: [llvm-commits] [llvm] r122616 - /llvm/trunk/lib/MC/MCStreamer.cpp Message-ID: <20101229024233.7A0332A6C12C@llvm.org> Author: rafael Date: Tue Dec 28 20:42:33 2010 New Revision: 122616 URL: http://llvm.org/viewvc/llvm-project?rev=122616&view=rev Log: Remove second return. Modified: llvm/trunk/lib/MC/MCStreamer.cpp Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122616&r1=122615&r2=122616&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Dec 28 20:42:33 2010 @@ -206,7 +206,6 @@ MCCFIInstruction Instruction(Label, Dest, Source); CurFrame->Instructions.push_back(Instruction); return false; - return false; } bool MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { From zwarich at apple.com Tue Dec 28 21:52:51 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 29 Dec 2010 03:52:51 -0000 Subject: [llvm-commits] [llvm] r122617 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101229035251.DA35C2A6C12C@llvm.org> Author: zwarich Date: Tue Dec 28 21:52:51 2010 New Revision: 122617 URL: http://llvm.org/viewvc/llvm-project?rev=122617&view=rev Log: Add text explaining an assertion. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122617&r1=122616&r2=122617&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Dec 28 21:52:51 2010 @@ -283,7 +283,9 @@ LiveInterval& DestLI = LI->getInterval(DestReg); LiveInterval& NewLI = LI->getInterval(NewReg); - assert(DestLI.ranges.size() == 1); + assert(DestLI.ranges.size() == 1 + && "PHI destination copy's live interval should be a single live " + "range from the beginning of the BB to the copy instruction."); LiveRange* DestLR = DestLI.begin(); VNInfo* NewVNI = NewLI.getVNInfoAt(DestLR->start); if (!NewVNI) { From zwarich at apple.com Tue Dec 28 21:55:58 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 28 Dec 2010 19:55:58 -0800 Subject: [llvm-commits] [llvm] r122586 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <52B39F5D-46A8-4869-83F4-D7BA324C9493@apple.com> References: <20101227220842.45C1A2A6C12C@llvm.org> <52B39F5D-46A8-4869-83F4-D7BA324C9493@apple.com> Message-ID: <49A60ADF-9FD6-4716-AFBB-D3B4D4CE2E89@apple.com> On Dec 28, 2010, at 6:15 PM, Bill Wendling wrote: > On Dec 27, 2010, at 2:08 PM, Cameron Zwarich wrote: > >> Author: zwarich >> Date: Mon Dec 27 16:08:42 2010 >> New Revision: 122586 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122586&view=rev >> Log: >> Change an assertion to assert what the code actually relies upon. >> >> Modified: >> llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >> >> Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122586&r1=122585&r2=122586&view=diff >> ============================================================================== >> --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) >> +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Dec 27 16:08:42 2010 >> @@ -283,7 +283,7 @@ >> LiveInterval& DestLI = LI->getInterval(DestReg); >> LiveInterval& NewLI = LI->getInterval(NewReg); >> >> - assert(DestLI.containsOneValue()); >> + assert(DestLI.ranges.size() == 1); > > Could you add a string saying why it should be 1? Something like: > > assert(DestLI.ranges.size() == 1 && "One is the loneliest number!"); Done in r122617. Thanks, Cameron From geek4civic at gmail.com Tue Dec 28 21:58:36 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 29 Dec 2010 03:58:36 -0000 Subject: [llvm-commits] [llvm] r122618 - /llvm/trunk/test/CodeGen/X86/fp-in-intregs.ll Message-ID: <20101229035836.9B5E42A6C12C@llvm.org> Author: chapuni Date: Tue Dec 28 21:58:36 2010 New Revision: 122618 URL: http://llvm.org/viewvc/llvm-project?rev=122618&view=rev Log: test/CodeGen/X86/fp-in-intregs.ll: FileCheck-ize. Modified: llvm/trunk/test/CodeGen/X86/fp-in-intregs.ll Modified: llvm/trunk/test/CodeGen/X86/fp-in-intregs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fp-in-intregs.ll?rev=122618&r1=122617&r2=122618&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/fp-in-intregs.ll (original) +++ llvm/trunk/test/CodeGen/X86/fp-in-intregs.ll Tue Dec 28 21:58:36 2010 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86 -mcpu=yonah | not egrep {\(\(xor\|and\)ps\|movd\)} +; RUN: llc < %s -march=x86 -mcpu=yonah | FileCheck %s +; CHECK-NOT: {{((xor|and)ps|movd)}} ; These operations should be done in integer registers, eliminating constant ; pool loads, movd's etc. From geek4civic at gmail.com Tue Dec 28 21:58:47 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 29 Dec 2010 03:58:47 -0000 Subject: [llvm-commits] [llvm] r122619 - /llvm/trunk/test/CodeGen/X86/negative-sin.ll Message-ID: <20101229035847.7565E2A6C12C@llvm.org> Author: chapuni Date: Tue Dec 28 21:58:47 2010 New Revision: 122619 URL: http://llvm.org/viewvc/llvm-project?rev=122619&view=rev Log: test/CodeGen/X86/negative-sin.ll: FileCheck-ize. Modified: llvm/trunk/test/CodeGen/X86/negative-sin.ll Modified: llvm/trunk/test/CodeGen/X86/negative-sin.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/negative-sin.ll?rev=122619&r1=122618&r2=122619&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/negative-sin.ll (original) +++ llvm/trunk/test/CodeGen/X86/negative-sin.ll Tue Dec 28 21:58:47 2010 @@ -1,5 +1,5 @@ -; RUN: llc < %s -enable-unsafe-fp-math -march=x86-64 | \ -; RUN: not egrep {addsd|subsd|xor} +; RUN: llc < %s -enable-unsafe-fp-math -march=x86-64 | FileCheck %s +; CHECK-NOT: {{addsd|subsd|xor}} declare double @sin(double %f) From geek4civic at gmail.com Tue Dec 28 21:58:56 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 29 Dec 2010 03:58:56 -0000 Subject: [llvm-commits] [llvm] r122620 - /llvm/trunk/test/Transforms/ConstProp/logicaltest.ll Message-ID: <20101229035856.B44E92A6C12C@llvm.org> Author: chapuni Date: Tue Dec 28 21:58:56 2010 New Revision: 122620 URL: http://llvm.org/viewvc/llvm-project?rev=122620&view=rev Log: test/Transforms/ConstProp/logicaltest.ll: FileCheck-ize. Modified: llvm/trunk/test/Transforms/ConstProp/logicaltest.ll Modified: llvm/trunk/test/Transforms/ConstProp/logicaltest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/logicaltest.ll?rev=122620&r1=122619&r2=122620&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ConstProp/logicaltest.ll (original) +++ llvm/trunk/test/Transforms/ConstProp/logicaltest.ll Tue Dec 28 21:58:56 2010 @@ -1,7 +1,7 @@ ; Ensure constant propogation of logical instructions is working correctly. -; RUN: opt < %s -constprop -die -S | \ -; RUN: not egrep {and|or|xor} +; RUN: opt < %s -constprop -die -S | FileCheck %s +; CHECK-NOT: {{and|or|xor}} define i32 @test1() { %R = and i32 4, 1234 ; [#uses=1] From geek4civic at gmail.com Tue Dec 28 21:59:03 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 29 Dec 2010 03:59:03 -0000 Subject: [llvm-commits] [llvm] r122621 - in /llvm/trunk: autoconf/configure.ac configure Message-ID: <20101229035903.8E77E2A6C12C@llvm.org> Author: chapuni Date: Tue Dec 28 21:59:03 2010 New Revision: 122621 URL: http://llvm.org/viewvc/llvm-project?rev=122621&view=rev Log: autoconf: [PR7874] Add --disable-pthreads to suppress detecting pthreads on certain hosts. This would be needed to build pthread*.dll-free distribution on recent MinGW-MSYS distros. Modified: llvm/trunk/autoconf/configure.ac llvm/trunk/configure Modified: llvm/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=122621&r1=122620&r2=122621&view=diff ============================================================================== --- llvm/trunk/autoconf/configure.ac (original) +++ llvm/trunk/autoconf/configure.ac Tue Dec 28 21:59:03 2010 @@ -530,6 +530,18 @@ esac AC_DEFINE_UNQUOTED([ENABLE_THREADS],$ENABLE_THREADS,[Define if threads enabled]) +dnl Allow disablement of pthread.h +AC_ARG_ENABLE(pthreads, + AS_HELP_STRING([--enable-pthreads], + [Use pthreads if available (default is YES)]),, + enableval=default) +case "$enableval" in + yes) AC_SUBST(ENABLE_PTHREADS,[1]) ;; + no) AC_SUBST(ENABLE_PTHREADS,[0]) ;; + default) AC_SUBST(ENABLE_PTHREADS,[1]) ;; + *) AC_MSG_ERROR([Invalid setting for --enable-pthreads. Use "yes" or "no"]) ;; +esac + dnl Allow building without position independent code AC_ARG_ENABLE(pic, AS_HELP_STRING([--enable-pic], @@ -1216,7 +1228,7 @@ dnl pthread locking functions are optional - but llvm will not be thread-safe dnl without locks. -if test "$ENABLE_THREADS" -eq 1 ; then +if test "$ENABLE_THREADS" -eq 1 && test "$ENABLE_PTHREADS" -eq 1 ; then AC_CHECK_LIB(pthread, pthread_mutex_init) AC_SEARCH_LIBS(pthread_mutex_lock,pthread, AC_DEFINE([HAVE_PTHREAD_MUTEX_LOCK],[1], @@ -1308,7 +1320,7 @@ AC_CHECK_HEADERS([sys/types.h sys/ioctl.h malloc/malloc.h mach/mach.h]) AC_CHECK_HEADERS([valgrind/valgrind.h]) AC_CHECK_HEADERS([fenv.h]) -if test "$ENABLE_THREADS" -eq 1 ; then +if test "$ENABLE_THREADS" -eq 1 && test "$ENABLE_PTHREADS" -eq 1 ; then AC_CHECK_HEADERS(pthread.h, AC_SUBST(HAVE_PTHREAD, 1), AC_SUBST(HAVE_PTHREAD, 0)) Modified: llvm/trunk/configure URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/configure?rev=122621&r1=122620&r2=122621&view=diff ============================================================================== --- llvm/trunk/configure (original) +++ llvm/trunk/configure Tue Dec 28 21:59:03 2010 @@ -691,6 +691,7 @@ ENABLE_DOCS ENABLE_DOXYGEN ENABLE_THREADS +ENABLE_PTHREADS ENABLE_PIC ENABLE_SHARED ENABLE_TIMESTAMPS @@ -1415,6 +1416,7 @@ --enable-docs Build documents (default is YES) --enable-doxygen Build doxygen documentation (default is NO) --enable-threads Use threads if available (default is YES) + --enable-pthreads Use pthreads if available (default is YES) --enable-pic Build LLVM with Position Independent Code (default is YES) --enable-shared Build a shared library and link tools against it @@ -4935,6 +4937,25 @@ _ACEOF +# Check whether --enable-pthreads was given. +if test "${enable_pthreads+set}" = set; then + enableval=$enable_pthreads; +else + enableval=default +fi + +case "$enableval" in + yes) ENABLE_PTHREADS=1 + ;; + no) ENABLE_PTHREADS=0 + ;; + default) ENABLE_PTHREADS=1 + ;; + *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-pthreads. Use \"yes\" or \"no\"" >&5 +echo "$as_me: error: Invalid setting for --enable-pthreads. Use \"yes\" or \"no\"" >&2;} + { (exit 1); exit 1; }; } ;; +esac + # Check whether --enable-pic was given. if test "${enable_pic+set}" = set; then enableval=$enable_pic; @@ -11518,7 +11539,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6; } @@ -16897,7 +16918,7 @@ done -if test "$ENABLE_THREADS" -eq 1 ; then +if test "$ENABLE_THREADS" -eq 1 && test "$ENABLE_PTHREADS" -eq 1 ; then for ac_header in pthread.h do @@ -21788,6 +21809,7 @@ ENABLE_DOCS!$ENABLE_DOCS$ac_delim ENABLE_DOXYGEN!$ENABLE_DOXYGEN$ac_delim ENABLE_THREADS!$ENABLE_THREADS$ac_delim +ENABLE_PTHREADS!$ENABLE_PTHREADS$ac_delim ENABLE_PIC!$ENABLE_PIC$ac_delim ENABLE_SHARED!$ENABLE_SHARED$ac_delim ENABLE_TIMESTAMPS!$ENABLE_TIMESTAMPS$ac_delim @@ -21795,7 +21817,6 @@ LLVM_ENUM_TARGETS!$LLVM_ENUM_TARGETS$ac_delim LLVM_ENUM_ASM_PRINTERS!$LLVM_ENUM_ASM_PRINTERS$ac_delim LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim -LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -21837,6 +21858,7 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim CLANGPATH!$CLANGPATH$ac_delim CLANGXXPATH!$CLANGXXPATH$ac_delim @@ -21933,7 +21955,6 @@ ALL_BINDINGS!$ALL_BINDINGS$ac_delim OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim -RPATH!$RPATH$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -21975,12 +21996,13 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +RPATH!$RPATH$ac_delim RDYNAMIC!$RDYNAMIC$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 3; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 4; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 From geek4civic at gmail.com Tue Dec 28 21:59:14 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 29 Dec 2010 03:59:14 -0000 Subject: [llvm-commits] [llvm] r122622 - in /llvm/trunk: Makefile.config.in autoconf/configure.ac configure tools/llvm-shlib/Makefile Message-ID: <20101229035914.D9C1B2A6C12C@llvm.org> Author: chapuni Date: Tue Dec 28 21:59:14 2010 New Revision: 122622 URL: http://llvm.org/viewvc/llvm-project?rev=122622&view=rev Log: autoconf: Add --disable-embed-stdcxx to suppress linking libstdc++.a into llvm.dll with --enable-shared on Cygming. Cygwin has stdc++.dll in it's distribution, and we can assume distro's stdc++.dll might be available. Modified: llvm/trunk/Makefile.config.in llvm/trunk/autoconf/configure.ac llvm/trunk/configure llvm/trunk/tools/llvm-shlib/Makefile Modified: llvm/trunk/Makefile.config.in URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.config.in?rev=122622&r1=122621&r2=122622&view=diff ============================================================================== --- llvm/trunk/Makefile.config.in (original) +++ llvm/trunk/Makefile.config.in Tue Dec 28 21:59:14 2010 @@ -279,6 +279,9 @@ # Do we want to build a shared library and link the tools with it? ENABLE_SHARED := @ENABLE_SHARED@ +# Do we want to link the stdc++ into a shared library? (Cygming) +ENABLE_EMBED_STDCXX := @ENABLE_EMBED_STDCXX@ + # Use -fvisibility-inlines-hidden? ENABLE_VISIBILITY_INLINES_HIDDEN := @ENABLE_VISIBILITY_INLINES_HIDDEN@ Modified: llvm/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=122622&r1=122621&r2=122622&view=diff ============================================================================== --- llvm/trunk/autoconf/configure.ac (original) +++ llvm/trunk/autoconf/configure.ac Tue Dec 28 21:59:14 2010 @@ -568,6 +568,18 @@ *) AC_MSG_ERROR([Invalid setting for --enable-shared. Use "yes" or "no"]) ;; esac +dnl Allow libstdc++ is embedded in LLVM.dll. +AC_ARG_ENABLE(embed-stdcxx, + AS_HELP_STRING([--enable-embed-stdcxx], + [Build a shared library with embedded libstdc++ for Win32 DLL (default is YES)]),, + enableval=default) +case "$enableval" in + yes) AC_SUBST(ENABLE_EMBED_STDCXX,[1]) ;; + no) AC_SUBST(ENABLE_EMBED_STDCXX,[0]) ;; + default) AC_SUBST(ENABLE_EMBED_STDCXX,[1]) ;; + *) AC_MSG_ERROR([Invalid setting for --enable-embed-stdcxx. Use "yes" or "no"]) ;; +esac + dnl Enable embedding timestamp information into build. AC_ARG_ENABLE(timestamps, AS_HELP_STRING([--enable-timestamps], Modified: llvm/trunk/configure URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/configure?rev=122622&r1=122621&r2=122622&view=diff ============================================================================== --- llvm/trunk/configure (original) +++ llvm/trunk/configure Tue Dec 28 21:59:14 2010 @@ -694,6 +694,7 @@ ENABLE_PTHREADS ENABLE_PIC ENABLE_SHARED +ENABLE_EMBED_STDCXX ENABLE_TIMESTAMPS TARGETS_TO_BUILD LLVM_ENUM_TARGETS @@ -1421,6 +1422,8 @@ is YES) --enable-shared Build a shared library and link tools against it (default is NO) + --enable-embed-stdcxx Build a shared library with embedded libstdc++ for + Win32 DLL (default is YES) --enable-timestamps Enable embedding timestamp information in build (default is YES) --enable-targets Build specific host targets: all or @@ -4999,6 +5002,25 @@ { (exit 1); exit 1; }; } ;; esac +# Check whether --enable-embed-stdcxx was given. +if test "${enable_embed_stdcxx+set}" = set; then + enableval=$enable_embed_stdcxx; +else + enableval=default +fi + +case "$enableval" in + yes) ENABLE_EMBED_STDCXX=1 + ;; + no) ENABLE_EMBED_STDCXX=0 + ;; + default) ENABLE_EMBED_STDCXX=1 + ;; + *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-embed-stdcxx. Use \"yes\" or \"no\"" >&5 +echo "$as_me: error: Invalid setting for --enable-embed-stdcxx. Use \"yes\" or \"no\"" >&2;} + { (exit 1); exit 1; }; } ;; +esac + # Check whether --enable-timestamps was given. if test "${enable_timestamps+set}" = set; then enableval=$enable_timestamps; @@ -11539,7 +11561,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <conf$$subs.sed <<_ACEOF +LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim CLANGPATH!$CLANGPATH$ac_delim @@ -21954,7 +21977,6 @@ BINDINGS_TO_BUILD!$BINDINGS_TO_BUILD$ac_delim ALL_BINDINGS!$ALL_BINDINGS$ac_delim OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim -ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -21996,13 +22018,14 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim RPATH!$RPATH$ac_delim RDYNAMIC!$RDYNAMIC$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 4; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 5; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 Modified: llvm/trunk/tools/llvm-shlib/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-shlib/Makefile?rev=122622&r1=122621&r2=122622&view=diff ============================================================================== --- llvm/trunk/tools/llvm-shlib/Makefile (original) +++ llvm/trunk/tools/llvm-shlib/Makefile Tue Dec 28 21:59:14 2010 @@ -18,11 +18,12 @@ include $(LEVEL)/Makefile.config ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW)) - EXPORTED_SYMBOL_FILE = $(ObjDir)/$(LIBRARYNAME).exports + EXPORTED_SYMBOL_FILE = $(ObjDir)/$(LIBRARYNAME).exports + ifeq (1,$(ENABLE_EMBED_STDCXX)) # It is needed to force static-stdc++.a linked. - # FIXME: It should be omitted when configure detects system's stdc++.dll. SHLIB_FRAG_NAMES += stdc++.a.o + endif endif From geek4civic at gmail.com Tue Dec 28 21:59:27 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 29 Dec 2010 03:59:27 -0000 Subject: [llvm-commits] [llvm] r122623 - in /llvm/trunk/lib/Target: ARM/CMakeLists.txt ARM/Disassembler/CMakeLists.txt X86/Disassembler/CMakeLists.txt Message-ID: <20101229035927.7F2C92A6C12C@llvm.org> Author: chapuni Date: Tue Dec 28 21:59:27 2010 New Revision: 122623 URL: http://llvm.org/viewvc/llvm-project?rev=122623&view=rev Log: CMake: Add disabling optimization on MSVC8 and MSVC10 as workaround for some files in Target/ARM and Target/X86. Modified: llvm/trunk/lib/Target/ARM/CMakeLists.txt llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt llvm/trunk/lib/Target/X86/Disassembler/CMakeLists.txt Modified: llvm/trunk/lib/Target/ARM/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/CMakeLists.txt?rev=122623&r1=122622&r2=122623&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/ARM/CMakeLists.txt Tue Dec 28 21:59:27 2010 @@ -53,3 +53,11 @@ Thumb2RegisterInfo.cpp Thumb2SizeReduction.cpp ) + +# workaround for hanging compilation on MSVC10 +if( MSVC_VERSION EQUAL 1600 ) +set_property( + SOURCE ARMISelLowering.cpp + PROPERTY COMPILE_FLAGS "/Od" + ) +endif() Modified: llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt?rev=122623&r1=122622&r2=122623&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt Tue Dec 28 21:59:27 2010 @@ -4,8 +4,8 @@ ARMDisassembler.cpp ARMDisassemblerCore.cpp ) -# workaround for hanging compilation on MSVC9 and 10 -if( MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 ) +# workaround for hanging compilation on MSVC8, 9 and 10 +if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 ) set_property( SOURCE ARMDisassembler.cpp PROPERTY COMPILE_FLAGS "/Od" Modified: llvm/trunk/lib/Target/X86/Disassembler/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/CMakeLists.txt?rev=122623&r1=122622&r2=122623&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/X86/Disassembler/CMakeLists.txt Tue Dec 28 21:59:27 2010 @@ -5,7 +5,7 @@ X86DisassemblerDecoder.c ) # workaround for hanging compilation on MSVC9 and 10 -if( MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 ) +if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 ) set_property( SOURCE X86Disassembler.cpp PROPERTY COMPILE_FLAGS "/Od" From rafael.espindola at gmail.com Tue Dec 28 22:31:26 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 29 Dec 2010 04:31:26 -0000 Subject: [llvm-commits] [llvm] r122624 - in /llvm/trunk: lib/MC/MCDwarf.cpp lib/MC/MCParser/AsmParser.cpp test/MC/ELF/cfi.s Message-ID: <20101229043126.6AFCB2A6C12C@llvm.org> Author: rafael Date: Tue Dec 28 22:31:26 2010 New Revision: 122624 URL: http://llvm.org/viewvc/llvm-project?rev=122624&view=rev Log: Correctly encode pcrel|indirect. Modified: llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCParser/AsmParser.cpp llvm/trunk/test/MC/ELF/cfi.s Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122624&r1=122623&r2=122624&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Dec 28 22:31:26 2010 @@ -526,7 +526,7 @@ MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); unsigned format = symbolEncoding & 0x0f; - unsigned application = symbolEncoding & 0xf0; + unsigned application = symbolEncoding & 0x70; unsigned size; switch (format) { default: @@ -553,7 +553,6 @@ assert(0 && "Unknown Encoding"); break; case 0: - case dwarf::DW_EH_PE_indirect: streamer.EmitSymbolValue(&symbol, size); break; case dwarf::DW_EH_PE_pcrel: Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122624&r1=122623&r2=122624&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Dec 28 22:31:26 2010 @@ -2248,10 +2248,9 @@ Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) return false; - const unsigned Application = Encoding & 0xf0; + const unsigned Application = Encoding & 0x70; if (Application != dwarf::DW_EH_PE_absptr && - Application != dwarf::DW_EH_PE_pcrel && - Application != dwarf::DW_EH_PE_indirect) + Application != dwarf::DW_EH_PE_pcrel) return false; return true; Modified: llvm/trunk/test/MC/ELF/cfi.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi.s?rev=122624&r1=122623&r2=122624&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi.s (original) +++ llvm/trunk/test/MC/ELF/cfi.s Tue Dec 28 22:31:26 2010 @@ -163,18 +163,67 @@ .cfi_personality 0x88, foo nop .cfi_endproc + +f28: + .cfi_startproc + .cfi_personality 0x90, foo + nop + .cfi_endproc + +f29: + .cfi_startproc + .cfi_personality 0x92, foo + nop + .cfi_endproc + +f30: + .cfi_startproc + .cfi_personality 0x93, foo + nop + .cfi_endproc + +f31: + .cfi_startproc + .cfi_personality 0x94, foo + nop + .cfi_endproc + +f32: + .cfi_startproc + .cfi_personality 0x9a, foo + nop + .cfi_endproc + +f33: + .cfi_startproc + .cfi_personality 0x9b, foo + nop + .cfi_endproc + +f34: + .cfi_startproc + .cfi_personality 0x9c, foo + nop + .cfi_endproc + +f36: + .cfi_startproc + .cfi_personality 0x98, foo + nop + .cfi_endproc + // CHECK: # Section 0x00000004 // CHECK-NEXT: (('sh_name', 0x00000012) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) // CHECK-NEXT: ('sh_flags', 0x00000002) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000060) -// CHECK-NEXT: ('sh_size', 0x00000538) +// CHECK-NEXT: ('sh_offset', 0x00000068) +// CHECK-NEXT: ('sh_size', 0x000006c8) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000000) -// CHECK-NEXT: ('_section_data', '14000000 00000000 017a4c52 00017810 02031b0c 07089001 14000000 1c000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000003 1b0c0708 90010000 14000000 28000000 00000000 01000000 04000000 00000000 14000000 70000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000002 1b0c0708 90010000 10000000 28000000 00000000 01000000 02000000 18000000 00000000 017a5052 00017810 04020000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06030000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a040000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 040a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 060b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a0c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a080000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a100000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04120000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06130000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a140000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 041a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 061b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a1c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a180000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a800000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04820000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06830000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a840000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 048a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 068b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a8c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a88000 0 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000') +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a4c52 00017810 02031b0c 07089001 14000000 1c000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000003 1b0c0708 90010000 14000000 28000000 00000000 01000000 04000000 00000000 14000000 70000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000002 1b0c0708 90010000 10000000 28000000 00000000 01000000 02000000 18000000 00000000 017a5052 00017810 04020000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06030000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a040000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 040a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 060b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a0c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a080000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a100000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04120000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06130000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a140000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 041a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 061b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a1c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a180000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a800000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04820000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06830000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a840000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 048a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 068b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a8c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a88000 0 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a900000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04920000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06930000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a940000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 049a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 069b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a9c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a980000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000') // CHECK-NEXT: ), // CHECK: # Section 0x00000008 @@ -182,8 +231,8 @@ // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000980) -// CHECK-NEXT: ('sh_size', 0x00000540) +// CHECK-NEXT: ('sh_offset', 0x00000bf8) +// CHECK-NEXT: ('sh_size', 0x000006c0) // CHECK-NEXT: ('sh_link', 0x00000006) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) @@ -191,339 +240,435 @@ // CHECK-NEXT: ('_relocations', [ // CHECK-NEXT: # Relocation 0x00000000 // CHECK-NEXT: (('r_offset', 0x00000020) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000001 // CHECK-NEXT: (('r_offset', 0x00000029) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000028) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000002 // CHECK-NEXT: (('r_offset', 0x00000043) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000003 // CHECK-NEXT: (('r_offset', 0x0000005c) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000001) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000004 // CHECK-NEXT: (('r_offset', 0x00000065) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000028) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000005 // CHECK-NEXT: (('r_offset', 0x00000074) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000002) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000006 // CHECK-NEXT: (('r_offset', 0x0000007d) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000028) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000007 // CHECK-NEXT: (('r_offset', 0x00000097) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000008 // CHECK-NEXT: (('r_offset', 0x000000b0) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000003) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000009 // CHECK-NEXT: (('r_offset', 0x000000b9) -// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000028) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000000a // CHECK-NEXT: (('r_offset', 0x000000ce) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000000b // CHECK-NEXT: (('r_offset', 0x000000e0) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000004) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000000c // CHECK-NEXT: (('r_offset', 0x000000fe) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000000d // CHECK-NEXT: (('r_offset', 0x00000110) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000005) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000000e // CHECK-NEXT: (('r_offset', 0x0000012e) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000000f // CHECK-NEXT: (('r_offset', 0x00000144) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000006) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000010 // CHECK-NEXT: (('r_offset', 0x00000162) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000011 // CHECK-NEXT: (('r_offset', 0x00000174) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000007) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000012 // CHECK-NEXT: (('r_offset', 0x00000192) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000013 // CHECK-NEXT: (('r_offset', 0x000001a4) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000008) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000014 // CHECK-NEXT: (('r_offset', 0x000001c2) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000015 // CHECK-NEXT: (('r_offset', 0x000001d8) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000009) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000016 // CHECK-NEXT: (('r_offset', 0x000001f6) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000017 // CHECK-NEXT: (('r_offset', 0x0000020c) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000a) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000018 // CHECK-NEXT: (('r_offset', 0x0000022a) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000019 // CHECK-NEXT: (('r_offset', 0x00000240) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000b) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000001a // CHECK-NEXT: (('r_offset', 0x0000025e) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000d) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000001b // CHECK-NEXT: (('r_offset', 0x00000270) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000c) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000001c // CHECK-NEXT: (('r_offset', 0x0000028e) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000001d // CHECK-NEXT: (('r_offset', 0x000002a0) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000d) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000001e // CHECK-NEXT: (('r_offset', 0x000002be) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000001f // CHECK-NEXT: (('r_offset', 0x000002d4) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000e) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000020 // CHECK-NEXT: (('r_offset', 0x000002f2) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000d) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000021 // CHECK-NEXT: (('r_offset', 0x00000304) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000000f) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000022 // CHECK-NEXT: (('r_offset', 0x00000322) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000023 // CHECK-NEXT: (('r_offset', 0x00000334) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000010) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000024 // CHECK-NEXT: (('r_offset', 0x00000352) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000025 // CHECK-NEXT: (('r_offset', 0x00000368) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000011) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000026 // CHECK-NEXT: (('r_offset', 0x00000386) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000027 // CHECK-NEXT: (('r_offset', 0x0000039c) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000012) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000028 // CHECK-NEXT: (('r_offset', 0x000003ba) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000029 // CHECK-NEXT: (('r_offset', 0x000003d0) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000013) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000002a // CHECK-NEXT: (('r_offset', 0x000003ee) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000002b // CHECK-NEXT: (('r_offset', 0x00000400) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000014) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000002c // CHECK-NEXT: (('r_offset', 0x0000041e) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000002d // CHECK-NEXT: (('r_offset', 0x00000430) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000015) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000002e // CHECK-NEXT: (('r_offset', 0x0000044e) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x0000002f // CHECK-NEXT: (('r_offset', 0x00000464) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000016) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000030 // CHECK-NEXT: (('r_offset', 0x00000482) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000c) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000031 // CHECK-NEXT: (('r_offset', 0x00000494) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000017) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000032 // CHECK-NEXT: (('r_offset', 0x000004b2) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000033 // CHECK-NEXT: (('r_offset', 0x000004c4) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000018) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000034 // CHECK-NEXT: (('r_offset', 0x000004e2) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000035 // CHECK-NEXT: (('r_offset', 0x000004f8) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000019) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000036 // CHECK-NEXT: (('r_offset', 0x00000516) -// CHECK-NEXT: ('r_sym', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000037 // CHECK-NEXT: (('r_offset', 0x0000052c) -// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000001a) // CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000038 +// CHECK-NEXT: (('r_offset', 0x0000054a) +// CHECK-NEXT: ('r_sym', 0x00000029) +// CHECK-NEXT: ('r_type', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000039 +// CHECK-NEXT: (('r_offset', 0x00000560) +// CHECK-NEXT: ('r_sym', 0x00000024) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000001b) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000003a +// CHECK-NEXT: (('r_offset', 0x0000057e) +// CHECK-NEXT: ('r_sym', 0x00000029) +// CHECK-NEXT: ('r_type', 0x0000000d) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000003b +// CHECK-NEXT: (('r_offset', 0x00000590) +// CHECK-NEXT: ('r_sym', 0x00000024) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000001c) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000003c +// CHECK-NEXT: (('r_offset', 0x000005ae) +// CHECK-NEXT: ('r_sym', 0x00000029) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000003d +// CHECK-NEXT: (('r_offset', 0x000005c0) +// CHECK-NEXT: ('r_sym', 0x00000024) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000001d) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000003e +// CHECK-NEXT: (('r_offset', 0x000005de) +// CHECK-NEXT: ('r_sym', 0x00000029) +// CHECK-NEXT: ('r_type', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000003f +// CHECK-NEXT: (('r_offset', 0x000005f4) +// CHECK-NEXT: ('r_sym', 0x00000024) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000001e) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000040 +// CHECK-NEXT: (('r_offset', 0x00000612) +// CHECK-NEXT: ('r_sym', 0x00000029) +// CHECK-NEXT: ('r_type', 0x0000000d) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000041 +// CHECK-NEXT: (('r_offset', 0x00000624) +// CHECK-NEXT: ('r_sym', 0x00000024) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000001f) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000042 +// CHECK-NEXT: (('r_offset', 0x00000642) +// CHECK-NEXT: ('r_sym', 0x00000029) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000043 +// CHECK-NEXT: (('r_offset', 0x00000654) +// CHECK-NEXT: ('r_sym', 0x00000024) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000020) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000044 +// CHECK-NEXT: (('r_offset', 0x00000672) +// CHECK-NEXT: ('r_sym', 0x00000029) +// CHECK-NEXT: ('r_type', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000045 +// CHECK-NEXT: (('r_offset', 0x00000688) +// CHECK-NEXT: ('r_sym', 0x00000024) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000021) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000046 +// CHECK-NEXT: (('r_offset', 0x000006a6) +// CHECK-NEXT: ('r_sym', 0x00000029) +// CHECK-NEXT: ('r_type', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000047 +// CHECK-NEXT: (('r_offset', 0x000006bc) +// CHECK-NEXT: ('r_sym', 0x00000024) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000022) +// CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), From zwarich at apple.com Tue Dec 28 22:42:39 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 29 Dec 2010 04:42:39 -0000 Subject: [llvm-commits] [llvm] r122625 - /llvm/trunk/lib/CodeGen/RegAllocBase.h Message-ID: <20101229044239.333B72A6C12C@llvm.org> Author: zwarich Date: Tue Dec 28 22:42:39 2010 New Revision: 122625 URL: http://llvm.org/viewvc/llvm-project?rev=122625&view=rev Log: Add a missing word to a comment. Modified: llvm/trunk/lib/CodeGen/RegAllocBase.h Modified: llvm/trunk/lib/CodeGen/RegAllocBase.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBase.h?rev=122625&r1=122624&r2=122625&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBase.h (original) +++ llvm/trunk/lib/CodeGen/RegAllocBase.h Tue Dec 28 22:42:39 2010 @@ -30,7 +30,7 @@ // of registers, if a more sophisticated allocator chooses to do that. // // This framework provides a way to engineer the compile time vs. code -// quality trade-off without relying a particular theoretical solver. +// quality trade-off without relying on a particular theoretical solver. // //===----------------------------------------------------------------------===// From wendling at apple.com Tue Dec 28 23:32:05 2010 From: wendling at apple.com (Bill Wendling) Date: Tue, 28 Dec 2010 21:32:05 -0800 Subject: [llvm-commits] [llvm] r122586 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <49A60ADF-9FD6-4716-AFBB-D3B4D4CE2E89@apple.com> References: <20101227220842.45C1A2A6C12C@llvm.org> <52B39F5D-46A8-4869-83F4-D7BA324C9493@apple.com> <49A60ADF-9FD6-4716-AFBB-D3B4D4CE2E89@apple.com> Message-ID: <0EBB4CFF-2E64-4CBD-899A-7927CD47D891@apple.com> On Dec 28, 2010, at 7:55 PM, Cameron Zwarich wrote: > On Dec 28, 2010, at 6:15 PM, Bill Wendling wrote: > >> On Dec 27, 2010, at 2:08 PM, Cameron Zwarich wrote: >> >>> Author: zwarich >>> Date: Mon Dec 27 16:08:42 2010 >>> New Revision: 122586 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=122586&view=rev >>> Log: >>> Change an assertion to assert what the code actually relies upon. >>> >>> Modified: >>> llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >>> >>> Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122586&r1=122585&r2=122586&view=diff >>> ============================================================================== >>> --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) >>> +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Dec 27 16:08:42 2010 >>> @@ -283,7 +283,7 @@ >>> LiveInterval& DestLI = LI->getInterval(DestReg); >>> LiveInterval& NewLI = LI->getInterval(NewReg); >>> >>> - assert(DestLI.containsOneValue()); >>> + assert(DestLI.ranges.size() == 1); >> >> Could you add a string saying why it should be 1? Something like: >> >> assert(DestLI.ranges.size() == 1 && "One is the loneliest number!"); > > Done in r122617. > Thanks! :-) -bw From venkatra at cs.wisc.edu Tue Dec 28 23:37:15 2010 From: venkatra at cs.wisc.edu (Venkatraman Govindaraju) Date: Wed, 29 Dec 2010 05:37:15 -0000 Subject: [llvm-commits] [llvm] r122626 - /llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Message-ID: <20101229053715.B35992A6C12C@llvm.org> Author: venkatra Date: Tue Dec 28 23:37:15 2010 New Revision: 122626 URL: http://llvm.org/viewvc/llvm-project?rev=122626&view=rev Log: SPARC backend fix: correctly passing arguments through stack Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=122626&r1=122625&r2=122626&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Tue Dec 28 23:37:15 2010 @@ -365,20 +365,24 @@ SDValue Val = OutVals[i]; EVT ObjectVT = Outs[i].VT; SDValue ValToStore(0, 0); - unsigned ObjSize; + SDValue ValToStore2(0, 0); + unsigned ArgOffset1 = 0, ArgOffset2 = 0; switch (ObjectVT.getSimpleVT().SimpleTy) { default: llvm_unreachable("Unhandled argument type!"); case MVT::i32: - ObjSize = 4; + ArgOffset1 = ArgOffset; + ArgOffset += 4; if (RegsToPass.size() >= 6) { ValToStore = Val; } else { RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Val)); } + break; case MVT::f32: - ObjSize = 4; + ArgOffset1 = ArgOffset; + ArgOffset += 4; if (RegsToPass.size() >= 6) { ValToStore = Val; } else { @@ -388,14 +392,17 @@ } break; case MVT::f64: { - ObjSize = 8; + if (RegsToPass.size() >= 6) { - ValToStore = Val; // Whole thing is passed in memory. - break; + if (ArgOffset % 8 == 0) { + ArgOffset1 = ArgOffset; + ArgOffset += 8; + ValToStore = Val; // Whole thing is passed in memory. + break; + } } - // Break into top and bottom parts by storing to the stack and loading - // out the parts as integers. Top part goes in a reg. + // out the parts as integers. SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32); SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Val, StackPtr, MachinePointerInfo(), @@ -410,22 +417,31 @@ SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr, MachinePointerInfo(), false, false, 0); - RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi)); - if (RegsToPass.size() >= 6) { - ValToStore = Lo; - ArgOffset += 4; - ObjSize = 4; + ArgOffset1 = ArgOffset; + ValToStore = Hi; + } else { + RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi)); + } + ArgOffset += 4; + if (RegsToPass.size() >= 6) { + ArgOffset2 = ArgOffset; + ValToStore2 = Lo; } else { RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo)); } + ArgOffset += 4; break; } case MVT::i64: { - ObjSize = 8; + if (RegsToPass.size() >= 6) { - ValToStore = Val; // Whole thing is passed in memory. - break; + if (ArgOffset % 8 == 0) { + ArgOffset1 = ArgOffset; + ArgOffset += 8; + ValToStore = Val; // Whole thing is passed in memory. + break; + } } // Split the value into top and bottom part. Top part goes in a reg. @@ -433,28 +449,40 @@ DAG.getConstant(1, MVT::i32)); SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Val, DAG.getConstant(0, MVT::i32)); - RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi)); - if (RegsToPass.size() >= 6) { - ValToStore = Lo; - ArgOffset += 4; - ObjSize = 4; + ArgOffset1 = ArgOffset; + ValToStore = Hi; + } else { + RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi)); + } + ArgOffset += 4; + if (RegsToPass.size() >= 6) { + ArgOffset2 = ArgOffset; + ValToStore2 = Lo; } else { RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo)); } + ArgOffset += 4; break; } } if (ValToStore.getNode()) { SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); - SDValue PtrOff = DAG.getConstant(ArgOffset, MVT::i32); + SDValue PtrOff = DAG.getConstant(ArgOffset1, MVT::i32); PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); MemOpChains.push_back(DAG.getStore(Chain, dl, ValToStore, PtrOff, MachinePointerInfo(), false, false, 0)); } - ArgOffset += ObjSize; + if (ValToStore2.getNode()) { + SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); + SDValue PtrOff = DAG.getConstant(ArgOffset2, MVT::i32); + PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); + MemOpChains.push_back(DAG.getStore(Chain, dl, ValToStore2, + PtrOff, MachinePointerInfo(), + false, false, 0)); + } } #endif From zwarich at apple.com Wed Dec 29 04:32:54 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 29 Dec 2010 02:32:54 -0800 Subject: [llvm-commits] [llvm] r122596 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <72680009-B7D5-4298-AAB4-929D31EE10C5@2pi.dk> References: <20101228104933.E73A82A6C12C@llvm.org> <933BD2C5-63C9-499D-9631-8BA1D32D3C7E@apple.com> <8E469394-5CEE-46C1-B7A4-3EFC7754C468@apple.com> <8443CA3E-D7F9-4DE1-B8FD-C25AB0C36CE0@2pi.dk> <153E5FFF-5A54-4B05-A7B2-ED1484022A54@apple.com> <90F15B7D-C61B-47E0-BC4A-5139EB28AE56@apple.com> <72680009-B7D5-4298-AAB4-929D31EE10C5@2pi.dk> Message-ID: On Dec 28, 2010, at 3:08 PM, Jakob Stoklund Olesen wrote: > Maybe you are going about this the wrong way. The majority of virtual registers are never involved with PHIs, so StrongPHIElimination shouldn't have to look at them at all. Yet, here you are iterating over all operands in the machine code. > > Perhaps you could keep track of the virtual registers that are used or defined by PHI instructions and use their use-def chains instead? If I use def-use chains to build arrays of relevant instructions per-MBB and then sort them by SlotIndex before running the existing code, I get a 47% speedup. I'll clean it up and land it. Cameron From zwarich at apple.com Wed Dec 29 05:00:09 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 29 Dec 2010 11:00:09 -0000 Subject: [llvm-commits] [llvm] r122627 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101229110009.71FD32A6C12C@llvm.org> Author: zwarich Date: Wed Dec 29 05:00:09 2010 New Revision: 122627 URL: http://llvm.org/viewvc/llvm-project?rev=122627&view=rev Log: Instead of processing every instruction when splitting interferences, only process those instructions that define phi sources. This is a 47% speedup of StrongPHIElimination compile time on 403.gcc. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122627&r1=122626&r2=122627&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Dec 29 05:00:09 2010 @@ -107,8 +107,6 @@ /// Isolate a PHI. void isolatePHI(MachineInstr*); - void PartitionRegisters(MachineFunction& MF); - /// Traverses a basic block, splitting any interferences found between /// registers in the same congruence class. It takes two DenseMaps as /// arguments that it also updates: CurrentDominatingParent, which maps @@ -142,6 +140,10 @@ DenseMap RegNodeMap; + // Maps a basic block to a list of its defs of registers that appear as PHI + // sources. + DenseMap > PHISrcDefs; + // FIXME: Can these two data structures be combined? Would a std::multimap // be any better? @@ -161,6 +163,16 @@ typedef DenseMap DestCopyMap; DestCopyMap InsertedDestCopies; }; + + struct MIIndexCompare { + MIIndexCompare(LiveIntervals* LiveIntervals) : LI(LiveIntervals) { } + + bool operator()(const MachineInstr* LHS, const MachineInstr* RHS) const { + return LI->getInstructionIndex(LHS) < LI->getInstructionIndex(RHS); + } + + LiveIntervals* LI; + }; } // namespace char StrongPHIElimination::ID = 0; @@ -207,7 +219,27 @@ DT = &getAnalysis(); LI = &getAnalysis(); - PartitionRegisters(MF); + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); + BBI != BBE && BBI->isPHI(); ++BBI) { + unsigned DestReg = BBI->getOperand(0).getReg(); + addReg(DestReg); + PHISrcDefs[I].push_back(BBI); + + for (unsigned i = 1; i < BBI->getNumOperands(); i += 2) { + MachineOperand& SrcMO = BBI->getOperand(i); + unsigned SrcReg = SrcMO.getReg(); + addReg(SrcReg); + unionRegs(DestReg, SrcReg); + + for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg), + DE = MRI->def_end(); DI != DE; ++DI) { + PHISrcDefs[DI->getParent()].push_back(&*DI); + } + } + } + } // Perform a depth-first traversal of the dominator tree, splitting // interferences amongst PHI-congruence classes. @@ -232,7 +264,20 @@ // FIXME: Preserve the equivalence classes during copy insertion and use // the preversed equivalence classes instead of recomputing them. RegNodeMap.clear(); - PartitionRegisters(MF); + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); + BBI != BBE && BBI->isPHI(); ++BBI) { + unsigned DestReg = BBI->getOperand(0).getReg(); + addReg(DestReg); + + for (unsigned i = 1; i < BBI->getNumOperands(); i += 2) { + unsigned SrcReg = BBI->getOperand(i).getReg(); + addReg(SrcReg); + unionRegs(DestReg, SrcReg); + } + } + } DenseMap RegRenamingMap; bool Changed = false; @@ -336,6 +381,7 @@ Allocator.Reset(); RegNodeMap.clear(); + PHISrcDefs.clear(); InsertedSrcCopySet.clear(); InsertedSrcCopyMap.clear(); InsertedDestCopies.clear(); @@ -410,23 +456,6 @@ Node->parent.setInt(Node->parent.getInt() | Node::kPHIIsolatedFlag); } -void StrongPHIElimination::PartitionRegisters(MachineFunction& MF) { - for (MachineFunction::iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); - BBI != BBE && BBI->isPHI(); ++BBI) { - unsigned DestReg = BBI->getOperand(0).getReg(); - addReg(DestReg); - - for (unsigned i = 1; i < BBI->getNumOperands(); i += 2) { - unsigned SrcReg = BBI->getOperand(i).getReg(); - addReg(SrcReg); - unionRegs(DestReg, SrcReg); - } - } - } -} - /// SplitInterferencesForBasicBlock - traverses a basic block, splitting any /// interferences found between registers in the same congruence class. It /// takes two DenseMaps as arguments that it also updates: @@ -471,10 +500,15 @@ MachineBasicBlock& MBB, DenseMap& CurrentDominatingParent, DenseMap& ImmediateDominatingParent) { - for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end(); - BBI != BBE; ++BBI) { - for (MachineInstr::const_mop_iterator I = BBI->operands_begin(), - E = BBI->operands_end(); I != E; ++I) { + // Sort defs by their order in the original basic block, as the code below + // assumes that it is processing definitions in dominance order. + std::vector& DefInstrs = PHISrcDefs[&MBB]; + std::sort(DefInstrs.begin(), DefInstrs.end(), MIIndexCompare(LI)); + + for (std::vector::const_iterator BBI = DefInstrs.begin(), + BBE = DefInstrs.end(); BBI != BBE; ++BBI) { + for (MachineInstr::const_mop_iterator I = (*BBI)->operands_begin(), + E = (*BBI)->operands_end(); I != E; ++I) { const MachineOperand& MO = *I; // FIXME: This would be faster if it were possible to bail out of checking @@ -506,7 +540,7 @@ // Pop registers from the stack represented by ImmediateDominatingParent // until we find a parent that dominates the current instruction. - while (NewParent && (!DT->dominates(MRI->getVRegDef(NewParent), BBI) + while (NewParent && (!DT->dominates(MRI->getVRegDef(NewParent), *BBI) || !getRegColor(NewParent))) NewParent = ImmediateDominatingParent[NewParent]; @@ -514,7 +548,7 @@ // instruction, so it is only necessary to check for the liveness of // NewParent in order to check for an interference. if (NewParent - && LI->getInterval(NewParent).liveAt(LI->getInstructionIndex(BBI))) { + && LI->getInterval(NewParent).liveAt(LI->getInstructionIndex(*BBI))) { // If there is an interference, always isolate the new register. This // could be improved by using a heuristic that decides which of the two // registers to isolate. From zwarich at apple.com Wed Dec 29 05:49:11 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 29 Dec 2010 11:49:11 -0000 Subject: [llvm-commits] [llvm] r122628 - /llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp Message-ID: <20101229114911.1B81D2A6C12C@llvm.org> Author: zwarich Date: Wed Dec 29 05:49:10 2010 New Revision: 122628 URL: http://llvm.org/viewvc/llvm-project?rev=122628&view=rev Log: None of the other pass names in CodeGen have terminating periods. Modified: llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp Modified: llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp?rev=122628&r1=122627&r2=122628&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp (original) +++ llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp Wed Dec 29 05:49:10 2010 @@ -27,10 +27,10 @@ char ProcessImplicitDefs::ID = 0; INITIALIZE_PASS_BEGIN(ProcessImplicitDefs, "processimpdefs", - "Process Implicit Definitions.", false, false) + "Process Implicit Definitions", false, false) INITIALIZE_PASS_DEPENDENCY(LiveVariables) INITIALIZE_PASS_END(ProcessImplicitDefs, "processimpdefs", - "Process Implicit Definitions.", false, false) + "Process Implicit Definitions", false, false) void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); From geek4civic at gmail.com Wed Dec 29 05:58:55 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 29 Dec 2010 20:58:55 +0900 Subject: [llvm-commits] [PATCH] Add some options to configure for Cygming In-Reply-To: <4DCB677B-A351-40B3-ADDD-2E5543CBF2B3@apple.com> References: <4DCB677B-A351-40B3-ADDD-2E5543CBF2B3@apple.com> Message-ID: Committed in r122621 and r122622, thank you! ...Takumi From daniel at zuster.org Wed Dec 29 08:14:06 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 29 Dec 2010 14:14:06 -0000 Subject: [llvm-commits] [llvm] r122630 - in /llvm/trunk: include/llvm/MC/MCMachOSymbolFlags.h lib/MC/MCMachOStreamer.cpp test/MC/MachO/darwin-Thumb-reloc.s Message-ID: <20101229141406.A4BC92A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 29 08:14:06 2010 New Revision: 122630 URL: http://llvm.org/viewvc/llvm-project?rev=122630&view=rev Log: MC/Mach-O/Thumb: Set the thumb bit in the symbol table. Modified: llvm/trunk/include/llvm/MC/MCMachOSymbolFlags.h llvm/trunk/lib/MC/MCMachOStreamer.cpp llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s Modified: llvm/trunk/include/llvm/MC/MCMachOSymbolFlags.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCMachOSymbolFlags.h?rev=122630&r1=122629&r2=122630&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCMachOSymbolFlags.h (original) +++ llvm/trunk/include/llvm/MC/MCMachOSymbolFlags.h Wed Dec 29 08:14:06 2010 @@ -34,6 +34,7 @@ SF_ReferenceTypePrivateUndefinedLazy = 0x0005, // Other 'desc' flags. + SF_ThumbFunc = 0x0008, SF_NoDeadStrip = 0x0020, SF_WeakReference = 0x0040, SF_WeakDefinition = 0x0080, Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=122630&r1=122629&r2=122630&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Wed Dec 29 08:14:06 2010 @@ -140,12 +140,16 @@ } } -void MCMachOStreamer::EmitThumbFunc(MCSymbol *Func) { +void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) { // FIXME: Flag the function ISA as thumb with DW_AT_APPLE_isa. // Remember that the function is a thumb function. Fixup and relocation // values will need adjusted. - getAssembler().setIsThumbFunc(Func); + getAssembler().setIsThumbFunc(Symbol); + + // Mark the thumb bit on the symbol. + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); + SD.setFlags(SD.getFlags() | SF_ThumbFunc); } void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { Modified: llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s?rev=122630&r1=122629&r2=122630&view=diff ============================================================================== --- llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s (original) +++ llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s Wed Dec 29 08:14:06 2010 @@ -98,7 +98,7 @@ @ CHECK: (('n_strx', 1) @ CHECK: ('n_type', 0xf) @ CHECK: ('n_sect', 1) -@ CHECK-FIXME: ('n_desc', 8) +@ CHECK: ('n_desc', 8) @ CHECK: ('n_value', 0) @ CHECK: ('_string', '_main') @ CHECK: ), From peckw at wesleypeck.com Wed Dec 29 13:46:28 2010 From: peckw at wesleypeck.com (Wesley Peck) Date: Wed, 29 Dec 2010 19:46:28 -0000 Subject: [llvm-commits] [llvm] r122631 - in /llvm/trunk/lib/Target/MBlaze: MBlazeFrameInfo.cpp MBlazeRegisterInfo.cpp Message-ID: <20101229194628.9ABFE2A6C12C@llvm.org> Author: peckw Date: Wed Dec 29 13:46:28 2010 New Revision: 122631 URL: http://llvm.org/viewvc/llvm-project?rev=122631&view=rev Log: Fix stack layout error in MBlaze backend. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp Modified: llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp?rev=122631&r1=122630&r2=122631&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp Wed Dec 29 13:46:28 2010 @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "mblaze-frame-info" + #include "MBlazeFrameInfo.h" #include "MBlazeInstrInfo.h" #include "MBlazeMachineFunction.h" @@ -24,6 +26,9 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -66,6 +71,23 @@ int StackAdjust = 0; int StackOffset = -28; + + // In this loop we are searching frame indexes that corrospond to incoming + // arguments that are already in the stack. We look for instruction sequences + // like the following: + // + // LWI REG, FI1, 0 + // ... + // SWI REG, FI2, 0 + // + // As long as there are no defs of REG in the ... part, we can eliminate + // the SWI instruction because the value has already been stored to the + // stack by the caller. All we need to do is locate FI at the correct + // stack location according to the calling convensions. + // + // Additionally, if the SWI operation kills the def of REG then we don't + // need the LWI operation so we can erase it as well. +#if 1 for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) { for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 || @@ -75,60 +97,88 @@ unsigned FIReg = I->getOperand(0).getReg(); MachineBasicBlock::iterator SI = I; for (SI++; SI != MIE; ++SI) { - if (!SI->getOperand(0).isReg()) continue; - if (!SI->getOperand(1).isFI()) continue; - if (SI->getOpcode() != MBlaze::SWI) continue; + if (!SI->getOperand(0).isReg() || + !SI->getOperand(1).isFI() || + SI->getOpcode() != MBlaze::SWI) continue; int FI = SI->getOperand(1).getIndex(); - if (SI->getOperand(0).getReg() != FIReg) continue; - if (MFI->isFixedObjectIndex(FI)) continue; - if (MFI->getObjectSize(FI) != 4) continue; + if (SI->getOperand(0).getReg() != FIReg || + MFI->isFixedObjectIndex(FI) || + MFI->getObjectSize(FI) != 4) continue; + if (SI->getOperand(0).isDef()) break; - if (SI->getOperand(0).isKill()) + if (SI->getOperand(0).isKill()) { + DEBUG(dbgs() << "LWI for FI#" << I->getOperand(1).getIndex() + << " removed\n"); EraseInstr.push_back(I); + } + EraseInstr.push_back(SI); + DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n"); + MBlazeFI->recordLoadArgsFI(FI, StackOffset); + DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n"); + StackOffset -= 4; StackAdjust += 4; break; } } } +#endif - for (MachineBasicBlock::iterator I=MBB->begin(), E=MBB->end(); I != E; ++I) { - if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 || - !I->getOperand(1).isFI() || !I->getOperand(0).isReg() || - I->getOperand(1).getIndex() < 0) continue; + // In this loop we are searching for frame indexes that corrospond to + // incoming arguments that are in registers. We look for instruction + // sequences like the following: + // + // ... SWI REG, FI, 0 + // + // As long as the ... part does not define REG and if REG is an incoming + // parameter register then we know that, according to ABI convensions, the + // caller has allocated stack space for it already. Instead of allocating + // stack space on our frame, we record the correct location in the callers + // frame. +#if 1 + for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) { + for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { + if (I->definesRegister(LI->first)) + break; + + if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 || + !I->getOperand(1).isFI() || !I->getOperand(0).isReg() || + I->getOperand(1).getIndex() < 0) continue; - unsigned FIReg = 0; - for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) { if (I->getOperand(0).getReg() == LI->first) { - FIReg = LI->first; - break; - } - } + int FI = I->getOperand(1).getIndex(); + MBlazeFI->recordLiveIn(FI); - if (FIReg) { - int FI = I->getOperand(1).getIndex(); - MBlazeFI->recordLiveIn(FI); - - StackAdjust += 4; - switch (FIReg) { - default: llvm_unreachable("invalid incoming parameter!"); - case MBlaze::R5: MBlazeFI->recordLoadArgsFI(FI, -4); break; - case MBlaze::R6: MBlazeFI->recordLoadArgsFI(FI, -8); break; - case MBlaze::R7: MBlazeFI->recordLoadArgsFI(FI, -12); break; - case MBlaze::R8: MBlazeFI->recordLoadArgsFI(FI, -16); break; - case MBlaze::R9: MBlazeFI->recordLoadArgsFI(FI, -20); break; - case MBlaze::R10: MBlazeFI->recordLoadArgsFI(FI, -24); break; + int FILoc = 0; + switch (LI->first) { + default: llvm_unreachable("invalid incoming parameter!"); + case MBlaze::R5: FILoc = -4; break; + case MBlaze::R6: FILoc = -8; break; + case MBlaze::R7: FILoc = -12; break; + case MBlaze::R8: FILoc = -16; break; + case MBlaze::R9: FILoc = -20; break; + case MBlaze::R10: FILoc = -24; break; + } + + StackAdjust += 4; + MBlazeFI->recordLoadArgsFI(FI, FILoc); + DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n"); + break; } } } +#endif + // Go ahead and erase all of the instructions that we determined were + // no longer needed. for (int i = 0, e = EraseInstr.size(); i < e; ++i) MBB->erase(EraseInstr[i]); + DEBUG(dbgs() << "Final stack adjustment: " << StackAdjust << "\n"); MBlazeFI->setStackAdjust(StackAdjust); } @@ -230,7 +280,10 @@ // Get the number of bytes to allocate from the FrameInfo unsigned FrameSize = MFI->getStackSize(); + DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" ); + FrameSize -= MBlazeFI->getStackAdjust(); + DEBUG(dbgs() << "Adjusted Frame Size: " << FrameSize << "\n" ); // Get the alignments provided by the target, and the maximum alignment // (if any) of the fixed frame objects. @@ -241,6 +294,7 @@ // Make sure the frame is aligned. FrameSize = (FrameSize + AlignMask) & ~AlignMask; MFI->setStackSize(FrameSize); + DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" ); } // hasFP - Return true if the specified function should have a dedicated frame Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp?rev=122631&r1=122630&r2=122631&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp Wed Dec 29 13:46:28 2010 @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "mblaze-reg-info" +#define DEBUG_TYPE "mblaze-frame-info" #include "MBlaze.h" #include "MBlazeSubtarget.h" @@ -277,25 +277,32 @@ unsigned oi = i == 2 ? 1 : 2; - DEBUG(errs() << "\nFunction : " << MF.getFunction()->getName() << "\n"; - errs() << "<--------->\n" << MI); + DEBUG(dbgs() << "\nFunction : " << MF.getFunction()->getName() << "\n"; + dbgs() << "<--------->\n" << MI); int FrameIndex = MI.getOperand(i).getIndex(); int stackSize = MF.getFrameInfo()->getStackSize(); int spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex); - DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n" + DEBUG(dbgs() << "FrameIndex : " << FrameIndex << "\n" << "spOffset : " << spOffset << "\n" - << "stackSize : " << stackSize << "\n"); + << "stackSize : " << stackSize << "\n" + << "isFixed : " << MFI->isFixedObjectIndex(FrameIndex) << "\n" + << "isLiveIn : " << MBlazeFI->isLiveIn(FrameIndex) << "\n" + << "isSpill : " << MFI->isSpillSlotObjectIndex(FrameIndex) + << "\n" ); // as explained on LowerFormalArguments, detect negative offsets // and adjust SPOffsets considering the final stack size. int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset; Offset += MI.getOperand(oi).getImm(); - if (!MFI->isFixedObjectIndex(FrameIndex) && !MBlazeFI->isLiveIn(FrameIndex) && spOffset >= 0) + if (!MFI->isFixedObjectIndex(FrameIndex) && + !MFI->isSpillSlotObjectIndex(FrameIndex) && + !MBlazeFI->isLiveIn(FrameIndex) && + spOffset >= 0) Offset -= MBlazeFI->getStackAdjust(); - DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); + DEBUG(dbgs() << "Offset : " << Offset << "\n" << "<--------->\n"); MI.getOperand(oi).ChangeToImmediate(Offset); MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false); From stoklund at 2pi.dk Wed Dec 29 14:16:21 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 29 Dec 2010 12:16:21 -0800 Subject: [llvm-commits] [llvm] r122627 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <20101229110009.71FD32A6C12C@llvm.org> References: <20101229110009.71FD32A6C12C@llvm.org> Message-ID: <0571B9B9-133E-498E-8413-BE2C1905D188@2pi.dk> On Dec 29, 2010, at 3:00 AM, Cameron Zwarich wrote: > Author: zwarich > Date: Wed Dec 29 05:00:09 2010 > New Revision: 122627 > > URL: http://llvm.org/viewvc/llvm-project?rev=122627&view=rev > Log: > Instead of processing every instruction when splitting interferences, only > process those instructions that define phi sources. This is a 47% speedup of > StrongPHIElimination compile time on 403.gcc. Nice! How does strong phi elimination affect the runtime of coalescing? > + for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg), > + DE = MRI->def_end(); DI != DE; ++DI) { > + PHISrcDefs[DI->getParent()].push_back(&*DI); Do these registers have multiple definitions, or could you use MRI->getVRegDef()? /jakob -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101229/ea654cd6/attachment.bin From sabre at nondot.org Wed Dec 29 16:41:18 2010 From: sabre at nondot.org (Chris Lattner) Date: Wed, 29 Dec 2010 22:41:18 -0000 Subject: [llvm-commits] [llvm] r122632 - /llvm/trunk/lib/Linker/LinkModules.cpp Message-ID: <20101229224118.5BD932A6C12C@llvm.org> Author: lattner Date: Wed Dec 29 16:41:18 2010 New Revision: 122632 URL: http://llvm.org/viewvc/llvm-project?rev=122632&view=rev Log: improve warning message to at least say what the triples are. Modified: llvm/trunk/lib/Linker/LinkModules.cpp Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=122632&r1=122631&r2=122632&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Wed Dec 29 16:41:18 2010 @@ -1219,7 +1219,9 @@ errs() << "WARNING: Linking two modules of different data layouts!\n"; if (!Src->getTargetTriple().empty() && Dest->getTargetTriple() != Src->getTargetTriple()) - errs() << "WARNING: Linking two modules of different target triples!\n"; + errs() << "WARNING: Linking two modules of different target triples: '" + << Src->getTargetTriple() << "' and '" << Dest->getDataLayout() + << "'\n"; // Append the module inline asm string. if (!Src->getModuleInlineAsm().empty()) { From fvbommel at gmail.com Wed Dec 29 17:22:14 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Thu, 30 Dec 2010 00:22:14 +0100 Subject: [llvm-commits] [llvm] r122632 - /llvm/trunk/lib/Linker/LinkModules.cpp In-Reply-To: <20101229224118.5BD932A6C12C@llvm.org> References: <20101229224118.5BD932A6C12C@llvm.org> Message-ID: On Wed, Dec 29, 2010 at 11:41 PM, Chris Lattner wrote: > improve warning message to at least say what the triples are. > ? if (!Src->getTargetTriple().empty() && > ? ? ? Dest->getTargetTriple() != Src->getTargetTriple()) > - ? ?errs() << "WARNING: Linking two modules of different target triples!\n"; > + ? ?errs() << "WARNING: Linking two modules of different target triples: '" > + ? ? ? ? ? << Src->getTargetTriple() << "' and '" << Dest->getDataLayout() > + ? ? ? ? ? << "'\n"; s/getDataLayout/getTargetTriple/ ? From zwarich at apple.com Wed Dec 29 18:36:53 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 29 Dec 2010 16:36:53 -0800 Subject: [llvm-commits] [llvm] r122627 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <0571B9B9-133E-498E-8413-BE2C1905D188@2pi.dk> References: <20101229110009.71FD32A6C12C@llvm.org> <0571B9B9-133E-498E-8413-BE2C1905D188@2pi.dk> Message-ID: On Dec 29, 2010, at 12:16 PM, Jakob Stoklund Olesen wrote: > On Dec 29, 2010, at 3:00 AM, Cameron Zwarich wrote: > >> Author: zwarich >> Date: Wed Dec 29 05:00:09 2010 >> New Revision: 122627 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122627&view=rev >> Log: >> Instead of processing every instruction when splitting interferences, only >> process those instructions that define phi sources. This is a 47% speedup of >> StrongPHIElimination compile time on 403.gcc. > > Nice! > > How does strong phi elimination affect the runtime of coalescing? It doesn't reduce it as much as I would like. On 403.gcc, coalescing takes up 4.0-4.1% of compile time with normal PHIElimination, and it goes down to 3.9% with StrongPHIElimination. StrongPHIElimination is getting fast enough that total compile time is just noise, but I'd like to investigate why there isn't as much of a speedup in coalescing as I would expect. I'm not splitting non-loop critical edges at the moment, because I wanted to test all of the critical edge handling. That will probably lead to fewer copies. >> + for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg), >> + DE = MRI->def_end(); DI != DE; ++DI) { >> + PHISrcDefs[DI->getParent()].push_back(&*DI); > > Do these registers have multiple definitions, or could you use MRI->getVRegDef()? Using getVRegDef() should be fine, since all of the definitions from things like 2-address instructions should be in the same BB. I was going to do that, but I got some confusing results between 3 variants, in increasing order of performance: 1) What I landed, using MOs instead of MIs. 2) What I landed, but only using the MO of the first use (the same use returned by getVRegDef()). 3) What I landed, but using getVRegDef(). It doesn't really make sense to me that 2) should be slower than 3). I guess I'll land 3) and investigate other benchmarks of compile-time. There are a couple of other possible speedups: 1) Sorting the entire basic block isn't really necessary, it should just be enough to do a few comparisons when things interfere. 2) I'm using the simple theoretically optimal union-find. There are faster versions that are slightly less optimal. 3) Getting rid of the second pass of reforming the equivalence classes and renaming registers. This would also make it easier to cut down on the number of new virtual registers. I tried doing this and it is tricky, but it should work. Cameron From zwarich at apple.com Wed Dec 29 18:42:23 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 30 Dec 2010 00:42:23 -0000 Subject: [llvm-commits] [llvm] r122635 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101230004223.95E6C2A6C12C@llvm.org> Author: zwarich Date: Wed Dec 29 18:42:23 2010 New Revision: 122635 URL: http://llvm.org/viewvc/llvm-project?rev=122635&view=rev Log: Use getVRegDef() instead of def_iterator. This leads to fewer defs being added with 2-address instructions, for about a 3.5% speedup of StrongPHIElimination on 403.gcc. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122635&r1=122634&r2=122635&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Dec 29 18:42:23 2010 @@ -233,10 +233,9 @@ addReg(SrcReg); unionRegs(DestReg, SrcReg); - for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg), - DE = MRI->def_end(); DI != DE; ++DI) { - PHISrcDefs[DI->getParent()].push_back(&*DI); - } + MachineInstr* DefMI = MRI->getVRegDef(SrcReg); + if (DefMI) + PHISrcDefs[DefMI->getParent()].push_back(DefMI); } } } From sabre at nondot.org Wed Dec 29 19:09:30 2010 From: sabre at nondot.org (Chris Lattner) Date: Wed, 29 Dec 2010 17:09:30 -0800 Subject: [llvm-commits] [llvm] r122632 - /llvm/trunk/lib/Linker/LinkModules.cpp In-Reply-To: References: <20101229224118.5BD932A6C12C@llvm.org> Message-ID: <86ECBC61-D187-4C76-9166-DBFAFB0BC85A@nondot.org> Sigh yes, will fix. On Dec 29, 2010, at 3:22 PM, Frits van Bommel wrote: > On Wed, Dec 29, 2010 at 11:41 PM, Chris Lattner wrote: >> improve warning message to at least say what the triples are. > >> if (!Src->getTargetTriple().empty() && >> Dest->getTargetTriple() != Src->getTargetTriple()) >> - errs() << "WARNING: Linking two modules of different target triples!\n"; >> + errs() << "WARNING: Linking two modules of different target triples: '" >> + << Src->getTargetTriple() << "' and '" << Dest->getDataLayout() >> + << "'\n"; > > s/getDataLayout/getTargetTriple/ ? From sabre at nondot.org Wed Dec 29 19:07:20 2010 From: sabre at nondot.org (Chris Lattner) Date: Thu, 30 Dec 2010 01:07:20 -0000 Subject: [llvm-commits] [llvm] r122636 - /llvm/trunk/lib/Linker/LinkModules.cpp Message-ID: <20101230010720.F41142A6C12C@llvm.org> Author: lattner Date: Wed Dec 29 19:07:20 2010 New Revision: 122636 URL: http://llvm.org/viewvc/llvm-project?rev=122636&view=rev Log: print the right string, thanks for Frits for noticing. Modified: llvm/trunk/lib/Linker/LinkModules.cpp Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=122636&r1=122635&r2=122636&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Wed Dec 29 19:07:20 2010 @@ -1220,7 +1220,7 @@ if (!Src->getTargetTriple().empty() && Dest->getTargetTriple() != Src->getTargetTriple()) errs() << "WARNING: Linking two modules of different target triples: '" - << Src->getTargetTriple() << "' and '" << Dest->getDataLayout() + << Src->getTargetTriple() << "' and '" << Dest->getTargetTriple() << "'\n"; // Append the module inline asm string. From stoklund at 2pi.dk Wed Dec 29 20:39:26 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 29 Dec 2010 18:39:26 -0800 Subject: [llvm-commits] [llvm] r122627 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: References: <20101229110009.71FD32A6C12C@llvm.org> <0571B9B9-133E-498E-8413-BE2C1905D188@2pi.dk> Message-ID: On Dec 29, 2010, at 4:36 PM, Cameron Zwarich wrote: >> How does strong phi elimination affect the runtime of coalescing? > > It doesn't reduce it as much as I would like. On 403.gcc, coalescing takes up 4.0-4.1% of compile time with normal PHIElimination, and it goes down to 3.9% with StrongPHIElimination. StrongPHIElimination is getting fast enough that total compile time is just noise, but I'd like to investigate why there isn't as much of a speedup in coalescing as I would expect. You may want to get some numbers from the ARM target as well. X86 has lots of copies from two-address instructions. > There are a couple of other possible speedups: > > 1) Sorting the entire basic block isn't really necessary, it should just be enough to do a few comparisons when things interfere. > > 2) I'm using the simple theoretically optimal union-find. There are faster versions that are slightly less optimal. You could probably save some code size by using ADT/EquivalenceClasses.h. I don't know how that implementation performs, though. /jakob -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101229/23d94be5/attachment.bin From sabre at nondot.org Wed Dec 29 20:49:46 2010 From: sabre at nondot.org (Chris Lattner) Date: Thu, 30 Dec 2010 02:49:46 -0000 Subject: [llvm-commits] [llvm] r122637 - /llvm/trunk/lib/Linker/LinkModules.cpp Message-ID: <20101230024946.0CE4C2A6C12C@llvm.org> Author: lattner Date: Wed Dec 29 20:49:45 2010 New Revision: 122637 URL: http://llvm.org/viewvc/llvm-project?rev=122637&view=rev Log: include the module identifier when emitting this warning, PR8865. Modified: llvm/trunk/lib/Linker/LinkModules.cpp Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=122637&r1=122636&r2=122637&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Wed Dec 29 20:49:45 2010 @@ -1218,10 +1218,13 @@ Src->getDataLayout() != Dest->getDataLayout()) errs() << "WARNING: Linking two modules of different data layouts!\n"; if (!Src->getTargetTriple().empty() && - Dest->getTargetTriple() != Src->getTargetTriple()) - errs() << "WARNING: Linking two modules of different target triples: '" - << Src->getTargetTriple() << "' and '" << Dest->getTargetTriple() - << "'\n"; + Dest->getTargetTriple() != Src->getTargetTriple()) { + errs() << "WARNING: Linking two modules of different target triples: "; + if (!Src->getModuleIdentifier().empty()) + errs() << Src->getModuleIdentifier() << ": "; + errs() << "'" << Src->getTargetTriple() << "' and '" + << Dest->getTargetTriple() << "'\n"; + } // Append the module inline asm string. if (!Src->getModuleInlineAsm().empty()) { From zwarich at apple.com Wed Dec 29 21:23:51 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 29 Dec 2010 19:23:51 -0800 Subject: [llvm-commits] [llvm] r122627 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: References: <20101229110009.71FD32A6C12C@llvm.org> <0571B9B9-133E-498E-8413-BE2C1905D188@2pi.dk> Message-ID: On Dec 29, 2010, at 6:39 PM, Jakob Stoklund Olesen wrote: > On Dec 29, 2010, at 4:36 PM, Cameron Zwarich wrote: >>> How does strong phi elimination affect the runtime of coalescing? >> >> It doesn't reduce it as much as I would like. On 403.gcc, coalescing takes up 4.0-4.1% of compile time with normal PHIElimination, and it goes down to 3.9% with StrongPHIElimination. StrongPHIElimination is getting fast enough that total compile time is just noise, but I'd like to investigate why there isn't as much of a speedup in coalescing as I would expect. > > You may want to get some numbers from the ARM target as well. X86 has lots of copies from two-address instructions. How useful would this sort of dominator-based coalescing be for copies introduced by two-address instructions? Cameron > >> >> From stoklund at 2pi.dk Wed Dec 29 21:46:43 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 29 Dec 2010 19:46:43 -0800 Subject: [llvm-commits] [llvm] r122627 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: References: <20101229110009.71FD32A6C12C@llvm.org> <0571B9B9-133E-498E-8413-BE2C1905D188@2pi.dk> Message-ID: <67E75EBA-16E3-4233-9BE4-3AB7C5E02C85@2pi.dk> On Dec 29, 2010, at 7:23 PM, Cameron Zwarich wrote: > On Dec 29, 2010, at 6:39 PM, Jakob Stoklund Olesen wrote: > >> On Dec 29, 2010, at 4:36 PM, Cameron Zwarich wrote: >>>> How does strong phi elimination affect the runtime of coalescing? >>> >>> It doesn't reduce it as much as I would like. On 403.gcc, coalescing takes up 4.0-4.1% of compile time with normal PHIElimination, and it goes down to 3.9% with StrongPHIElimination. StrongPHIElimination is getting fast enough that total compile time is just noise, but I'd like to investigate why there isn't as much of a speedup in coalescing as I would expect. >> >> You may want to get some numbers from the ARM target as well. X86 has lots of copies from two-address instructions. > > How useful would this sort of dominator-based coalescing be for copies introduced by two-address instructions? Probably not very. The advantage of strong phi elimination lies in avoiding creating a bunch of virtual registers and copy instructions only to delete them again. Those are not very expensive operations, so whatever you do must be fast. You could handle 2-address instructions in a similar way, avoiding the copy instructions. I don't think it would be worth it. /jakob -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101229/e10fdb30/attachment.bin From clchiou at gmail.com Thu Dec 30 04:41:27 2010 From: clchiou at gmail.com (Che-Liang Chiou) Date: Thu, 30 Dec 2010 10:41:27 -0000 Subject: [llvm-commits] [llvm] r122638 - in /llvm/trunk: lib/Target/PTX/PTX.h lib/Target/PTX/PTXAsmPrinter.cpp lib/Target/PTX/PTXInstrInfo.td test/CodeGen/PTX/ld.ll Message-ID: <20101230104127.AA51C2A6C12C@llvm.org> Author: clchiou Date: Thu Dec 30 04:41:27 2010 New Revision: 122638 URL: http://llvm.org/viewvc/llvm-project?rev=122638&view=rev Log: ptx: add state spaces Modified: llvm/trunk/lib/Target/PTX/PTX.h llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.td llvm/trunk/test/CodeGen/PTX/ld.ll Modified: llvm/trunk/lib/Target/PTX/PTX.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTX.h?rev=122638&r1=122637&r2=122638&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTX.h (original) +++ llvm/trunk/lib/Target/PTX/PTX.h Thu Dec 30 04:41:27 2010 @@ -21,6 +21,16 @@ class PTXTargetMachine; class FunctionPass; + namespace PTX { + enum StateSpace { + GLOBAL = 0, // default to global state space + CONSTANT = 1, + LOCAL = 2, + PARAMETER = 3, + SHARED = 4 + }; + } // namespace PTX + FunctionPass *createPTXISelDag(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel); Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp?rev=122638&r1=122637&r2=122638&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp Thu Dec 30 04:41:27 2010 @@ -103,11 +103,14 @@ } static const char *getStateSpaceName(unsigned addressSpace) { - if (addressSpace <= 255) - return "global"; - // TODO Add more state spaces - - llvm_unreachable("Unknown state space"); + switch (addressSpace) { + default: llvm_unreachable("Unknown state space"); + case PTX::GLOBAL: return "global"; + case PTX::CONSTANT: return "const"; + case PTX::LOCAL: return "local"; + case PTX::PARAMETER: return "param"; + case PTX::SHARED: return "shared"; + } return NULL; } Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=122638&r1=122637&r2=122638&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Thu Dec 30 04:41:27 2010 @@ -22,9 +22,47 @@ //===----------------------------------------------------------------------===// def load_global : PatFrag<(ops node:$ptr), (load node:$ptr), [{ - if (const Value *Src = cast(N)->getSrcValue()) - if (const PointerType *PT = dyn_cast(Src->getType())) - return PT->getAddressSpace() <= 255; + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::GLOBAL; + return false; +}]>; + +def load_constant : PatFrag<(ops node:$ptr), (load node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::CONSTANT; + return false; +}]>; + +def load_local : PatFrag<(ops node:$ptr), (load node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::LOCAL; + return false; +}]>; + +def load_parameter : PatFrag<(ops node:$ptr), (load node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::PARAMETER; + return false; +}]>; + +def load_shared : PatFrag<(ops node:$ptr), (load node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::SHARED; return false; }]>; @@ -142,6 +180,10 @@ } defm LDg : PTX_LD<"ld.global", RRegs32, load_global>; +defm LDc : PTX_LD<"ld.const", RRegs32, load_constant>; +defm LDl : PTX_LD<"ld.local", RRegs32, load_local>; +defm LDp : PTX_LD<"ld.param", RRegs32, load_parameter>; +defm LDs : PTX_LD<"ld.shared", RRegs32, load_shared>; ///===- Control Flow Instructions -----------------------------------------===// Modified: llvm/trunk/test/CodeGen/PTX/ld.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/ld.ll?rev=122638&r1=122637&r2=122638&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/ld.ll (original) +++ llvm/trunk/test/CodeGen/PTX/ld.ll Thu Dec 30 04:41:27 2010 @@ -3,6 +3,15 @@ ;CHECK: .extern .global .s32 array[]; @array = external global [10 x i32] +;CHECK: .extern .const .s32 array_constant[]; + at array_constant = external addrspace(1) constant [10 x i32] + +;CHECK: .extern .local .s32 array_local[]; + at array_local = external addrspace(2) global [10 x i32] + +;CHECK: .extern .shared .s32 array_shared[]; + at array_shared = external addrspace(4) global [10 x i32] + define ptx_device i32 @t1(i32* %p) { entry: ;CHECK: ld.global.s32 r0, [r1]; @@ -27,7 +36,7 @@ ret i32 %x } -define ptx_device i32 @t4() { +define ptx_device i32 @t4_global() { entry: ;CHECK: ld.global.s32 r0, [array]; %i = getelementptr [10 x i32]* @array, i32 0, i32 0 @@ -35,6 +44,30 @@ ret i32 %x } +define ptx_device i32 @t4_const() { +entry: +;CHECK: ld.const.s32 r0, [array_constant]; + %i = getelementptr [10 x i32] addrspace(1)* @array_constant, i32 0, i32 0 + %x = load i32 addrspace(1)* %i + ret i32 %x +} + +define ptx_device i32 @t4_local() { +entry: +;CHECK: ld.local.s32 r0, [array_local]; + %i = getelementptr [10 x i32] addrspace(2)* @array_local, i32 0, i32 0 + %x = load i32 addrspace(2)* %i + ret i32 %x +} + +define ptx_device i32 @t4_shared() { +entry: +;CHECK: ld.shared.s32 r0, [array_shared]; + %i = getelementptr [10 x i32] addrspace(4)* @array_shared, i32 0, i32 0 + %x = load i32 addrspace(4)* %i + ret i32 %x +} + define ptx_device i32 @t5() { entry: ;CHECK: ld.global.s32 r0, [array+4]; From nicholas at mxc.ca Thu Dec 30 16:10:49 2010 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 30 Dec 2010 22:10:49 -0000 Subject: [llvm-commits] [llvm] r122641 - in /llvm/trunk: lib/Target/X86/X86InstrInfo.td test/MC/X86/x86-64.s Message-ID: <20101230221049.5783D2A6C12C@llvm.org> Author: nicholas Date: Thu Dec 30 16:10:49 2010 New Revision: 122641 URL: http://llvm.org/viewvc/llvm-project?rev=122641&view=rev Log: Add another non-commutable instruction that gas accepts commuted forms for. Fixes PR8861. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/test/MC/X86/x86-64.s Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=122641&r1=122640&r2=122641&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Dec 30 16:10:49 2010 @@ -1465,14 +1465,15 @@ // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they -// commute. We also allow fdivrp/fsubrp even though they don't commute, solely -// because gas supports it. +// commute. We also allow fdiv[r]p/fsubrp even though they don't commute, +// solely because gas supports it. def : InstAlias<"faddp %st(0), $op", (ADD_FPrST0 RST:$op)>; def : InstAlias<"fmulp %st(0), $op", (MUL_FPrST0 RST:$op)>; def : InstAlias<"fsubrp %st(0), $op", (SUB_FPrST0 RST:$op)>; +def : InstAlias<"fdivp %st(0), $op", (DIVR_FPrST0 RST:$op)>; def : InstAlias<"fdivrp %st(0), $op", (DIV_FPrST0 RST:$op)>; -// We accepts "fnstsw %eax" even though it only writes %ax. +// We accept "fnstsw %eax" even though it only writes %ax. def : InstAlias<"fnstsw %eax", (FNSTSW8r)>; def : InstAlias<"fnstsw %al" , (FNSTSW8r)>; def : InstAlias<"fnstsw" , (FNSTSW8r)>; Modified: llvm/trunk/test/MC/X86/x86-64.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-64.s?rev=122641&r1=122640&r2=122641&view=diff ============================================================================== --- llvm/trunk/test/MC/X86/x86-64.s (original) +++ llvm/trunk/test/MC/X86/x86-64.s Thu Dec 30 16:10:49 2010 @@ -504,6 +504,10 @@ fsubrp %ST(0), %ST(1) // CHECK: encoding: [0xde,0xe9] fsubrp %ST(1), %ST(0) // CHECK: encoding: [0xde,0xe9] +// also PR8861 +fdivp %st(0), %st(1) // CHECK: encoding: [0xde,0xf1] +fdivp %st(1), %st(0) // CHECK: encoding: [0xde,0xf1] + movl foo(%rip), %eax // CHECK: movl foo(%rip), %eax From benny.kra at googlemail.com Thu Dec 30 16:34:44 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 30 Dec 2010 22:34:44 -0000 Subject: [llvm-commits] [llvm] r122642 - in /llvm/trunk/lib: MC/MCDwarf.cpp Transforms/Utils/Local.cpp Message-ID: <20101230223444.EAF462A6C12C@llvm.org> Author: d0k Date: Thu Dec 30 16:34:44 2010 New Revision: 122642 URL: http://llvm.org/viewvc/llvm-project?rev=122642&view=rev Log: Make a bunch of symbols internal. Modified: llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122642&r1=122641&r2=122642&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Thu Dec 30 16:34:44 2010 @@ -712,31 +712,30 @@ return fdeEnd; } -struct CIEKey { - static const CIEKey EmptyKey; - static const CIEKey TombstoneKey; - - CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_, - unsigned LsdaEncoding_) : Personality(Personality_), - PersonalityEncoding(PersonalityEncoding_), - LsdaEncoding(LsdaEncoding_) { - } - const MCSymbol* Personality; - unsigned PersonalityEncoding; - unsigned LsdaEncoding; -}; - -const CIEKey CIEKey::EmptyKey(0, 0, -1); -const CIEKey CIEKey::TombstoneKey(0, -1, 0); +namespace { + struct CIEKey { + static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1); } + static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0); } + + CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_, + unsigned LsdaEncoding_) : Personality(Personality_), + PersonalityEncoding(PersonalityEncoding_), + LsdaEncoding(LsdaEncoding_) { + } + const MCSymbol* Personality; + unsigned PersonalityEncoding; + unsigned LsdaEncoding; + }; +} namespace llvm { template <> struct DenseMapInfo { static CIEKey getEmptyKey() { - return CIEKey::EmptyKey; + return CIEKey::getEmptyKey(); } static CIEKey getTombstoneKey() { - return CIEKey::TombstoneKey; + return CIEKey::getTombstoneKey(); } static unsigned getHashValue(const CIEKey &Key) { FoldingSetNodeID ID; Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=122642&r1=122641&r2=122642&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Dec 30 16:34:44 2010 @@ -650,7 +650,8 @@ /// is to simply align all global variables and allocation instructions to /// their preferred alignment from the beginning. /// -unsigned enforceKnownAlignment(Value *V, unsigned Align, unsigned PrefAlign) { +static unsigned enforceKnownAlignment(Value *V, unsigned Align, + unsigned PrefAlign) { User *U = dyn_cast(V); if (!U) return Align; From baldrick at free.fr Fri Dec 31 10:17:54 2010 From: baldrick at free.fr (Duncan Sands) Date: Fri, 31 Dec 2010 16:17:54 -0000 Subject: [llvm-commits] [llvm] r122645 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Message-ID: <20101231161754.D1A6D2A6C12C@llvm.org> Author: baldrick Date: Fri Dec 31 10:17:54 2010 New Revision: 122645 URL: http://llvm.org/viewvc/llvm-project?rev=122645&view=rev Log: Zap dead instructions harder. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp?rev=122645&r1=122644&r2=122645&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Fri Dec 31 10:17:54 2010 @@ -83,13 +83,8 @@ // Finally, run over the function zapping any dead instructions. for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { - Instruction *I = BI++; - if (isInstructionTriviallyDead(I)) { - I->eraseFromParent(); - Changed = true; - } - } + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) + Changed |= RecursivelyDeleteTriviallyDeadInstructions(BI++); return Changed; } From baldrick at free.fr Fri Dec 31 11:49:05 2010 From: baldrick at free.fr (Duncan Sands) Date: Fri, 31 Dec 2010 17:49:05 -0000 Subject: [llvm-commits] [llvm] r122647 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Message-ID: <20101231174905.E2A4A2A6C12C@llvm.org> Author: baldrick Date: Fri Dec 31 11:49:05 2010 New Revision: 122647 URL: http://llvm.org/viewvc/llvm-project?rev=122647&view=rev Log: Simplify this pass by using a depth-first iterator to ensure that all operands are visited before the instructions themselves. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp?rev=122647&r1=122646&r2=122647&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Fri Dec 31 11:49:05 2010 @@ -18,13 +18,13 @@ #include "llvm/Function.h" #include "llvm/Pass.h" #include "llvm/Type.h" +#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" -#include using namespace llvm; STATISTIC(NumSimplified, "Number of redundant instructions removed"); @@ -42,49 +42,30 @@ /// runOnFunction - Remove instructions that simplify. bool runOnFunction(Function &F) { - const TargetData *TD = getAnalysisIfAvailable(); const DominatorTree *DT = getAnalysisIfAvailable(); + const TargetData *TD = getAnalysisIfAvailable(); bool Changed = false; + bool LocalChanged; - // Add all interesting instructions to the worklist. These are processed - // in FIFO order, so instructions are usually visited before their uses. - std::queue Worklist; - for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { - Instruction *I = BI++; - // Zap any dead instructions. - if (isInstructionTriviallyDead(I)) { - I->eraseFromParent(); - Changed = true; - continue; + do { + LocalChanged = false; + + for (df_iterator DI = df_begin(&F.getEntryBlock()), + DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) + for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) { + Instruction *I = BI++; + // Don't bother simplifying unused instructions. + if (!I->use_empty()) + if (Value *V = SimplifyInstruction(I, TD, DT)) { + I->replaceAllUsesWith(V); + LocalChanged = true; + ++NumSimplified; + } + LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); } - // Add all others to the worklist. - Worklist.push(I); - } - - // Simplify everything in the worklist until the cows come home. - while (!Worklist.empty()) { - Instruction *I = Worklist.front(); - Worklist.pop(); - // Don't bother simplifying unused instructions. - if (I->use_empty()) continue; - Value *V = SimplifyInstruction(I, TD, DT); - if (!V) continue; - - // This instruction simplifies! Replace it with its simplification and - // add all uses to the worklist, since they may now simplify. - ++NumSimplified; - I->replaceAllUsesWith(V); - for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); - UI != UE; ++UI) - Worklist.push(cast(*UI)); - Changed = true; - } - - // Finally, run over the function zapping any dead instructions. - for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) - Changed |= RecursivelyDeleteTriviallyDeadInstructions(BI++); + + Changed |= LocalChanged; + } while (LocalChanged); return Changed; } From ofv at wanadoo.es Fri Dec 31 13:10:49 2010 From: ofv at wanadoo.es (Oscar Fuentes) Date: Fri, 31 Dec 2010 19:10:49 -0000 Subject: [llvm-commits] [llvm] r122648 - /llvm/trunk/cmake/modules/LLVMProcessSources.cmake Message-ID: <20101231191049.3AD9B2A6C12C@llvm.org> Author: ofv Date: Fri Dec 31 13:10:49 2010 New Revision: 122648 URL: http://llvm.org/viewvc/llvm-project?rev=122648&view=rev Log: CMake (MSVC): cmake automatically adds the /EHsc and /GR compiler options. If we are building with exceptions/rtti disabled, we replace /EHsc with /EHs-c- and /GR with /GR-, respectively. If we just add the disabling options we get warnings like this: cl : Command line warning D9025 : overriding '/EHs' with '/EHs-' Modified: llvm/trunk/cmake/modules/LLVMProcessSources.cmake Modified: llvm/trunk/cmake/modules/LLVMProcessSources.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMProcessSources.cmake?rev=122648&r1=122647&r2=122648&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMProcessSources.cmake (original) +++ llvm/trunk/cmake/modules/LLVMProcessSources.cmake Fri Dec 31 13:10:49 2010 @@ -42,7 +42,7 @@ if( CMAKE_COMPILER_IS_GNUCXX ) add_definitions( -fno-exceptions ) elseif( MSVC ) - add_definitions( /EHs-c- ) + string( REGEX REPLACE "[ ^]/EHsc ?" " /EHs-c- " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" ) add_definitions( /D_HAS_EXCEPTIONS=0 ) endif() endif() @@ -50,7 +50,7 @@ if( CMAKE_COMPILER_IS_GNUCXX ) add_definitions( -fno-rtti ) elseif( MSVC ) - add_definitions( /GR- ) + string( REGEX REPLACE "[ ^]/GR ?" " /GR- " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" ) endif() endif() From ofv at wanadoo.es Fri Dec 31 14:15:37 2010 From: ofv at wanadoo.es (Oscar Fuentes) Date: Fri, 31 Dec 2010 20:15:37 -0000 Subject: [llvm-commits] [llvm] r122649 - /llvm/trunk/lib/Target/X86/CMakeLists.txt Message-ID: <20101231201537.D145B2A6C12C@llvm.org> Author: ofv Date: Fri Dec 31 14:15:37 2010 New Revision: 122649 URL: http://llvm.org/viewvc/llvm-project?rev=122649&view=rev Log: Add to the list of cmake files the object file, not the asm file. This is necessary for executing the custom command that runs the assember. Fixes PR8877. Modified: llvm/trunk/lib/Target/X86/CMakeLists.txt Modified: llvm/trunk/lib/Target/X86/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/CMakeLists.txt?rev=122649&r1=122648&r2=122649&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/X86/CMakeLists.txt Fri Dec 31 14:15:37 2010 @@ -47,7 +47,7 @@ MAIN_DEPENDENCY X86CompilationCallback_Win64.asm COMMAND ${CMAKE_ASM_MASM_COMPILER} /Fo ${CMAKE_CURRENT_BINARY_DIR}/X86CompilationCallback_Win64.obj /c ${CMAKE_CURRENT_SOURCE_DIR}/X86CompilationCallback_Win64.asm ) - set(sources ${sources} X86CompilationCallback_Win64.asm) + set(sources ${sources} ${CMAKE_CURRENT_BINARY_DIR}/X86CompilationCallback_Win64.obj) endif() add_llvm_target(X86CodeGen ${sources}) From idadesub at users.sourceforge.net Fri Dec 31 21:27:43 2010 From: idadesub at users.sourceforge.net (Erick Tryzelaar) Date: Sat, 01 Jan 2011 03:27:43 -0000 Subject: [llvm-commits] [llvm] r122650 - in /llvm/trunk/docs/tutorial: OCamlLangImpl7.html OCamlLangImpl8.html Message-ID: <20110101032743.A29712A6C12C@llvm.org> Author: erickt Date: Fri Dec 31 21:27:43 2010 New Revision: 122650 URL: http://llvm.org/viewvc/llvm-project?rev=122650&view=rev Log: Add an OCaml tutorial page 8 Added: llvm/trunk/docs/tutorial/OCamlLangImpl8.html Modified: llvm/trunk/docs/tutorial/OCamlLangImpl7.html Modified: llvm/trunk/docs/tutorial/OCamlLangImpl7.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl7.html?rev=122650&r1=122649&r2=122650&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/OCamlLangImpl7.html (original) +++ llvm/trunk/docs/tutorial/OCamlLangImpl7.html Fri Dec 31 21:27:43 2010 @@ -30,7 +30,7 @@
  • Full Code Listing
  • -
  • Chapter 8: Conclusion and other useful LLVM +
  • Chapter 8: Conclusion and other useful LLVM tidbits
  • Added: llvm/trunk/docs/tutorial/OCamlLangImpl8.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl8.html?rev=122650&view=auto ============================================================================== --- llvm/trunk/docs/tutorial/OCamlLangImpl8.html (added) +++ llvm/trunk/docs/tutorial/OCamlLangImpl8.html Fri Dec 31 21:27:43 2010 @@ -0,0 +1,365 @@ + + + + + Kaleidoscope: Conclusion and other useful LLVM tidbits + + + + + + + +
    Kaleidoscope: Conclusion and other useful LLVM + tidbits
    + + + + +
    +

    Written by Chris Lattner

    +
    + + + + + +
    + +

    Welcome to the the final chapter of the "Implementing a +language with LLVM" tutorial. In the course of this tutorial, we have grown +our little Kaleidoscope language from being a useless toy, to being a +semi-interesting (but probably still useless) toy. :)

    + +

    It is interesting to see how far we've come, and how little code it has +taken. We built the entire lexer, parser, AST, code generator, and an +interactive run-loop (with a JIT!) by-hand in under 700 lines of +(non-comment/non-blank) code.

    + +

    Our little language supports a couple of interesting features: it supports +user defined binary and unary operators, it uses JIT compilation for immediate +evaluation, and it supports a few control flow constructs with SSA construction. +

    + +

    Part of the idea of this tutorial was to show you how easy and fun it can be +to define, build, and play with languages. Building a compiler need not be a +scary or mystical process! Now that you've seen some of the basics, I strongly +encourage you to take the code and hack on it. For example, try adding:

    + +
      +
    • global variables - While global variables have questional value in +modern software engineering, they are often useful when putting together quick +little hacks like the Kaleidoscope compiler itself. Fortunately, our current +setup makes it very easy to add global variables: just have value lookup check +to see if an unresolved variable is in the global variable symbol table before +rejecting it. To create a new global variable, make an instance of the LLVM +GlobalVariable class.
    • + +
    • typed variables - Kaleidoscope currently only supports variables of +type double. This gives the language a very nice elegance, because only +supporting one type means that you never have to specify types. Different +languages have different ways of handling this. The easiest way is to require +the user to specify types for every variable definition, and record the type +of the variable in the symbol table along with its Value*.
    • + +
    • arrays, structs, vectors, etc - Once you add types, you can start +extending the type system in all sorts of interesting ways. Simple arrays are +very easy and are quite useful for many different applications. Adding them is +mostly an exercise in learning how the LLVM getelementptr instruction works: it +is so nifty/unconventional, it has its own FAQ! If you add support +for recursive types (e.g. linked lists), make sure to read the section in the LLVM +Programmer's Manual that describes how to construct them.
    • + +
    • standard runtime - Our current language allows the user to access +arbitrary external functions, and we use it for things like "printd" and +"putchard". As you extend the language to add higher-level constructs, often +these constructs make the most sense if they are lowered to calls into a +language-supplied runtime. For example, if you add hash tables to the language, +it would probably make sense to add the routines to a runtime, instead of +inlining them all the way.
    • + +
    • memory management - Currently we can only access the stack in +Kaleidoscope. It would also be useful to be able to allocate heap memory, +either with calls to the standard libc malloc/free interface or with a garbage +collector. If you would like to use garbage collection, note that LLVM fully +supports Accurate Garbage Collection +including algorithms that move objects and need to scan/update the stack.
    • + +
    • debugger support - LLVM supports generation of DWARF Debug info which is understood by +common debuggers like GDB. Adding support for debug info is fairly +straightforward. The best way to understand it is to compile some C/C++ code +with "llvm-gcc -g -O0" and taking a look at what it produces.
    • + +
    • exception handling support - LLVM supports generation of zero cost exceptions which interoperate +with code compiled in other languages. You could also generate code by +implicitly making every function return an error value and checking it. You +could also make explicit use of setjmp/longjmp. There are many different ways +to go here.
    • + +
    • object orientation, generics, database access, complex numbers, +geometric programming, ... - Really, there is +no end of crazy features that you can add to the language.
    • + +
    • unusual domains - We've been talking about applying LLVM to a domain +that many people are interested in: building a compiler for a specific language. +However, there are many other domains that can use compiler technology that are +not typically considered. For example, LLVM has been used to implement OpenGL +graphics acceleration, translate C++ code to ActionScript, and many other +cute and clever things. Maybe you will be the first to JIT compile a regular +expression interpreter into native code with LLVM?
    • + +
    + +

    +Have fun - try doing something crazy and unusual. Building a language like +everyone else always has, is much less fun than trying something a little crazy +or off the wall and seeing how it turns out. If you get stuck or want to talk +about it, feel free to email the llvmdev mailing +list: it has lots of people who are interested in languages and are often +willing to help out. +

    + +

    Before we end this tutorial, I want to talk about some "tips and tricks" for generating +LLVM IR. These are some of the more subtle things that may not be obvious, but +are very useful if you want to take advantage of LLVM's capabilities.

    + +
    + + + + + +
    + +

    We have a couple common questions about code in the LLVM IR form - lets just +get these out of the way right now, shall we?

    + +
    + + + + + +
    + +

    Kaleidoscope is an example of a "portable language": any program written in +Kaleidoscope will work the same way on any target that it runs on. Many other +languages have this property, e.g. lisp, java, haskell, javascript, python, etc +(note that while these languages are portable, not all their libraries are).

    + +

    One nice aspect of LLVM is that it is often capable of preserving target +independence in the IR: you can take the LLVM IR for a Kaleidoscope-compiled +program and run it on any target that LLVM supports, even emitting C code and +compiling that on targets that LLVM doesn't support natively. You can trivially +tell that the Kaleidoscope compiler generates target-independent code because it +never queries for any target-specific information when generating code.

    + +

    The fact that LLVM provides a compact, target-independent, representation for +code gets a lot of people excited. Unfortunately, these people are usually +thinking about C or a language from the C family when they are asking questions +about language portability. I say "unfortunately", because there is really no +way to make (fully general) C code portable, other than shipping the source code +around (and of course, C source code is not actually portable in general +either - ever port a really old application from 32- to 64-bits?).

    + +

    The problem with C (again, in its full generality) is that it is heavily +laden with target specific assumptions. As one simple example, the preprocessor +often destructively removes target-independence from the code when it processes +the input text:

    + +
    +
    +#ifdef __i386__
    +  int X = 1;
    +#else
    +  int X = 42;
    +#endif
    +
    +
    + +

    While it is possible to engineer more and more complex solutions to problems +like this, it cannot be solved in full generality in a way that is better than shipping +the actual source code.

    + +

    That said, there are interesting subsets of C that can be made portable. If +you are willing to fix primitive types to a fixed size (say int = 32-bits, +and long = 64-bits), don't care about ABI compatibility with existing binaries, +and are willing to give up some other minor features, you can have portable +code. This can make sense for specialized domains such as an +in-kernel language.

    + +
    + + + + + +
    + +

    Many of the languages above are also "safe" languages: it is impossible for +a program written in Java to corrupt its address space and crash the process +(assuming the JVM has no bugs). +Safety is an interesting property that requires a combination of language +design, runtime support, and often operating system support.

    + +

    It is certainly possible to implement a safe language in LLVM, but LLVM IR +does not itself guarantee safety. The LLVM IR allows unsafe pointer casts, +use after free bugs, buffer over-runs, and a variety of other problems. Safety +needs to be implemented as a layer on top of LLVM and, conveniently, several +groups have investigated this. Ask on the llvmdev mailing +list if you are interested in more details.

    + +
    + + + + + +
    + +

    One thing about LLVM that turns off many people is that it does not solve all +the world's problems in one system (sorry 'world hunger', someone else will have +to solve you some other day). One specific complaint is that people perceive +LLVM as being incapable of performing high-level language-specific optimization: +LLVM "loses too much information".

    + +

    Unfortunately, this is really not the place to give you a full and unified +version of "Chris Lattner's theory of compiler design". Instead, I'll make a +few observations:

    + +

    First, you're right that LLVM does lose information. For example, as of this +writing, there is no way to distinguish in the LLVM IR whether an SSA-value came +from a C "int" or a C "long" on an ILP32 machine (other than debug info). Both +get compiled down to an 'i32' value and the information about what it came from +is lost. The more general issue here, is that the LLVM type system uses +"structural equivalence" instead of "name equivalence". Another place this +surprises people is if you have two types in a high-level language that have the +same structure (e.g. two different structs that have a single int field): these +types will compile down into a single LLVM type and it will be impossible to +tell what it came from.

    + +

    Second, while LLVM does lose information, LLVM is not a fixed target: we +continue to enhance and improve it in many different ways. In addition to +adding new features (LLVM did not always support exceptions or debug info), we +also extend the IR to capture important information for optimization (e.g. +whether an argument is sign or zero extended, information about pointers +aliasing, etc). Many of the enhancements are user-driven: people want LLVM to +include some specific feature, so they go ahead and extend it.

    + +

    Third, it is possible and easy to add language-specific +optimizations, and you have a number of choices in how to do it. As one trivial +example, it is easy to add language-specific optimization passes that +"know" things about code compiled for a language. In the case of the C family, +there is an optimization pass that "knows" about the standard C library +functions. If you call "exit(0)" in main(), it knows that it is safe to +optimize that into "return 0;" because C specifies what the 'exit' +function does.

    + +

    In addition to simple library knowledge, it is possible to embed a variety of +other language-specific information into the LLVM IR. If you have a specific +need and run into a wall, please bring the topic up on the llvmdev list. At the +very worst, you can always treat LLVM as if it were a "dumb code generator" and +implement the high-level optimizations you desire in your front-end, on the +language-specific AST. +

    + +
    + + + + + +
    + +

    There is a variety of useful tips and tricks that you come to know after +working on/with LLVM that aren't obvious at first glance. Instead of letting +everyone rediscover them, this section talks about some of these issues.

    + +
    + + + + + +
    + +

    One interesting thing that comes up, if you are trying to keep the code +generated by your compiler "target independent", is that you often need to know +the size of some LLVM type or the offset of some field in an llvm structure. +For example, you might need to pass the size of a type into a function that +allocates memory.

    + +

    Unfortunately, this can vary widely across targets: for example the width of +a pointer is trivially target-specific. However, there is a clever +way to use the getelementptr instruction that allows you to compute this +in a portable way.

    + +
    + + + + + +
    + +

    Some languages want to explicitly manage their stack frames, often so that +they are garbage collected or to allow easy implementation of closures. There +are often better ways to implement these features than explicit stack frames, +but LLVM +does support them, if you want. It requires your front-end to convert the +code into Continuation +Passing Style and the use of tail calls (which LLVM also supports).

    + +
    + + +
    +
    + Valid CSS! + Valid HTML 4.01! + + Chris Lattner
    + The LLVM Compiler Infrastructure
    + Last modified: $Date$ +
    + + From idadesub at users.sourceforge.net Fri Dec 31 21:29:25 2010 From: idadesub at users.sourceforge.net (Erick Tryzelaar) Date: Sat, 01 Jan 2011 03:29:25 -0000 Subject: [llvm-commits] [llvm] r122651 - /llvm/trunk/docs/tutorial/index.html Message-ID: <20110101032925.451602A6C12C@llvm.org> Author: erickt Date: Fri Dec 31 21:29:25 2010 New Revision: 122651 URL: http://llvm.org/viewvc/llvm-project?rev=122651&view=rev Log: Add a reference to the OCamlLangImpl8. Modified: llvm/trunk/docs/tutorial/index.html Modified: llvm/trunk/docs/tutorial/index.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/index.html?rev=122651&r1=122650&r2=122651&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/index.html (original) +++ llvm/trunk/docs/tutorial/index.html Fri Dec 31 21:29:25 2010 @@ -35,7 +35,7 @@
  • Extending the language: control flow
  • Extending the language: user-defined operators
  • Extending the language: mutable variables / SSA construction
  • -
  • Conclusion and other useful LLVM tidbits
  • +
  • Conclusion and other useful LLVM tidbits
  • Advanced Topics
      From clchiou at gmail.com Sat Jan 1 04:50:38 2011 From: clchiou at gmail.com (Che-Liang Chiou) Date: Sat, 01 Jan 2011 10:50:38 -0000 Subject: [llvm-commits] [llvm] r122652 - in /llvm/trunk: lib/Target/PTX/PTXInstrInfo.td lib/Target/PTX/PTXMFInfoExtract.cpp lib/Target/PTX/PTXTargetMachine.cpp lib/Target/PTX/PTXTargetMachine.h test/CodeGen/PTX/st.ll Message-ID: <20110101105038.1C34A2A6C12C@llvm.org> Author: clchiou Date: Sat Jan 1 04:50:37 2011 New Revision: 122652 URL: http://llvm.org/viewvc/llvm-project?rev=122652&view=rev Log: ptx: add store instruction Added: llvm/trunk/test/CodeGen/PTX/st.ll Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td llvm/trunk/lib/Target/PTX/PTXMFInfoExtract.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.h Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=122652&r1=122651&r2=122652&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Sat Jan 1 04:50:37 2011 @@ -66,6 +66,56 @@ return false; }]>; +def store_global + : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::GLOBAL; + return false; +}]>; + +def store_constant + : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::CONSTANT; + return false; +}]>; + +def store_local + : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::LOCAL; + return false; +}]>; + +def store_parameter + : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::PARAMETER; + return false; +}]>; + +def store_shared + : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{ + const Value *Src; + const PointerType *PT; + if ((Src = cast(N)->getSrcValue()) && + (PT = dyn_cast(Src->getType()))) + return PT->getAddressSpace() == PTX::SHARED; + return false; +}]>; + // Addressing modes. def ADDRrr : ComplexPattern; def ADDRri : ComplexPattern; @@ -145,6 +195,21 @@ [(set RC:$d, (pat_load ADDRii:$a))]>; } +multiclass PTX_ST { + def rr : InstPTX<(outs), + (ins RC:$d, MEMrr:$a), + !strconcat(opstr, ".%type\t[$a], $d"), + [(pat_store RC:$d, ADDRrr:$a)]>; + def ri : InstPTX<(outs), + (ins RC:$d, MEMri:$a), + !strconcat(opstr, ".%type\t[$a], $d"), + [(pat_store RC:$d, ADDRri:$a)]>; + def ii : InstPTX<(outs), + (ins RC:$d, MEMii:$a), + !strconcat(opstr, ".%type\t[$a], $d"), + [(pat_store RC:$d, ADDRii:$a)]>; +} + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -185,6 +250,12 @@ defm LDp : PTX_LD<"ld.param", RRegs32, load_parameter>; defm LDs : PTX_LD<"ld.shared", RRegs32, load_shared>; +defm STg : PTX_ST<"st.global", RRegs32, store_global>; +defm STc : PTX_ST<"st.const", RRegs32, store_constant>; +defm STl : PTX_ST<"st.local", RRegs32, store_local>; +defm STp : PTX_ST<"st.param", RRegs32, store_parameter>; +defm STs : PTX_ST<"st.shared", RRegs32, store_shared>; + ///===- Control Flow Instructions -----------------------------------------===// let isReturn = 1, isTerminator = 1, isBarrier = 1 in { Modified: llvm/trunk/lib/Target/PTX/PTXMFInfoExtract.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXMFInfoExtract.cpp?rev=122652&r1=122651&r2=122652&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXMFInfoExtract.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXMFInfoExtract.cpp Sat Jan 1 04:50:37 2011 @@ -22,6 +22,8 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +// NOTE: PTXMFInfoExtract must after register allocation! + namespace llvm { /// PTXMFInfoExtract - PTX specific code to extract of PTX machine /// function information for PTXAsmPrinter @@ -50,22 +52,38 @@ PTXMachineFunctionInfo *MFI = MF.getInfo(); MachineRegisterInfo &MRI = MF.getRegInfo(); - DEBUG(dbgs() << "****** PTX FUNCTION LOCAL VAR REG DEF ******\n"); + DEBUG(dbgs() << "******** PTX FUNCTION LOCAL VAR REG DEF ********\n"); + + unsigned retreg = MFI->retReg(); - unsigned reg_ret = MFI->retReg(); + DEBUG(dbgs() + << "PTX::NoRegister == " << PTX::NoRegister << "\n" + << "PTX::NUM_TARGET_REGS == " << PTX::NUM_TARGET_REGS << "\n"); + + DEBUG(for (unsigned reg = PTX::NoRegister + 1; + reg < PTX::NUM_TARGET_REGS; ++reg) + if (MRI.isPhysRegUsed(reg)) + dbgs() << "Used Reg: " << reg << "\n";); // FIXME: This is a slow linear scanning for (unsigned reg = PTX::NoRegister + 1; reg < PTX::NUM_TARGET_REGS; ++reg) - if (MRI.isPhysRegUsed(reg) && reg != reg_ret && !MFI->isArgReg(reg)) + if (MRI.isPhysRegUsed(reg) && reg != retreg && !MFI->isArgReg(reg)) MFI->addLocalVarReg(reg); // Notify MachineFunctionInfo that I've done adding local var reg MFI->doneAddLocalVar(); + DEBUG(dbgs() << "Return Reg: " << retreg << "\n"); + + DEBUG(for (PTXMachineFunctionInfo::reg_iterator + i = MFI->argRegBegin(), e = MFI->argRegEnd(); + i != e; ++i) + dbgs() << "Arg Reg: " << *i << "\n";); + DEBUG(for (PTXMachineFunctionInfo::reg_iterator i = MFI->localVarRegBegin(), e = MFI->localVarRegEnd(); i != e; ++i) - dbgs() << "Used Reg: " << *i << "\n";); + dbgs() << "Local Var Reg: " << *i << "\n";); return false; } Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp?rev=122652&r1=122651&r2=122652&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Sat Jan 1 04:50:37 2011 @@ -49,6 +49,12 @@ bool PTXTargetMachine::addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel) { PM.add(createPTXISelDag(*this, OptLevel)); + return false; +} + +bool PTXTargetMachine::addPostRegAlloc(PassManagerBase &PM, + CodeGenOpt::Level OptLevel) { + // PTXMFInfoExtract must after register allocation! PM.add(createPTXMFInfoExtract(*this, OptLevel)); return false; } Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.h?rev=122652&r1=122651&r2=122652&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.h (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.h Sat Jan 1 04:50:37 2011 @@ -50,6 +50,8 @@ virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel); + virtual bool addPostRegAlloc(PassManagerBase &PM, + CodeGenOpt::Level OptLevel); }; // class PTXTargetMachine } // namespace llvm Added: llvm/trunk/test/CodeGen/PTX/st.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/st.ll?rev=122652&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PTX/st.ll (added) +++ llvm/trunk/test/CodeGen/PTX/st.ll Sat Jan 1 04:50:37 2011 @@ -0,0 +1,78 @@ +; RUN: llc < %s -march=ptx | FileCheck %s + +;CHECK: .extern .global .s32 array[]; + at array = external global [10 x i32] + +;CHECK: .extern .const .s32 array_constant[]; + at array_constant = external addrspace(1) constant [10 x i32] + +;CHECK: .extern .local .s32 array_local[]; + at array_local = external addrspace(2) global [10 x i32] + +;CHECK: .extern .shared .s32 array_shared[]; + at array_shared = external addrspace(4) global [10 x i32] + +define ptx_device void @t1(i32* %p, i32 %x) { +entry: +;CHECK: st.global.s32 [r1], r2; + store i32 %x, i32* %p + ret void +} + +define ptx_device void @t2(i32* %p, i32 %x) { +entry: +;CHECK: st.global.s32 [r1+4], r2; + %i = getelementptr i32* %p, i32 1 + store i32 %x, i32* %i + ret void +} + +define ptx_device void @t3(i32* %p, i32 %q, i32 %x) { +;CHECK: .reg .s32 r0; +entry: +;CHECK: shl.b32 r0, r2, 2; +;CHECK: st.global.s32 [r1+r0], r3; + %i = getelementptr i32* %p, i32 %q + store i32 %x, i32* %i + ret void +} + +define ptx_device void @t4_global(i32 %x) { +entry: +;CHECK: st.global.s32 [array], r1; + %i = getelementptr [10 x i32]* @array, i32 0, i32 0 + store i32 %x, i32* %i + ret void +} + +define ptx_device void @t4_const(i32 %x) { +entry: +;CHECK: st.const.s32 [array_constant], r1; + %i = getelementptr [10 x i32] addrspace(1)* @array_constant, i32 0, i32 0 + store i32 %x, i32 addrspace(1)* %i + ret void +} + +define ptx_device void @t4_local(i32 %x) { +entry: +;CHECK: st.local.s32 [array_local], r1; + %i = getelementptr [10 x i32] addrspace(2)* @array_local, i32 0, i32 0 + store i32 %x, i32 addrspace(2)* %i + ret void +} + +define ptx_device void @t4_shared(i32 %x) { +entry: +;CHECK: st.shared.s32 [array_shared], r1; + %i = getelementptr [10 x i32] addrspace(4)* @array_shared, i32 0, i32 0 + store i32 %x, i32 addrspace(4)* %i + ret void +} + +define ptx_device void @t5(i32 %x) { +entry: +;CHECK: st.global.s32 [array+4], r1; + %i = getelementptr [10 x i32]* @array, i32 0, i32 1 + store i32 %x, i32* %i + ret void +} From clchiou at gmail.com Sat Jan 1 05:58:58 2011 From: clchiou at gmail.com (Che-Liang Chiou) Date: Sat, 01 Jan 2011 11:58:58 -0000 Subject: [llvm-commits] [llvm] r122653 - in /llvm/trunk: lib/Target/PTX/PTXISelDAGToDAG.cpp lib/Target/PTX/PTXInstrInfo.td test/CodeGen/PTX/ld.ll test/CodeGen/PTX/st.ll Message-ID: <20110101115858.874722A6C12C@llvm.org> Author: clchiou Date: Sat Jan 1 05:58:58 2011 New Revision: 122653 URL: http://llvm.org/viewvc/llvm-project?rev=122653&view=rev Log: ptx: remove reg-reg addressing mode and st.const Modified: llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.td llvm/trunk/test/CodeGen/PTX/ld.ll llvm/trunk/test/CodeGen/PTX/st.ll Modified: llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp?rev=122653&r1=122652&r2=122653&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp Sat Jan 1 05:58:58 2011 @@ -67,8 +67,8 @@ isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1))) return false; - R1 = Addr.getOperand(0); - R2 = Addr.getOperand(1); + R1 = Addr; + R2 = CurDAG->getTargetConstant(0, MVT::i32); return true; } @@ -76,17 +76,20 @@ bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset) { if (Addr.getOpcode() != ISD::ADD) { + // let SelectADDRii handle the [imm] case if (isImm(Addr)) return false; - // is [reg] but not [imm] + // it is [reg] Base = Addr; Offset = CurDAG->getTargetConstant(0, MVT::i32); return true; } + if (Addr.getNumOperands() < 2) + return false; + // let SelectADDRii handle the [imm+imm] case - if (Addr.getNumOperands() >= 2 && - isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1))) + if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1))) return false; // try [reg+imm] and [imm+reg] @@ -96,13 +99,7 @@ return true; } - // either [reg+imm] and [imm+reg] - for (int i = 0; i < 2; i ++) - if (SelectImm(Addr.getOperand(1-i), Offset)) { - Base = Addr.getOperand(i); - return true; - } - + // neither [reg+imm] nor [imm+reg] return false; } Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=122653&r1=122652&r2=122653&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Sat Jan 1 05:58:58 2011 @@ -76,16 +76,6 @@ return false; }]>; -def store_constant - : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{ - const Value *Src; - const PointerType *PT; - if ((Src = cast(N)->getSrcValue()) && - (PT = dyn_cast(Src->getType()))) - return PT->getAddressSpace() == PTX::CONSTANT; - return false; -}]>; - def store_local : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{ const Value *Src; @@ -122,10 +112,6 @@ def ADDRii : ComplexPattern; // Address operands -def MEMrr : Operand { - let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops RRegs32, RRegs32); -} def MEMri : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops RRegs32, i32imm); @@ -182,7 +168,7 @@ multiclass PTX_LD { def rr : InstPTX<(outs RC:$d), - (ins MEMrr:$a), + (ins MEMri:$a), !strconcat(opstr, ".%type\t$d, [$a]"), [(set RC:$d, (pat_load ADDRrr:$a))]>; def ri : InstPTX<(outs RC:$d), @@ -197,7 +183,7 @@ multiclass PTX_ST { def rr : InstPTX<(outs), - (ins RC:$d, MEMrr:$a), + (ins RC:$d, MEMri:$a), !strconcat(opstr, ".%type\t[$a], $d"), [(pat_store RC:$d, ADDRrr:$a)]>; def ri : InstPTX<(outs), @@ -251,7 +237,6 @@ defm LDs : PTX_LD<"ld.shared", RRegs32, load_shared>; defm STg : PTX_ST<"st.global", RRegs32, store_global>; -defm STc : PTX_ST<"st.const", RRegs32, store_constant>; defm STl : PTX_ST<"st.local", RRegs32, store_local>; defm STp : PTX_ST<"st.param", RRegs32, store_parameter>; defm STs : PTX_ST<"st.shared", RRegs32, store_shared>; Modified: llvm/trunk/test/CodeGen/PTX/ld.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/ld.ll?rev=122653&r1=122652&r2=122653&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/ld.ll (original) +++ llvm/trunk/test/CodeGen/PTX/ld.ll Sat Jan 1 05:58:58 2011 @@ -30,7 +30,8 @@ define ptx_device i32 @t3(i32* %p, i32 %q) { entry: ;CHECK: shl.b32 r0, r2, 2; -;CHECK: ld.global.s32 r0, [r1+r0]; +;CHECK: add.s32 r0, r1, r0; +;CHECK: ld.global.s32 r0, [r0]; %i = getelementptr i32* %p, i32 %q %x = load i32* %i ret i32 %x Modified: llvm/trunk/test/CodeGen/PTX/st.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/st.ll?rev=122653&r1=122652&r2=122653&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/st.ll (original) +++ llvm/trunk/test/CodeGen/PTX/st.ll Sat Jan 1 05:58:58 2011 @@ -31,7 +31,8 @@ ;CHECK: .reg .s32 r0; entry: ;CHECK: shl.b32 r0, r2, 2; -;CHECK: st.global.s32 [r1+r0], r3; +;CHECK: add.s32 r0, r1, r0; +;CHECK: st.global.s32 [r0], r3; %i = getelementptr i32* %p, i32 %q store i32 %x, i32* %i ret void @@ -45,14 +46,6 @@ ret void } -define ptx_device void @t4_const(i32 %x) { -entry: -;CHECK: st.const.s32 [array_constant], r1; - %i = getelementptr [10 x i32] addrspace(1)* @array_constant, i32 0, i32 0 - store i32 %x, i32 addrspace(1)* %i - ret void -} - define ptx_device void @t4_local(i32 %x) { entry: ;CHECK: st.local.s32 [array_local], r1; From baldrick at free.fr Sat Jan 1 10:12:09 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 01 Jan 2011 16:12:09 -0000 Subject: [llvm-commits] [llvm] r122654 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp lib/Target/README.txt test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll Message-ID: <20110101161209.8EA9A2A6C12C@llvm.org> Author: baldrick Date: Sat Jan 1 10:12:09 2011 New Revision: 122654 URL: http://llvm.org/viewvc/llvm-project?rev=122654&view=rev Log: Fix a README item by having InstructionSimplify do a mild form of value numbering, in which it considers (for example) "%a = add i32 %x, %y" and "%b = add i32 %x, %y" to be equal because the operands are equal and the result of the instructions only depends on the values of the operands. This has almost no effect (it removes 4 instructions from gcc-as-one-file), and perhaps slows down compilation: I measured a 0.4% slowdown on the large gcc-as-one-file testcase, but it wasn't statistically significant. Added: llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122654&r1=122653&r2=122654&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Sat Jan 1 10:12:09 2011 @@ -28,7 +28,7 @@ using namespace llvm; using namespace llvm::PatternMatch; -#define RecursionLimit 3 +#define RecursionLimit 4 STATISTIC(NumExpand, "Number of expansions"); STATISTIC(NumFactor , "Number of factorizations"); @@ -45,6 +45,53 @@ static Value *SimplifyXorInst(Value *, Value *, const TargetData *, const DominatorTree *, unsigned); +/// equal - Return true if the given values are known to be equal, false if they +/// are not equal or it is not clear whether they are equal or not. +static bool equal(Value *A, Value *B, unsigned MaxRecurse) { + // If the pointers are equal then the values are! + if (A == B) + return true; + // From this point on either recursion is used or the result is false, so bail + // out at once if we already hit the recursion limit. + if (!MaxRecurse--) + return false; + // If these are instructions, see if they compute the same value. + Instruction *AI = dyn_cast(A), *BI = dyn_cast(B); + if (!AI || !BI) + return false; + // If one of the instructions has extra flags attached then be conservative + // and say that the instructions differ. + if (!AI->hasSameSubclassOptionalData(BI)) + return false; + // For some reason alloca's are not considered to read or write memory, yet + // each one nonetheless manages to return a different value... + if (isa(AI)) + return false; + // Do not consider instructions to be equal if they may access memory. + if (AI->mayReadFromMemory() || AI->mayWriteToMemory()) + return false; + // If the instructions do not perform the same computation then bail out. + if (!BI->isSameOperationAs(AI)) + return false; + + // Check whether all operands are equal. If they are then the instructions + // have the same value. + bool AllOperandsEqual = true; + for (unsigned i = 0, e = AI->getNumOperands(); i != e; ++i) + if (!equal(AI->getOperand(i), BI->getOperand(i), MaxRecurse)) { + AllOperandsEqual = false; + break; + } + if (AllOperandsEqual) + return true; + + // If the instructions are commutative and their operands are equal when + // swapped then the instructions have the same value. + return AI->isCommutative() && + equal(AI->getOperand(0), BI->getOperand(1), MaxRecurse) && + equal(AI->getOperand(1), BI->getOperand(0), MaxRecurse); +} + /// ValueDominatesPHI - Does the given value dominate the specified phi node? static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) { Instruction *I = dyn_cast(V); @@ -88,8 +135,9 @@ if (Value *R = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) { // They do! Return "L op' R" if it simplifies or is already available. // If "L op' R" equals "A op' B" then "L op' R" is just the LHS. - if ((L == A && R == B) || (Instruction::isCommutative(OpcodeToExpand) - && L == B && R == A)) { + if ((equal(L, A, MaxRecurse) && equal(R, B, MaxRecurse)) || + (Instruction::isCommutative(OpcodeToExpand) && + equal(L, B, MaxRecurse) && equal(R, A, MaxRecurse))) { ++NumExpand; return LHS; } @@ -112,8 +160,9 @@ if (Value *R = SimplifyBinOp(Opcode, A, C, TD, DT, MaxRecurse)) { // They do! Return "L op' R" if it simplifies or is already available. // If "L op' R" equals "B op' C" then "L op' R" is just the RHS. - if ((L == B && R == C) || (Instruction::isCommutative(OpcodeToExpand) - && L == C && R == B)) { + if ((equal(L, B, MaxRecurse) && equal(R, C, MaxRecurse)) || + (Instruction::isCommutative(OpcodeToExpand) && + equal(L, C, MaxRecurse) && equal(R, B, MaxRecurse))) { ++NumExpand; return RHS; } @@ -155,17 +204,23 @@ // Use left distributivity, i.e. "X op' (Y op Z) = (X op' Y) op (X op' Z)". // Does the instruction have the form "(A op' B) op (A op' D)" or, in the // commutative case, "(A op' B) op (C op' A)"? - if (A == C || (Instruction::isCommutative(OpcodeToExtract) && A == D)) { - Value *DD = A == C ? D : C; + bool AEqualsC = equal(A, C, MaxRecurse); + if (AEqualsC || (Instruction::isCommutative(OpcodeToExtract) && + equal(A, D, MaxRecurse))) { + Value *DD = AEqualsC ? D : C; // Form "A op' (B op DD)" if it simplifies completely. // Does "B op DD" simplify? if (Value *V = SimplifyBinOp(Opcode, B, DD, TD, DT, MaxRecurse)) { // It does! Return "A op' V" if it simplifies or is already available. // If V equals B then "A op' V" is just the LHS. If V equals DD then // "A op' V" is just the RHS. - if (V == B || V == DD) { + if (equal(V, B, MaxRecurse)) { ++NumFactor; - return V == B ? LHS : RHS; + return LHS; + } + if (equal(V, DD, MaxRecurse)) { + ++NumFactor; + return RHS; } // Otherwise return "A op' V" if it simplifies. if (Value *W = SimplifyBinOp(OpcodeToExtract, A, V, TD, DT, MaxRecurse)) { @@ -178,17 +233,23 @@ // Use right distributivity, i.e. "(X op Y) op' Z = (X op' Z) op (Y op' Z)". // Does the instruction have the form "(A op' B) op (C op' B)" or, in the // commutative case, "(A op' B) op (B op' D)"? - if (B == D || (Instruction::isCommutative(OpcodeToExtract) && B == C)) { - Value *CC = B == D ? C : D; + bool BEqualsD = equal(B, D, MaxRecurse); + if (BEqualsD || (Instruction::isCommutative(OpcodeToExtract) && + equal(B, C, MaxRecurse))) { + Value *CC = BEqualsD ? C : D; // Form "(A op CC) op' B" if it simplifies completely.. // Does "A op CC" simplify? if (Value *V = SimplifyBinOp(Opcode, A, CC, TD, DT, MaxRecurse)) { // It does! Return "V op' B" if it simplifies or is already available. // If V equals A then "V op' B" is just the LHS. If V equals CC then // "V op' B" is just the RHS. - if (V == A || V == CC) { + if (equal(V, A, MaxRecurse)) { ++NumFactor; - return V == A ? LHS : RHS; + return LHS; + } + if (equal(V, CC, MaxRecurse)) { + ++NumFactor; + return RHS; } // Otherwise return "V op' B" if it simplifies. if (Value *W = SimplifyBinOp(OpcodeToExtract, V, B, TD, DT, MaxRecurse)) { @@ -227,7 +288,7 @@ if (Value *V = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) { // It does! Return "A op V" if it simplifies or is already available. // If V equals B then "A op V" is just the LHS. - if (V == B) return LHS; + if (equal(V, B, MaxRecurse)) return LHS; // Otherwise return "A op V" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, A, V, TD, DT, MaxRecurse)) { ++NumReassoc; @@ -246,7 +307,7 @@ if (Value *V = SimplifyBinOp(Opcode, A, B, TD, DT, MaxRecurse)) { // It does! Return "V op C" if it simplifies or is already available. // If V equals B then "V op C" is just the RHS. - if (V == B) return RHS; + if (equal(V, B, MaxRecurse)) return RHS; // Otherwise return "V op C" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, V, C, TD, DT, MaxRecurse)) { ++NumReassoc; @@ -269,7 +330,7 @@ if (Value *V = SimplifyBinOp(Opcode, C, A, TD, DT, MaxRecurse)) { // It does! Return "V op B" if it simplifies or is already available. // If V equals A then "V op B" is just the LHS. - if (V == A) return LHS; + if (equal(V, A, MaxRecurse)) return LHS; // Otherwise return "V op B" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, V, B, TD, DT, MaxRecurse)) { ++NumReassoc; @@ -288,7 +349,7 @@ if (Value *V = SimplifyBinOp(Opcode, C, A, TD, DT, MaxRecurse)) { // It does! Return "B op V" if it simplifies or is already available. // If V equals C then "B op V" is just the RHS. - if (V == C) return RHS; + if (equal(V, C, MaxRecurse)) return RHS; // Otherwise return "B op V" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, B, V, TD, DT, MaxRecurse)) { ++NumReassoc; @@ -331,9 +392,12 @@ FV = SimplifyBinOp(Opcode, LHS, SI->getFalseValue(), TD, DT, MaxRecurse); } - // If they simplified to the same value, then return the common value. // If they both failed to simplify then return null. - if (TV == FV) + if (!TV && !FV) + return 0; + + // If they simplified to the same value, then return the common value. + if (TV && FV && equal(TV, FV, MaxRecurse)) return TV; // If one branch simplified to undef, return the other one. @@ -344,7 +408,8 @@ // If applying the operation did not change the true and false select values, // then the result of the binop is the select itself. - if (TV == SI->getTrueValue() && FV == SI->getFalseValue()) + if (TV && equal(TV, SI->getTrueValue(), MaxRecurse) && + FV && equal(FV, SI->getFalseValue(), MaxRecurse)) return SI; // If one branch simplified and the other did not, and the simplified @@ -361,12 +426,12 @@ Value *UnsimplifiedBranch = FV ? SI->getTrueValue() : SI->getFalseValue(); Value *UnsimplifiedLHS = SI == LHS ? UnsimplifiedBranch : LHS; Value *UnsimplifiedRHS = SI == LHS ? RHS : UnsimplifiedBranch; - if (Simplified->getOperand(0) == UnsimplifiedLHS && - Simplified->getOperand(1) == UnsimplifiedRHS) + if (equal(Simplified->getOperand(0), UnsimplifiedLHS, MaxRecurse) && + equal(Simplified->getOperand(1), UnsimplifiedRHS, MaxRecurse)) return Simplified; if (Simplified->isCommutative() && - Simplified->getOperand(1) == UnsimplifiedLHS && - Simplified->getOperand(0) == UnsimplifiedRHS) + equal(Simplified->getOperand(1), UnsimplifiedLHS, MaxRecurse) && + equal(Simplified->getOperand(0), UnsimplifiedRHS, MaxRecurse)) return Simplified; } } @@ -403,7 +468,7 @@ MaxRecurse)) // It does! If they simplified to the same value, then use it as the // result of the original comparison. - if (TCmp == FCmp) + if (equal(TCmp, FCmp, MaxRecurse)) return TCmp; return 0; } @@ -519,14 +584,14 @@ // X + (Y - X) -> Y // (Y - X) + X -> Y // Eg: X + -X -> 0 - Value *Y = 0; - if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) || - match(Op0, m_Sub(m_Value(Y), m_Specific(Op1)))) + Value *X = 0, *Y = 0; + if ((match(Op1, m_Sub(m_Value(Y), m_Value(X))) && equal(X, Op0, MaxRecurse))|| + (match(Op0, m_Sub(m_Value(Y), m_Value(X))) && equal(X, Op1, MaxRecurse))) return Y; // X + ~X -> -1 since ~X = -X-1 - if (match(Op0, m_Not(m_Specific(Op1))) || - match(Op1, m_Not(m_Specific(Op0)))) + if ((match(Op0, m_Not(m_Value(X))) && equal(X, Op1, MaxRecurse)) || + (match(Op1, m_Not(m_Value(X))) && equal(X, Op0, MaxRecurse))) return Constant::getAllOnesValue(Op0->getType()); /// i1 add -> xor. @@ -583,14 +648,14 @@ return Op0; // X - X -> 0 - if (Op0 == Op1) + if (equal(Op0, Op1, MaxRecurse)) return Constant::getNullValue(Op0->getType()); // (X + Y) - Y -> X // (Y + X) - Y -> X - Value *X = 0; - if (match(Op0, m_Add(m_Value(X), m_Specific(Op1))) || - match(Op0, m_Add(m_Specific(Op1), m_Value(X)))) + Value *X = 0, *Y = 0; + if ((match(Op0, m_Add(m_Value(X), m_Value(Y))) && equal(Y, Op1, MaxRecurse))|| + (match(Op0, m_Add(m_Value(Y), m_Value(X))) && equal(Y, Op1, MaxRecurse))) return X; /// i1 sub -> xor. @@ -704,7 +769,7 @@ return Constant::getNullValue(Op0->getType()); // X & X = X - if (Op0 == Op1) + if (equal(Op0, Op1, MaxRecurse)) return Op0; // X & 0 = 0 @@ -717,18 +782,18 @@ // A & ~A = ~A & A = 0 Value *A = 0, *B = 0; - if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || - (match(Op1, m_Not(m_Value(A))) && A == Op0)) + if ((match(Op0, m_Not(m_Value(A))) && equal(A, Op1, MaxRecurse)) || + (match(Op1, m_Not(m_Value(A))) && equal(A, Op0, MaxRecurse))) return Constant::getNullValue(Op0->getType()); // (A | ?) & A = A if (match(Op0, m_Or(m_Value(A), m_Value(B))) && - (A == Op1 || B == Op1)) + (equal(A, Op1, MaxRecurse) || equal(B, Op1, MaxRecurse))) return Op1; // A & (A | ?) = A if (match(Op1, m_Or(m_Value(A), m_Value(B))) && - (A == Op0 || B == Op0)) + (equal(A, Op0, MaxRecurse) || equal(B, Op0, MaxRecurse))) return Op0; // Try some generic simplifications for associative operations. @@ -793,7 +858,7 @@ return Constant::getAllOnesValue(Op0->getType()); // X | X = X - if (Op0 == Op1) + if (equal(Op0, Op1, MaxRecurse)) return Op0; // X | 0 = X @@ -806,18 +871,18 @@ // A | ~A = ~A | A = -1 Value *A = 0, *B = 0; - if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || - (match(Op1, m_Not(m_Value(A))) && A == Op0)) + if ((match(Op0, m_Not(m_Value(A))) && equal(A, Op1, MaxRecurse)) || + (match(Op1, m_Not(m_Value(A))) && equal(A, Op0, MaxRecurse))) return Constant::getAllOnesValue(Op0->getType()); // (A & ?) | A = A if (match(Op0, m_And(m_Value(A), m_Value(B))) && - (A == Op1 || B == Op1)) + (equal(A, Op1, MaxRecurse) || equal(B, Op1, MaxRecurse))) return Op1; // A | (A & ?) = A if (match(Op1, m_And(m_Value(A), m_Value(B))) && - (A == Op0 || B == Op0)) + (equal(A, Op0, MaxRecurse) || equal(B, Op0, MaxRecurse))) return Op0; // Try some generic simplifications for associative operations. @@ -881,13 +946,13 @@ return Op0; // A ^ A = 0 - if (Op0 == Op1) + if (equal(Op0, Op1, MaxRecurse)) return Constant::getNullValue(Op0->getType()); // A ^ ~A = ~A ^ A = -1 Value *A = 0; - if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || - (match(Op1, m_Not(m_Value(A))) && A == Op0)) + if ((match(Op0, m_Not(m_Value(A))) && equal(A, Op1, MaxRecurse)) || + (match(Op1, m_Not(m_Value(A))) && equal(A, Op0, MaxRecurse))) return Constant::getAllOnesValue(Op0->getType()); // Try some generic simplifications for associative operations. @@ -944,7 +1009,7 @@ // icmp X, X -> true/false // X icmp undef -> true/false. For example, icmp ugt %X, undef -> false // because X could be 0. - if (LHS == RHS || isa(RHS)) + if (isa(RHS) || equal(LHS, RHS, MaxRecurse)) return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred)); // icmp , - Global/Stack value @@ -1028,7 +1093,7 @@ return UndefValue::get(GetCompareTy(LHS)); // fcmp x,x -> true/false. Not all compares are foldable. - if (LHS == RHS) { + if (equal(LHS, RHS, MaxRecurse)) { if (CmpInst::isTrueWhenEqual(Pred)) return ConstantInt::get(GetCompareTy(LHS), 1); if (CmpInst::isFalseWhenEqual(Pred)) @@ -1098,15 +1163,16 @@ /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold /// the result. If not, this returns null. -Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, - const TargetData *TD, const DominatorTree *) { +static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, + const TargetData *TD, const DominatorTree *, + unsigned MaxRecurse) { // select true, X, Y -> X // select false, X, Y -> Y if (ConstantInt *CB = dyn_cast(CondVal)) return CB->getZExtValue() ? TrueVal : FalseVal; // select C, X, X -> X - if (TrueVal == FalseVal) + if (equal(TrueVal, FalseVal, MaxRecurse)) return TrueVal; if (isa(TrueVal)) // select C, undef, X -> X @@ -1122,6 +1188,12 @@ return 0; } +Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifySelectInst(CondVal, TrueVal, FalseVal, TD, DT, + RecursionLimit); +} + /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps, Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=122654&r1=122653&r2=122654&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Jan 1 10:12:09 2011 @@ -2065,14 +2065,3 @@ } //===---------------------------------------------------------------------===// - -This compare could fold to false: - -define i1 @g(i32 a) nounwind readnone { - %add = shl i32 %a, 1 - %mul = shl i32 %a, 1 - %cmp = icmp ugt i32 %add, %mul - ret i1 %cmp -} - -//===---------------------------------------------------------------------===// Added: llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll?rev=122654&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll (added) +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll Sat Jan 1 10:12:09 2011 @@ -0,0 +1,9 @@ +; RUN: opt < %s -instsimplify -S | FileCheck %s +define i1 @g(i32 %a) nounwind readnone { +; CHECK: @g + %add = shl i32 %a, 1 + %mul = shl i32 %a, 1 + %cmp = icmp ugt i32 %add, %mul + ret i1 %cmp +; CHECK: ret i1 false +} From baldrick at free.fr Sat Jan 1 11:21:58 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 01 Jan 2011 17:21:58 -0000 Subject: [llvm-commits] [llvm] r122655 - /llvm/trunk/docs/WritingAnLLVMPass.html Message-ID: <20110101172158.ADD802A6C12C@llvm.org> Author: baldrick Date: Sat Jan 1 11:21:58 2011 New Revision: 122655 URL: http://llvm.org/viewvc/llvm-project?rev=122655&view=rev Log: Clarify that the loadable module turns up in the top-level directory, not locally. Modified: llvm/trunk/docs/WritingAnLLVMPass.html Modified: llvm/trunk/docs/WritingAnLLVMPass.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/WritingAnLLVMPass.html?rev=122655&r1=122654&r2=122655&view=diff ============================================================================== --- llvm/trunk/docs/WritingAnLLVMPass.html (original) +++ llvm/trunk/docs/WritingAnLLVMPass.html Sat Jan 1 11:21:58 2011 @@ -203,8 +203,8 @@

      This makefile specifies that all of the .cpp files in the current -directory are to be compiled and linked together into a -Debug+Asserts/lib/Hello.so shared object that can be dynamically loaded by +directory are to be compiled and linked together into a shared object +$(LEVEL)/Debug+Asserts/lib/Hello.so that can be dynamically loaded by the opt or bugpoint tools via their -load options. If your operating system uses a suffix other than .so (such as windows or Mac OS/X), the appropriate extension will be used.

      @@ -341,8 +341,9 @@

      Now that it's all together, compile the file with a simple "gmake" -command in the local directory and you should get a new -"Debug+Asserts/lib/Hello.so file. Note that everything in this file is +command in the local directory and you should get a new file +"Debug+Asserts/lib/Hello.so" under the top level directory of the LLVM +source tree (not in the local directory). Note that everything in this file is contained in an anonymous namespace: this reflects the fact that passes are self contained units that do not need external interfaces (although they can have them) to be useful.

      From baldrick at free.fr Sat Jan 1 11:28:50 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 01 Jan 2011 17:28:50 -0000 Subject: [llvm-commits] [llvm] r122656 - /llvm/trunk/docs/WritingAnLLVMPass.html Message-ID: <20110101172850.42B042A6C12C@llvm.org> Author: baldrick Date: Sat Jan 1 11:28:49 2011 New Revision: 122656 URL: http://llvm.org/viewvc/llvm-project?rev=122656&view=rev Log: I was unable to get the instructions to work if LLVM was built using a separate objects directory. Modified: llvm/trunk/docs/WritingAnLLVMPass.html Modified: llvm/trunk/docs/WritingAnLLVMPass.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/WritingAnLLVMPass.html?rev=122656&r1=122655&r2=122656&view=diff ============================================================================== --- llvm/trunk/docs/WritingAnLLVMPass.html (original) +++ llvm/trunk/docs/WritingAnLLVMPass.html Sat Jan 1 11:28:49 2011 @@ -178,9 +178,11 @@
      -

      First, you need to create a new directory somewhere in the LLVM source +

      First, configure and build LLVM. This needs to be done directly inside the + LLVM source tree rather than in a separate objects directory. + Next, you need to create a new directory somewhere in the LLVM source base. For this example, we'll assume that you made - lib/Transforms/Hello. Next, you must set up a build script + lib/Transforms/Hello. Finally, you must set up a build script (Makefile) that will compile the source code for the new pass. To do this, copy the following into Makefile:


      From baldrick at free.fr Sat Jan 1 11:37:07 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 01 Jan 2011 17:37:07 -0000 Subject: [llvm-commits] [llvm] r122657 - /llvm/trunk/docs/WritingAnLLVMPass.html Message-ID: <20110101173708.0925C2A6C12C@llvm.org> Author: baldrick Date: Sat Jan 1 11:37:07 2011 New Revision: 122657 URL: http://llvm.org/viewvc/llvm-project?rev=122657&view=rev Log: Correct a bunch of mistakes which meant that the example pass didn't even compile, let alone work. Modified: llvm/trunk/docs/WritingAnLLVMPass.html Modified: llvm/trunk/docs/WritingAnLLVMPass.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/WritingAnLLVMPass.html?rev=122657&r1=122656&r2=122657&view=diff ============================================================================== --- llvm/trunk/docs/WritingAnLLVMPass.html (original) +++ llvm/trunk/docs/WritingAnLLVMPass.html Sat Jan 1 11:37:07 2011 @@ -273,7 +273,7 @@
            static char ID;
      -     Hello() : FunctionPass(&ID) {}
      +     Hello() : FunctionPass(ID) {}
       

      This declares pass identifier used by LLVM to identify pass. This allows LLVM to @@ -301,7 +301,7 @@ initialization value is not important.

      -  INITIALIZE_PASS(Hello, "hello", "Hello World Pass",
      +  static RegisterPass X("hello", "Hello World Pass",
                               false /* Only looks at CFG */,
                               false /* Analysis Pass */);
       }  // end of anonymous namespace
      @@ -328,7 +328,7 @@
         struct Hello : public FunctionPass {
           
           static char ID;
      -    Hello() : FunctionPass(&ID) {}
      +    Hello() : FunctionPass(ID) {}
       
           virtual bool runOnFunction(Function &F) {
             errs() << "Hello: " << F.getName() << "\n";
      @@ -337,7 +337,7 @@
         };
         
         char Hello::ID = 0;
      -  INITIALIZE_PASS(Hello, "Hello", "Hello World Pass", false, false);
      +  static RegisterPass X("hello", "Hello World Pass", false, false);
       }
       
       
      @@ -361,7 +361,7 @@

      Now that you have a brand new shiny shared object file, we can use the opt command to run an LLVM program through your pass. Because you -registered your pass with the INITIALIZE_PASS macro, you will be able to +registered your pass with RegisterPass, you will be able to use the opt tool to access it, once loaded.

      To test it, follow the example at the end of the -

      As we saw above, passes are registered with the INITIALIZE_PASS -macro. The first parameter is the name of the pass that is to be used on +

      As we saw above, passes are registered with the RegisterPass +template. The template parameter is the name of the pass that is to be used on the command line to specify that the pass should be added to a program (for -example, with opt or bugpoint). The second argument is the +example, with opt or bugpoint). The first argument is the name of the pass, which is to be used for the -help output of programs, as well as for debug output generated by the --debug-pass option.

      From clattner at apple.com Sat Jan 1 13:06:51 2011 From: clattner at apple.com (Chris Lattner) Date: Sat, 1 Jan 2011 11:06:51 -0800 Subject: [llvm-commits] [llvm] r122654 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp lib/Target/README.txt test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll In-Reply-To: <20110101161209.8EA9A2A6C12C@llvm.org> References: <20110101161209.8EA9A2A6C12C@llvm.org> Message-ID: <5560C4E4-34C1-41EF-A8B8-695312D2E332@apple.com> On Jan 1, 2011, at 8:12 AM, Duncan Sands wrote: > Author: baldrick > Date: Sat Jan 1 10:12:09 2011 > New Revision: 122654 > > URL: http://llvm.org/viewvc/llvm-project?rev=122654&view=rev > Log: > Fix a README item by having InstructionSimplify do a mild form of value > numbering, in which it considers (for example) "%a = add i32 %x, %y" and > "%b = add i32 %x, %y" to be equal because the operands are equal and the > result of the instructions only depends on the values of the operands. > This has almost no effect (it removes 4 instructions from gcc-as-one-file), > and perhaps slows down compilation: I measured a 0.4% slowdown on the large > gcc-as-one-file testcase, but it wasn't statistically significant. Duncan, please don't do this. InstSimplify should *not* do CSE, which is what the README entry is about. I should not have added the readme entry as I did, because the actual issue is lack of early CSE. I have another way to fix this, which I'll be tackling shortly. -Chris From rafael.espindola at gmail.com Sat Jan 1 13:05:35 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Sat, 01 Jan 2011 19:05:35 -0000 Subject: [llvm-commits] [llvm] r122658 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp test/MC/ELF/relocation.s Message-ID: <20110101190535.D0B182A6C12C@llvm.org> Author: rafael Date: Sat Jan 1 13:05:35 2011 New Revision: 122658 URL: http://llvm.org/viewvc/llvm-project?rev=122658&view=rev Log: Fix PR8878. Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp llvm/trunk/test/MC/ELF/relocation.s Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=122658&r1=122657&r2=122658&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sat Jan 1 13:05:35 2011 @@ -1610,6 +1610,7 @@ assert(Modifier == MCSymbolRefExpr::VK_None); Type = ELF::R_X86_64_PC64; break; + case X86::reloc_signed_4byte: case X86::reloc_riprel_4byte_movq_load: case FK_Data_4: // FIXME? case X86::reloc_riprel_4byte: Modified: llvm/trunk/test/MC/ELF/relocation.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/relocation.s?rev=122658&r1=122657&r2=122658&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/relocation.s (original) +++ llvm/trunk/test/MC/ELF/relocation.s Sat Jan 1 13:05:35 2011 @@ -16,6 +16,7 @@ leaq foo at DTPOFF(%rax), %rcx # R_X86_64_DTPOFF32 pushq $bar movq foo(%rip), %rdx + leaq foo-bar(%r14),%r14 // CHECK: # Section 0x00000001 @@ -105,3 +106,9 @@ // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0xfffffffc) + +// CHECK: # Relocation 0x0000000d +// CHECK-NEXT: (('r_offset', 0x0000005c) +// CHECK-NEXT: ('r_sym', 0x00000006) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000005c) From sabre at nondot.org Sat Jan 1 13:39:01 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 01 Jan 2011 19:39:01 -0000 Subject: [llvm-commits] [llvm] r122659 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110101193901.C288E2A6C12C@llvm.org> Author: lattner Date: Sat Jan 1 13:39:01 2011 New Revision: 122659 URL: http://llvm.org/viewvc/llvm-project?rev=122659&view=rev Log: implement the "no aliasing accesses in loop" safety check. This pass should be correct now. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/LoopIdiom/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122659&r1=122658&r2=122659&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sat Jan 1 13:39:01 2011 @@ -180,6 +180,9 @@ // know that every byte is touched in the loop. unsigned StoreSize = (unsigned)SizeInBits >> 3; const SCEVConstant *Stride = dyn_cast(Ev->getOperand(1)); + + // TODO: Could also handle negative stride here someday, that will require the + // validity check in mayLoopModRefLocation to be updated though. if (Stride == 0 || StoreSize != Stride->getValue()->getValue()) return false; @@ -196,22 +199,46 @@ return false; } +/// mayLoopModRefLocation - Return true if the specified loop might do a load or +/// store to the same location that the specified store could store to, which is +/// a loop-strided access. +static bool mayLoopModRefLocation(StoreInst *SI, Loop *L, AliasAnalysis &AA) { + // Get the location that may be stored across the loop. Since the access is + // strided positively through memory, we say that the modified location starts + // at the pointer and has infinite size. + // TODO: Could improve this for constant trip-count loops. + AliasAnalysis::Location StoreLoc = + AliasAnalysis::Location(SI->getPointerOperand()); + + for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; + ++BI) + for (BasicBlock::iterator I = (*BI)->begin(), E = (*BI)->end(); I != E; ++I) + if (AA.getModRefInfo(I, StoreLoc) != AliasAnalysis::NoModRef) + return true; + + return false; +} + /// processLoopStoreOfSplatValue - We see a strided store of a memsetable value. /// If we can transform this into a memset in the loop preheader, do so. bool LoopIdiomRecognize:: processLoopStoreOfSplatValue(StoreInst *SI, unsigned StoreSize, Value *SplatValue, const SCEVAddRecExpr *Ev, const SCEV *BECount) { + // Temporarily remove the store from the loop, to avoid the mod/ref query from + // seeing it. + Instruction *InstAfterStore = ++BasicBlock::iterator(SI); + SI->removeFromParent(); + // Okay, we have a strided store "p[i]" of a splattable value. We can turn // this into a memset in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read // or write to the aliased location. Check for an alias. + bool Unsafe=mayLoopModRefLocation(SI, CurLoop, getAnalysis()); + + SI->insertBefore(InstAfterStore); - // FIXME: Need to get a base pointer that is valid. - // if (LoopCanModRefLocation(SI->getPointerOperand()) - - - // FIXME: TODO safety check. + if (Unsafe) return false; // Okay, everything looks good, insert the memset. BasicBlock *Preheader = CurLoop->getLoopPreheader(); Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122659&r1=122658&r2=122659&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sat Jan 1 13:39:01 2011 @@ -42,3 +42,26 @@ ; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base1, i8 1, i64 %tmp, i32 4, i1 false) ; CHECK-NOT: store } + +; This is a case where there is an extra may-aliased store in the loop, we can't +; promote the memset. +define void @test3(i32* %Base, i64 %Size, i8 *%MayAlias) nounwind ssp { +entry: + br label %for.body + +for.body: ; preds = %entry, %for.body + %i.011 = phi i64 [ %inc, %for.body ], [ 0, %entry ] + %add.ptr.i = getelementptr i32* %Base, i64 %i.011 + store i32 16843009, i32* %add.ptr.i, align 4 + + store i8 42, i8* %MayAlias + %inc = add nsw i64 %i.011, 1 + %exitcond = icmp eq i64 %inc, %Size + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %entry + ret void +; CHECK: @test3 +; CHECK-NOT: memset +; CHECK: ret void +} From sabre at nondot.org Sat Jan 1 13:54:22 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 01 Jan 2011 19:54:22 -0000 Subject: [llvm-commits] [llvm] r122660 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110101195422.3EBE82A6C12C@llvm.org> Author: lattner Date: Sat Jan 1 13:54:22 2011 New Revision: 122660 URL: http://llvm.org/viewvc/llvm-project?rev=122660&view=rev Log: improve validity check to handle constant-trip-count loops more aggressively. In practice, this doesn't help anything though, see the todo. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/LoopIdiom/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122660&r1=122659&r2=122660&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sat Jan 1 13:54:22 2011 @@ -193,8 +193,7 @@ return processLoopStoreOfSplatValue(SI, StoreSize, SplatValue, Ev, BECount); // Handle the memcpy case here. - errs() << "Found strided store: " << *Ev << "\n"; - + // errs() << "Found strided store: " << *Ev << "\n"; return false; } @@ -202,13 +201,23 @@ /// mayLoopModRefLocation - Return true if the specified loop might do a load or /// store to the same location that the specified store could store to, which is /// a loop-strided access. -static bool mayLoopModRefLocation(StoreInst *SI, Loop *L, AliasAnalysis &AA) { +static bool mayLoopModRefLocation(StoreInst *SI, Loop *L, const SCEV *BECount, + unsigned StoreSize, AliasAnalysis &AA) { // Get the location that may be stored across the loop. Since the access is // strided positively through memory, we say that the modified location starts // at the pointer and has infinite size. - // TODO: Could improve this for constant trip-count loops. - AliasAnalysis::Location StoreLoc = - AliasAnalysis::Location(SI->getPointerOperand()); + uint64_t AccessSize = AliasAnalysis::UnknownSize; + + // If the loop iterates a fixed number of times, we can refine the access size + // to be exactly the size of the memset, which is (BECount+1)*StoreSize + if (const SCEVConstant *BECst = dyn_cast(BECount)) + AccessSize = (BECst->getValue()->getZExtValue()+1)*StoreSize; + + // TODO: For this to be really effective, we have to dive into the pointer + // operand in the store. Store to &A[i] of 100 will always return may alias + // with store of &A[100], we need to StoreLoc to be "A" with size of 100, + // which will then no-alias a store to &A[100]. + AliasAnalysis::Location StoreLoc(SI->getPointerOperand(), AccessSize); for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; ++BI) @@ -234,7 +243,8 @@ // this into a memset in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read // or write to the aliased location. Check for an alias. - bool Unsafe=mayLoopModRefLocation(SI, CurLoop, getAnalysis()); + bool Unsafe = mayLoopModRefLocation(SI, CurLoop, BECount, StoreSize, + getAnalysis()); SI->insertBefore(InstAfterStore); Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122660&r1=122659&r2=122660&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sat Jan 1 13:54:22 2011 @@ -1,4 +1,4 @@ -; RUN: opt -loop-idiom < %s -S | FileCheck %s +; RUN: opt -basicaa -loop-idiom < %s -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.0.0" @@ -65,3 +65,29 @@ ; CHECK-NOT: memset ; CHECK: ret void } + + +;; TODO: We should be able to promote this memset. Not yet though. +define void @test4(i8* %Base) nounwind ssp { +bb.nph: ; preds = %entry + %Base100 = getelementptr i8* %Base, i64 1000 + br label %for.body + +for.body: ; preds = %bb.nph, %for.body + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] + %I.0.014 = getelementptr i8* %Base, i64 %indvar + store i8 0, i8* %I.0.014, align 1 + + ;; Store beyond the range memset, should be safe to promote. + store i8 42, i8* %Base100 + + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, 100 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK-TODO: @test4 +; CHECK-TODO: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 100, i32 1, i1 false) +; CHECK-TODO-NOT: store +} From baldrick at free.fr Sat Jan 1 14:08:02 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 01 Jan 2011 20:08:02 -0000 Subject: [llvm-commits] [llvm] r122661 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp lib/Target/README.txt test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll Message-ID: <20110101200802.7F3F12A6C130@llvm.org> Author: baldrick Date: Sat Jan 1 14:08:02 2011 New Revision: 122661 URL: http://llvm.org/viewvc/llvm-project?rev=122661&view=rev Log: Revert commit 122654 at the request of Chris, who reckons that instsimplify is the wrong hammer for this nail, and is probably right. Removed: llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122661&r1=122660&r2=122661&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Sat Jan 1 14:08:02 2011 @@ -28,7 +28,7 @@ using namespace llvm; using namespace llvm::PatternMatch; -#define RecursionLimit 4 +#define RecursionLimit 3 STATISTIC(NumExpand, "Number of expansions"); STATISTIC(NumFactor , "Number of factorizations"); @@ -45,53 +45,6 @@ static Value *SimplifyXorInst(Value *, Value *, const TargetData *, const DominatorTree *, unsigned); -/// equal - Return true if the given values are known to be equal, false if they -/// are not equal or it is not clear whether they are equal or not. -static bool equal(Value *A, Value *B, unsigned MaxRecurse) { - // If the pointers are equal then the values are! - if (A == B) - return true; - // From this point on either recursion is used or the result is false, so bail - // out at once if we already hit the recursion limit. - if (!MaxRecurse--) - return false; - // If these are instructions, see if they compute the same value. - Instruction *AI = dyn_cast(A), *BI = dyn_cast(B); - if (!AI || !BI) - return false; - // If one of the instructions has extra flags attached then be conservative - // and say that the instructions differ. - if (!AI->hasSameSubclassOptionalData(BI)) - return false; - // For some reason alloca's are not considered to read or write memory, yet - // each one nonetheless manages to return a different value... - if (isa(AI)) - return false; - // Do not consider instructions to be equal if they may access memory. - if (AI->mayReadFromMemory() || AI->mayWriteToMemory()) - return false; - // If the instructions do not perform the same computation then bail out. - if (!BI->isSameOperationAs(AI)) - return false; - - // Check whether all operands are equal. If they are then the instructions - // have the same value. - bool AllOperandsEqual = true; - for (unsigned i = 0, e = AI->getNumOperands(); i != e; ++i) - if (!equal(AI->getOperand(i), BI->getOperand(i), MaxRecurse)) { - AllOperandsEqual = false; - break; - } - if (AllOperandsEqual) - return true; - - // If the instructions are commutative and their operands are equal when - // swapped then the instructions have the same value. - return AI->isCommutative() && - equal(AI->getOperand(0), BI->getOperand(1), MaxRecurse) && - equal(AI->getOperand(1), BI->getOperand(0), MaxRecurse); -} - /// ValueDominatesPHI - Does the given value dominate the specified phi node? static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) { Instruction *I = dyn_cast(V); @@ -135,9 +88,8 @@ if (Value *R = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) { // They do! Return "L op' R" if it simplifies or is already available. // If "L op' R" equals "A op' B" then "L op' R" is just the LHS. - if ((equal(L, A, MaxRecurse) && equal(R, B, MaxRecurse)) || - (Instruction::isCommutative(OpcodeToExpand) && - equal(L, B, MaxRecurse) && equal(R, A, MaxRecurse))) { + if ((L == A && R == B) || (Instruction::isCommutative(OpcodeToExpand) + && L == B && R == A)) { ++NumExpand; return LHS; } @@ -160,9 +112,8 @@ if (Value *R = SimplifyBinOp(Opcode, A, C, TD, DT, MaxRecurse)) { // They do! Return "L op' R" if it simplifies or is already available. // If "L op' R" equals "B op' C" then "L op' R" is just the RHS. - if ((equal(L, B, MaxRecurse) && equal(R, C, MaxRecurse)) || - (Instruction::isCommutative(OpcodeToExpand) && - equal(L, C, MaxRecurse) && equal(R, B, MaxRecurse))) { + if ((L == B && R == C) || (Instruction::isCommutative(OpcodeToExpand) + && L == C && R == B)) { ++NumExpand; return RHS; } @@ -204,23 +155,17 @@ // Use left distributivity, i.e. "X op' (Y op Z) = (X op' Y) op (X op' Z)". // Does the instruction have the form "(A op' B) op (A op' D)" or, in the // commutative case, "(A op' B) op (C op' A)"? - bool AEqualsC = equal(A, C, MaxRecurse); - if (AEqualsC || (Instruction::isCommutative(OpcodeToExtract) && - equal(A, D, MaxRecurse))) { - Value *DD = AEqualsC ? D : C; + if (A == C || (Instruction::isCommutative(OpcodeToExtract) && A == D)) { + Value *DD = A == C ? D : C; // Form "A op' (B op DD)" if it simplifies completely. // Does "B op DD" simplify? if (Value *V = SimplifyBinOp(Opcode, B, DD, TD, DT, MaxRecurse)) { // It does! Return "A op' V" if it simplifies or is already available. // If V equals B then "A op' V" is just the LHS. If V equals DD then // "A op' V" is just the RHS. - if (equal(V, B, MaxRecurse)) { + if (V == B || V == DD) { ++NumFactor; - return LHS; - } - if (equal(V, DD, MaxRecurse)) { - ++NumFactor; - return RHS; + return V == B ? LHS : RHS; } // Otherwise return "A op' V" if it simplifies. if (Value *W = SimplifyBinOp(OpcodeToExtract, A, V, TD, DT, MaxRecurse)) { @@ -233,23 +178,17 @@ // Use right distributivity, i.e. "(X op Y) op' Z = (X op' Z) op (Y op' Z)". // Does the instruction have the form "(A op' B) op (C op' B)" or, in the // commutative case, "(A op' B) op (B op' D)"? - bool BEqualsD = equal(B, D, MaxRecurse); - if (BEqualsD || (Instruction::isCommutative(OpcodeToExtract) && - equal(B, C, MaxRecurse))) { - Value *CC = BEqualsD ? C : D; + if (B == D || (Instruction::isCommutative(OpcodeToExtract) && B == C)) { + Value *CC = B == D ? C : D; // Form "(A op CC) op' B" if it simplifies completely.. // Does "A op CC" simplify? if (Value *V = SimplifyBinOp(Opcode, A, CC, TD, DT, MaxRecurse)) { // It does! Return "V op' B" if it simplifies or is already available. // If V equals A then "V op' B" is just the LHS. If V equals CC then // "V op' B" is just the RHS. - if (equal(V, A, MaxRecurse)) { + if (V == A || V == CC) { ++NumFactor; - return LHS; - } - if (equal(V, CC, MaxRecurse)) { - ++NumFactor; - return RHS; + return V == A ? LHS : RHS; } // Otherwise return "V op' B" if it simplifies. if (Value *W = SimplifyBinOp(OpcodeToExtract, V, B, TD, DT, MaxRecurse)) { @@ -288,7 +227,7 @@ if (Value *V = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) { // It does! Return "A op V" if it simplifies or is already available. // If V equals B then "A op V" is just the LHS. - if (equal(V, B, MaxRecurse)) return LHS; + if (V == B) return LHS; // Otherwise return "A op V" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, A, V, TD, DT, MaxRecurse)) { ++NumReassoc; @@ -307,7 +246,7 @@ if (Value *V = SimplifyBinOp(Opcode, A, B, TD, DT, MaxRecurse)) { // It does! Return "V op C" if it simplifies or is already available. // If V equals B then "V op C" is just the RHS. - if (equal(V, B, MaxRecurse)) return RHS; + if (V == B) return RHS; // Otherwise return "V op C" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, V, C, TD, DT, MaxRecurse)) { ++NumReassoc; @@ -330,7 +269,7 @@ if (Value *V = SimplifyBinOp(Opcode, C, A, TD, DT, MaxRecurse)) { // It does! Return "V op B" if it simplifies or is already available. // If V equals A then "V op B" is just the LHS. - if (equal(V, A, MaxRecurse)) return LHS; + if (V == A) return LHS; // Otherwise return "V op B" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, V, B, TD, DT, MaxRecurse)) { ++NumReassoc; @@ -349,7 +288,7 @@ if (Value *V = SimplifyBinOp(Opcode, C, A, TD, DT, MaxRecurse)) { // It does! Return "B op V" if it simplifies or is already available. // If V equals C then "B op V" is just the RHS. - if (equal(V, C, MaxRecurse)) return RHS; + if (V == C) return RHS; // Otherwise return "B op V" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, B, V, TD, DT, MaxRecurse)) { ++NumReassoc; @@ -392,12 +331,9 @@ FV = SimplifyBinOp(Opcode, LHS, SI->getFalseValue(), TD, DT, MaxRecurse); } - // If they both failed to simplify then return null. - if (!TV && !FV) - return 0; - // If they simplified to the same value, then return the common value. - if (TV && FV && equal(TV, FV, MaxRecurse)) + // If they both failed to simplify then return null. + if (TV == FV) return TV; // If one branch simplified to undef, return the other one. @@ -408,8 +344,7 @@ // If applying the operation did not change the true and false select values, // then the result of the binop is the select itself. - if (TV && equal(TV, SI->getTrueValue(), MaxRecurse) && - FV && equal(FV, SI->getFalseValue(), MaxRecurse)) + if (TV == SI->getTrueValue() && FV == SI->getFalseValue()) return SI; // If one branch simplified and the other did not, and the simplified @@ -426,12 +361,12 @@ Value *UnsimplifiedBranch = FV ? SI->getTrueValue() : SI->getFalseValue(); Value *UnsimplifiedLHS = SI == LHS ? UnsimplifiedBranch : LHS; Value *UnsimplifiedRHS = SI == LHS ? RHS : UnsimplifiedBranch; - if (equal(Simplified->getOperand(0), UnsimplifiedLHS, MaxRecurse) && - equal(Simplified->getOperand(1), UnsimplifiedRHS, MaxRecurse)) + if (Simplified->getOperand(0) == UnsimplifiedLHS && + Simplified->getOperand(1) == UnsimplifiedRHS) return Simplified; if (Simplified->isCommutative() && - equal(Simplified->getOperand(1), UnsimplifiedLHS, MaxRecurse) && - equal(Simplified->getOperand(0), UnsimplifiedRHS, MaxRecurse)) + Simplified->getOperand(1) == UnsimplifiedLHS && + Simplified->getOperand(0) == UnsimplifiedRHS) return Simplified; } } @@ -468,7 +403,7 @@ MaxRecurse)) // It does! If they simplified to the same value, then use it as the // result of the original comparison. - if (equal(TCmp, FCmp, MaxRecurse)) + if (TCmp == FCmp) return TCmp; return 0; } @@ -584,14 +519,14 @@ // X + (Y - X) -> Y // (Y - X) + X -> Y // Eg: X + -X -> 0 - Value *X = 0, *Y = 0; - if ((match(Op1, m_Sub(m_Value(Y), m_Value(X))) && equal(X, Op0, MaxRecurse))|| - (match(Op0, m_Sub(m_Value(Y), m_Value(X))) && equal(X, Op1, MaxRecurse))) + Value *Y = 0; + if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) || + match(Op0, m_Sub(m_Value(Y), m_Specific(Op1)))) return Y; // X + ~X -> -1 since ~X = -X-1 - if ((match(Op0, m_Not(m_Value(X))) && equal(X, Op1, MaxRecurse)) || - (match(Op1, m_Not(m_Value(X))) && equal(X, Op0, MaxRecurse))) + if (match(Op0, m_Not(m_Specific(Op1))) || + match(Op1, m_Not(m_Specific(Op0)))) return Constant::getAllOnesValue(Op0->getType()); /// i1 add -> xor. @@ -648,14 +583,14 @@ return Op0; // X - X -> 0 - if (equal(Op0, Op1, MaxRecurse)) + if (Op0 == Op1) return Constant::getNullValue(Op0->getType()); // (X + Y) - Y -> X // (Y + X) - Y -> X - Value *X = 0, *Y = 0; - if ((match(Op0, m_Add(m_Value(X), m_Value(Y))) && equal(Y, Op1, MaxRecurse))|| - (match(Op0, m_Add(m_Value(Y), m_Value(X))) && equal(Y, Op1, MaxRecurse))) + Value *X = 0; + if (match(Op0, m_Add(m_Value(X), m_Specific(Op1))) || + match(Op0, m_Add(m_Specific(Op1), m_Value(X)))) return X; /// i1 sub -> xor. @@ -769,7 +704,7 @@ return Constant::getNullValue(Op0->getType()); // X & X = X - if (equal(Op0, Op1, MaxRecurse)) + if (Op0 == Op1) return Op0; // X & 0 = 0 @@ -782,18 +717,18 @@ // A & ~A = ~A & A = 0 Value *A = 0, *B = 0; - if ((match(Op0, m_Not(m_Value(A))) && equal(A, Op1, MaxRecurse)) || - (match(Op1, m_Not(m_Value(A))) && equal(A, Op0, MaxRecurse))) + if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || + (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getNullValue(Op0->getType()); // (A | ?) & A = A if (match(Op0, m_Or(m_Value(A), m_Value(B))) && - (equal(A, Op1, MaxRecurse) || equal(B, Op1, MaxRecurse))) + (A == Op1 || B == Op1)) return Op1; // A & (A | ?) = A if (match(Op1, m_Or(m_Value(A), m_Value(B))) && - (equal(A, Op0, MaxRecurse) || equal(B, Op0, MaxRecurse))) + (A == Op0 || B == Op0)) return Op0; // Try some generic simplifications for associative operations. @@ -858,7 +793,7 @@ return Constant::getAllOnesValue(Op0->getType()); // X | X = X - if (equal(Op0, Op1, MaxRecurse)) + if (Op0 == Op1) return Op0; // X | 0 = X @@ -871,18 +806,18 @@ // A | ~A = ~A | A = -1 Value *A = 0, *B = 0; - if ((match(Op0, m_Not(m_Value(A))) && equal(A, Op1, MaxRecurse)) || - (match(Op1, m_Not(m_Value(A))) && equal(A, Op0, MaxRecurse))) + if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || + (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getAllOnesValue(Op0->getType()); // (A & ?) | A = A if (match(Op0, m_And(m_Value(A), m_Value(B))) && - (equal(A, Op1, MaxRecurse) || equal(B, Op1, MaxRecurse))) + (A == Op1 || B == Op1)) return Op1; // A | (A & ?) = A if (match(Op1, m_And(m_Value(A), m_Value(B))) && - (equal(A, Op0, MaxRecurse) || equal(B, Op0, MaxRecurse))) + (A == Op0 || B == Op0)) return Op0; // Try some generic simplifications for associative operations. @@ -946,13 +881,13 @@ return Op0; // A ^ A = 0 - if (equal(Op0, Op1, MaxRecurse)) + if (Op0 == Op1) return Constant::getNullValue(Op0->getType()); // A ^ ~A = ~A ^ A = -1 Value *A = 0; - if ((match(Op0, m_Not(m_Value(A))) && equal(A, Op1, MaxRecurse)) || - (match(Op1, m_Not(m_Value(A))) && equal(A, Op0, MaxRecurse))) + if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || + (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getAllOnesValue(Op0->getType()); // Try some generic simplifications for associative operations. @@ -1009,7 +944,7 @@ // icmp X, X -> true/false // X icmp undef -> true/false. For example, icmp ugt %X, undef -> false // because X could be 0. - if (isa(RHS) || equal(LHS, RHS, MaxRecurse)) + if (LHS == RHS || isa(RHS)) return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred)); // icmp , - Global/Stack value @@ -1093,7 +1028,7 @@ return UndefValue::get(GetCompareTy(LHS)); // fcmp x,x -> true/false. Not all compares are foldable. - if (equal(LHS, RHS, MaxRecurse)) { + if (LHS == RHS) { if (CmpInst::isTrueWhenEqual(Pred)) return ConstantInt::get(GetCompareTy(LHS), 1); if (CmpInst::isFalseWhenEqual(Pred)) @@ -1163,16 +1098,15 @@ /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold /// the result. If not, this returns null. -static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, - const TargetData *TD, const DominatorTree *, - unsigned MaxRecurse) { +Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, + const TargetData *TD, const DominatorTree *) { // select true, X, Y -> X // select false, X, Y -> Y if (ConstantInt *CB = dyn_cast(CondVal)) return CB->getZExtValue() ? TrueVal : FalseVal; // select C, X, X -> X - if (equal(TrueVal, FalseVal, MaxRecurse)) + if (TrueVal == FalseVal) return TrueVal; if (isa(TrueVal)) // select C, undef, X -> X @@ -1188,12 +1122,6 @@ return 0; } -Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, - const TargetData *TD, const DominatorTree *DT) { - return ::SimplifySelectInst(CondVal, TrueVal, FalseVal, TD, DT, - RecursionLimit); -} - /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps, Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=122661&r1=122660&r2=122661&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Jan 1 14:08:02 2011 @@ -2065,3 +2065,14 @@ } //===---------------------------------------------------------------------===// + +This compare could fold to false: + +define i1 @g(i32 a) nounwind readnone { + %add = shl i32 %a, 1 + %mul = shl i32 %a, 1 + %cmp = icmp ugt i32 %add, %mul + ret i1 %cmp +} + +//===---------------------------------------------------------------------===// Removed: llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll?rev=122660&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll (original) +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll (removed) @@ -1,9 +0,0 @@ -; RUN: opt < %s -instsimplify -S | FileCheck %s -define i1 @g(i32 %a) nounwind readnone { -; CHECK: @g - %add = shl i32 %a, 1 - %mul = shl i32 %a, 1 - %cmp = icmp ugt i32 %add, %mul - ret i1 %cmp -; CHECK: ret i1 false -} From baldrick at free.fr Sat Jan 1 14:11:39 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 01 Jan 2011 21:11:39 +0100 Subject: [llvm-commits] [llvm] r122654 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp lib/Target/README.txt test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll In-Reply-To: <5560C4E4-34C1-41EF-A8B8-695312D2E332@apple.com> References: <20110101161209.8EA9A2A6C12C@llvm.org> <5560C4E4-34C1-41EF-A8B8-695312D2E332@apple.com> Message-ID: <4D1F8A7B.7000401@free.fr> Hi Chris, >> Fix a README item by having InstructionSimplify do a mild form of value >> numbering, in which it considers (for example) "%a = add i32 %x, %y" and >> "%b = add i32 %x, %y" to be equal because the operands are equal and the >> result of the instructions only depends on the values of the operands. >> This has almost no effect (it removes 4 instructions from gcc-as-one-file), >> and perhaps slows down compilation: I measured a 0.4% slowdown on the large >> gcc-as-one-file testcase, but it wasn't statistically significant. > > Duncan, please don't do this. InstSimplify should *not* do CSE, which is what the README entry is about. I should not have added the readme entry as I did, because the actual issue is lack of early CSE. I have another way to fix this, which I'll be tackling shortly. no problem, reverted in commit 122661. Ciao, Duncan. From sabre at nondot.org Sat Jan 1 14:12:04 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 01 Jan 2011 20:12:04 -0000 Subject: [llvm-commits] [llvm] r122662 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110101201204.6D4862A6C130@llvm.org> Author: lattner Date: Sat Jan 1 14:12:04 2011 New Revision: 122662 URL: http://llvm.org/viewvc/llvm-project?rev=122662&view=rev Log: add a validity check that was missed, fixing a crash on the new testcase. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/LoopIdiom/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122662&r1=122661&r2=122662&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sat Jan 1 14:12:04 2011 @@ -234,6 +234,11 @@ processLoopStoreOfSplatValue(StoreInst *SI, unsigned StoreSize, Value *SplatValue, const SCEVAddRecExpr *Ev, const SCEV *BECount) { + // Verify that the stored value is loop invariant. If not, we can't promote + // the memset. + if (!CurLoop->isLoopInvariant(SplatValue)) + return false; + // Temporarily remove the store from the loop, to avoid the mod/ref query from // seeing it. Instruction *InstAfterStore = ++BasicBlock::iterator(SI); Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122662&r1=122661&r2=122662&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sat Jan 1 14:12:04 2011 @@ -91,3 +91,26 @@ ; CHECK-TODO: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 100, i32 1, i1 false) ; CHECK-TODO-NOT: store } + +; This can't be promoted: the memset is a store of a loop variant value. +define void @test5(i8* %Base, i64 %Size) nounwind ssp { +bb.nph: ; preds = %entry + br label %for.body + +for.body: ; preds = %bb.nph, %for.body + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] + %I.0.014 = getelementptr i8* %Base, i64 %indvar + + %V = trunc i64 %indvar to i8 + store i8 %V, i8* %I.0.014, align 1 + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, %Size + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK: @test5 +; CHECK-NOT: memset +; CHECK: ret void +} + From clattner at apple.com Sat Jan 1 14:32:51 2011 From: clattner at apple.com (Chris Lattner) Date: Sat, 1 Jan 2011 12:32:51 -0800 Subject: [llvm-commits] [llvm] r122654 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp lib/Target/README.txt test/Transforms/InstSimplify/2010-12-31-ValueNumber.ll In-Reply-To: <4D1F8A7B.7000401@free.fr> References: <20110101161209.8EA9A2A6C12C@llvm.org> <5560C4E4-34C1-41EF-A8B8-695312D2E332@apple.com> <4D1F8A7B.7000401@free.fr> Message-ID: On Jan 1, 2011, at 12:11 PM, Duncan Sands wrote: > Hi Chris, > >>> Fix a README item by having InstructionSimplify do a mild form of value >>> numbering, in which it considers (for example) "%a = add i32 %x, %y" and >>> "%b = add i32 %x, %y" to be equal because the operands are equal and the >>> result of the instructions only depends on the values of the operands. >>> This has almost no effect (it removes 4 instructions from gcc-as-one-file), >>> and perhaps slows down compilation: I measured a 0.4% slowdown on the large >>> gcc-as-one-file testcase, but it wasn't statistically significant. >> >> Duncan, please don't do this. InstSimplify should *not* do CSE, which is what the README entry is about. I should not have added the readme entry as I did, because the actual issue is lack of early CSE. I have another way to fix this, which I'll be tackling shortly. > > no problem, reverted in commit 122661. Thanks Duncan!! -Chris From asl at math.spbu.ru Sat Jan 1 14:38:38 2011 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 01 Jan 2011 20:38:38 -0000 Subject: [llvm-commits] [llvm] r122663 - in /llvm/trunk/lib/Target/ARM: ARMAsmPrinter.cpp ARMAsmPrinter.h ARMISelDAGToDAG.cpp ARMInstrInfo.td Message-ID: <20110101203838.B82AD2A6C12E@llvm.org> Author: asl Date: Sat Jan 1 14:38:38 2011 New Revision: 122663 URL: http://llvm.org/viewvc/llvm-project?rev=122663&view=rev Log: Model operand restrictions of mul-like instructions on ARMv5 via earlyclobber stuff. This should fix PRs 2313 and 8157. Unfortunately, no testcase, since it'd be dependent on register assignments. Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=122663&r1=122662&r2=122663&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Sat Jan 1 14:38:38 2011 @@ -725,6 +725,16 @@ Inst.addOperand(MCOperand::CreateReg(ccreg)); } +void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI, + unsigned Opcode) { + MCInst TmpInst; + + // Emit the instruction as usual, just patch the opcode. + LowerARMMachineInstrToMCInst(MI, TmpInst, *this); + TmpInst.setOpcode(Opcode); + OutStreamer.EmitInstruction(TmpInst); +} + void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { switch (MI->getOpcode()) { default: break; @@ -1376,6 +1386,30 @@ } return; } + // These are the pseudos created to comply with stricter operand restrictions + // on ARMv5. Lower them now to "normal" instructions, since all the + // restrictions are already satisfied. + case ARM::MULv5: + EmitPatchedInstruction(MI, ARM::MUL); + return; + case ARM::MLAv5: + EmitPatchedInstruction(MI, ARM::MLA); + return; + case ARM::SMULLv5: + EmitPatchedInstruction(MI, ARM::SMULL); + return; + case ARM::UMULLv5: + EmitPatchedInstruction(MI, ARM::UMULL); + return; + case ARM::SMLALv5: + EmitPatchedInstruction(MI, ARM::SMLAL); + return; + case ARM::UMLALv5: + EmitPatchedInstruction(MI, ARM::UMLAL); + return; + case ARM::UMAALv5: + EmitPatchedInstruction(MI, ARM::UMAAL); + return; } MCInst TmpInst; Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h?rev=122663&r1=122662&r2=122663&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h Sat Jan 1 14:38:38 2011 @@ -79,6 +79,9 @@ // Helper for ELF .o only void emitARMAttributeSection(); + // Generic helper used to emit e.g. ARMv5 mul pseudos + void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc); + public: void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=122663&r1=122662&r2=122663&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Sat Jan 1 14:38:38 2011 @@ -2322,7 +2322,9 @@ SDValue Ops[] = { N->getOperand(0), N->getOperand(1), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), CurDAG->getRegister(0, MVT::i32) }; - return CurDAG->getMachineNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5); + return CurDAG->getMachineNode(Subtarget->hasV6Ops() ? + ARM::UMULL : ARM::UMULLv5, + dl, MVT::i32, MVT::i32, Ops, 5); } } case ISD::SMUL_LOHI: { @@ -2336,7 +2338,9 @@ SDValue Ops[] = { N->getOperand(0), N->getOperand(1), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), CurDAG->getRegister(0, MVT::i32) }; - return CurDAG->getMachineNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5); + return CurDAG->getMachineNode(Subtarget->hasV6Ops() ? + ARM::SMULL : ARM::SMULLv5, + dl, MVT::i32, MVT::i32, Ops, 5); } } case ISD::LOAD: { Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=122663&r1=122662&r2=122663&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Sat Jan 1 14:38:38 2011 @@ -149,6 +149,7 @@ def HasV5T : Predicate<"Subtarget->hasV5TOps()">; def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate; def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate; +def NoV6 : Predicate<"!Subtarget->hasV6Ops()">; def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate; def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate; @@ -2504,14 +2505,31 @@ let Inst{3-0} = Rn; } -let isCommutable = 1 in +let isCommutable = 1 in { +let Constraints = "@earlyclobber $Rd" in +def MULv5: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + IIC_iMUL32, [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>, + Requires<[IsARM, NoV6]>; + def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", - [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>; + [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>, + Requires<[IsARM, HasV6]>; +} +let Constraints = "@earlyclobber $Rd" in +def MLAv5: PseudoInst<(outs GPR:$Rd), + (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s), + IIC_iMAC32, [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), + GPR:$Ra))]>, + Requires<[IsARM, NoV6]> { + bits<4> Ra; + let Inst{15-12} = Ra; +} def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra", - [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> { + [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, + Requires<[IsARM, HasV6]> { bits<4> Ra; let Inst{15-12} = Ra; } @@ -2534,23 +2552,54 @@ let neverHasSideEffects = 1 in { let isCommutable = 1 in { +let Constraints = "@earlyclobber $RdLo, at earlyclobber $RdHi" in { +def SMULLv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi), + (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + IIC_iMUL64, []>, + Requires<[IsARM, NoV6]>; + +def UMULLv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi), + (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + IIC_iMUL64, []>, + Requires<[IsARM, NoV6]>; +} + def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi), (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, - "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>; + "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>, + Requires<[IsARM, HasV6]>; def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi), (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, - "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>; + "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>, + Requires<[IsARM, HasV6]>; } // Multiply + accumulate +let Constraints = "@earlyclobber $RdLo, at earlyclobber $RdHi" in { +def SMLALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi), + (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + IIC_iMAC64, []>, + Requires<[IsARM, NoV6]>; +def UMLALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi), + (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + IIC_iMAC64, []>, + Requires<[IsARM, NoV6]>; +def UMAALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi), + (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + IIC_iMAC64, []>, + Requires<[IsARM, NoV6]>; + +} + def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi), (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, - "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>; - + "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, + Requires<[IsARM, HasV6]>; def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi), (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, - "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>; + "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, + Requires<[IsARM, HasV6]>; def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, From sabre at nondot.org Sat Jan 1 14:39:18 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 01 Jan 2011 20:39:18 -0000 Subject: [llvm-commits] [llvm] r122664 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <20110101203918.64FF82A6C130@llvm.org> Author: lattner Date: Sat Jan 1 14:39:18 2011 New Revision: 122664 URL: http://llvm.org/viewvc/llvm-project?rev=122664&view=rev Log: turn on memset idiom recognition by default. Though there are still lots of limitations, this kicks in dozens of times in the 4 specfp2000 benchmarks, and hundreds of times in the int part. It also kicks in hundreds of times in multisource. This kicks in right before loop deletion, which has the pleasant effect of deleting loops that *just* do a memset. Modified: llvm/trunk/include/llvm/Support/StandardPasses.h Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122664&r1=122663&r2=122664&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Sat Jan 1 14:39:18 2011 @@ -145,6 +145,7 @@ PM->add(createLoopUnswitchPass(OptimizeSize || OptimizationLevel < 3)); PM->add(createInstructionCombiningPass()); PM->add(createIndVarSimplifyPass()); // Canonicalize indvars + PM->add(createLoopIdiomPass()); // Recognize idioms like memset. PM->add(createLoopDeletionPass()); // Delete dead loops if (UnrollLoops) PM->add(createLoopUnrollPass()); // Unroll small loops From asl at math.spbu.ru Sat Jan 1 14:57:26 2011 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 01 Jan 2011 20:57:26 -0000 Subject: [llvm-commits] [llvm] r122666 - /llvm/trunk/test/CodeGen/ARM/str_pre-2.ll Message-ID: <20110101205726.986E52A6C12D@llvm.org> Author: asl Date: Sat Jan 1 14:57:26 2011 New Revision: 122666 URL: http://llvm.org/viewvc/llvm-project?rev=122666&view=rev Log: Update the test Modified: llvm/trunk/test/CodeGen/ARM/str_pre-2.ll Modified: llvm/trunk/test/CodeGen/ARM/str_pre-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/str_pre-2.ll?rev=122666&r1=122665&r2=122666&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/str_pre-2.ll (original) +++ llvm/trunk/test/CodeGen/ARM/str_pre-2.ll Sat Jan 1 14:57:26 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=arm-linux-gnu | FileCheck %s +; RUN: llc < %s -mtriple=armv6-linux-gnu | FileCheck %s @b = external global i64* From rafael.espindola at gmail.com Sat Jan 1 14:58:46 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Sat, 01 Jan 2011 20:58:46 -0000 Subject: [llvm-commits] [llvm] r122667 - in /llvm/trunk: lib/Target/X86/X86AsmPrinter.cpp test/CodeGen/X86/inline-asm-h.ll Message-ID: <20110101205847.079F12A6C12D@llvm.org> Author: rafael Date: Sat Jan 1 14:58:46 2011 New Revision: 122667 URL: http://llvm.org/viewvc/llvm-project?rev=122667&view=rev Log: Add support for the 'H' modifier. Added: llvm/trunk/test/CodeGen/X86/inline-asm-h.ll Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=122667&r1=122666&r2=122667&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Sat Jan 1 14:58:46 2011 @@ -302,6 +302,9 @@ printSymbolOperand(MI->getOperand(Op+3), O); } + if (Modifier && strcmp(Modifier, "H") == 0) + O << "+8"; + if (HasParenPart) { assert(IndexReg.getReg() != X86::ESP && "X86 doesn't allow scaling by ESP"); @@ -458,6 +461,9 @@ case 'q': // Print SImode register // These only apply to registers, ignore on mem. break; + case 'H': + printMemReference(MI, OpNo, O, "H"); + return false; case 'P': // Don't print @PLT, but do print as memory. printMemReference(MI, OpNo, O, "no-rip"); return false; Added: llvm/trunk/test/CodeGen/X86/inline-asm-h.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inline-asm-h.ll?rev=122667&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/inline-asm-h.ll (added) +++ llvm/trunk/test/CodeGen/X86/inline-asm-h.ll Sat Jan 1 14:58:46 2011 @@ -0,0 +1,12 @@ +; RUN: llc -march=x86-64 < %s | FileCheck %s + + at foobar = common global i32 0, align 4 + +define void @zed() nounwind { +entry: + call void asm "movq %mm2,${0:H}", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* @foobar) nounwind + ret void +} + +; CHECK: zed +; CHECK: movq %mm2,foobar+8(%rip) From benny.kra at googlemail.com Sat Jan 1 15:53:18 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sat, 01 Jan 2011 21:53:18 -0000 Subject: [llvm-commits] [llvm] r122671 - in /llvm/trunk: test/MC/MachO/Darwin/ tools/llvmc/example/ tools/llvmc/plugins/ unittests/System/ utils/lit/ExampleTests/ utils/unittest/googletest/src/ Message-ID: <20110101215318.744E62A6C12C@llvm.org> Author: d0k Date: Sat Jan 1 15:53:18 2011 New Revision: 122671 URL: http://llvm.org/viewvc/llvm-project?rev=122671&view=rev Log: Remove empty directories left behind by git-svn users. Removed: llvm/trunk/test/MC/MachO/Darwin/ llvm/trunk/tools/llvmc/example/ llvm/trunk/tools/llvmc/plugins/ llvm/trunk/unittests/System/ llvm/trunk/utils/lit/ExampleTests/ llvm/trunk/utils/unittest/googletest/src/ From rafael.espindola at gmail.com Sat Jan 1 15:58:42 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Sat, 01 Jan 2011 21:58:42 -0000 Subject: [llvm-commits] [llvm] r122672 - /llvm/trunk/test/CodeGen/X86/inline-asm-h.ll Message-ID: <20110101215842.2857E2A6C12C@llvm.org> Author: rafael Date: Sat Jan 1 15:58:41 2011 New Revision: 122672 URL: http://llvm.org/viewvc/llvm-project?rev=122672&view=rev Log: Fix darwin bots. Modified: llvm/trunk/test/CodeGen/X86/inline-asm-h.ll Modified: llvm/trunk/test/CodeGen/X86/inline-asm-h.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inline-asm-h.ll?rev=122672&r1=122671&r2=122672&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/inline-asm-h.ll (original) +++ llvm/trunk/test/CodeGen/X86/inline-asm-h.ll Sat Jan 1 15:58:41 2011 @@ -1,4 +1,4 @@ -; RUN: llc -march=x86-64 < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s | FileCheck %s @foobar = common global i32 0, align 4 From sabre at nondot.org Sat Jan 1 16:09:55 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 01 Jan 2011 22:09:55 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r122673 - /llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Message-ID: <20110101220955.938E22A6C12C@llvm.org> Author: lattner Date: Sat Jan 1 16:09:55 2011 New Revision: 122673 URL: http://llvm.org/viewvc/llvm-project?rev=122673&view=rev Log: idiom recognition needs to be linked in. Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp?rev=122673&r1=122672&r2=122673&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Sat Jan 1 16:09:55 2011 @@ -69,6 +69,7 @@ llvm::createLoopUnrollPass(); llvm::createReassociatePass(); llvm::createLoopUnswitchPass(); + llvm::createLoopIdiomPass(); llvm::createAggressiveDCEPass(); llvm::createConstantMergePass(); llvm::createIndVarSimplifyPass(); From sabre at nondot.org Sat Jan 1 16:31:46 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 01 Jan 2011 22:31:46 -0000 Subject: [llvm-commits] [llvm] r122674 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/crash.ll Message-ID: <20110101223146.B5E422A6C12C@llvm.org> Author: lattner Date: Sat Jan 1 16:31:46 2011 New Revision: 122674 URL: http://llvm.org/viewvc/llvm-project?rev=122674&view=rev Log: fix a globalopt crash on two Adobe-C++ testcases that the recent loop idiom pass exposed. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/test/Transforms/GlobalOpt/crash.ll Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=122674&r1=122673&r2=122674&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sat Jan 1 16:31:46 2011 @@ -167,6 +167,11 @@ const User *U = *UI; if (const ConstantExpr *CE = dyn_cast(U)) { GS.HasNonInstructionUser = true; + + // If the result of the constantexpr isn't pointer type, then we won't + // know to expect it in various places. Just reject early. + if (!isa(CE->getType())) return true; + if (AnalyzeGlobal(CE, GS, PHIUsers)) return true; } else if (const Instruction *I = dyn_cast(U)) { if (!GS.HasMultipleAccessingFunctions) { Modified: llvm/trunk/test/Transforms/GlobalOpt/crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/crash.ll?rev=122674&r1=122673&r2=122674&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/crash.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/crash.ll Sat Jan 1 16:31:46 2011 @@ -55,3 +55,12 @@ ret void } + + + + at data8 = internal global [8000 x i8] zeroinitializer, align 16 +define void @memset_with_strange_user() ssp { + call void @llvm.memset.p0i8.i64(i8* getelementptr inbounds ([8000 x i8]* @data8, i64 0, i64 0), i8 undef, i64 ptrtoint (i8* getelementptr ([8000 x i8]* @data8, i64 1, i64 sub (i64 0, i64 ptrtoint ([8000 x i8]* @data8 to i64))) to i64), i32 16, i1 false) + ret void +} +declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind From sabre at nondot.org Sat Jan 1 16:52:11 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 01 Jan 2011 22:52:11 -0000 Subject: [llvm-commits] [llvm] r122675 - /llvm/trunk/lib/Target/README.txt Message-ID: <20110101225211.76D922A6C12C@llvm.org> Author: lattner Date: Sat Jan 1 16:52:11 2011 New Revision: 122675 URL: http://llvm.org/viewvc/llvm-project?rev=122675&view=rev Log: various updates. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=122675&r1=122674&r2=122675&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Jan 1 16:52:11 2011 @@ -383,7 +383,8 @@ } This is a form of idiom recognition for loops, the same thing that could be -useful for recognizing memset/memcpy. +useful for recognizing memset/memcpy. This sort of thing should be added to the +loop idiom pass. //===---------------------------------------------------------------------===// @@ -701,38 +702,31 @@ foo(input); } -We currently compile this into a memcpy from a global array since the -initializer is fairly large and not memset'able. This is good, but the memcpy -gets lowered to load/stores in the code generator. This is also ok, except -that the codegen lowering for memcpy doesn't handle the case when the source -is a constant global. This gives us atrocious code like this: +Clang compiles this into: - call "L1$pb" -"L1$pb": - popl %eax - movl _C.0.1444-"L1$pb"+32(%eax), %ecx - movl %ecx, 40(%esp) - movl _C.0.1444-"L1$pb"+20(%eax), %ecx - movl %ecx, 28(%esp) - movl _C.0.1444-"L1$pb"+36(%eax), %ecx - movl %ecx, 44(%esp) - movl _C.0.1444-"L1$pb"+44(%eax), %ecx - movl %ecx, 52(%esp) - movl _C.0.1444-"L1$pb"+40(%eax), %ecx - movl %ecx, 48(%esp) - movl _C.0.1444-"L1$pb"+12(%eax), %ecx - movl %ecx, 20(%esp) - movl _C.0.1444-"L1$pb"+4(%eax), %ecx -... + call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 16, i1 false) + %0 = getelementptr [8 x i64]* %input, i64 0, i64 0 + store i64 1, i64* %0, align 16 + %1 = getelementptr [8 x i64]* %input, i64 0, i64 2 + store i64 1, i64* %1, align 16 + %2 = getelementptr [8 x i64]* %input, i64 0, i64 4 + store i64 1, i64* %2, align 16 + %3 = getelementptr [8 x i64]* %input, i64 0, i64 6 + store i64 1, i64* %3, align 16 + +Which gets codegen'd into: + + pxor %xmm0, %xmm0 + movaps %xmm0, -16(%rbp) + movaps %xmm0, -32(%rbp) + movaps %xmm0, -48(%rbp) + movaps %xmm0, -64(%rbp) + movq $1, -64(%rbp) + movq $1, -48(%rbp) + movq $1, -32(%rbp) + movq $1, -16(%rbp) -instead of: - movl $1, 16(%esp) - movl $0, 20(%esp) - movl $1, 24(%esp) - movl $0, 28(%esp) - movl $1, 32(%esp) - movl $0, 36(%esp) - ... +It would be better to have 4 movq's of 0 instead of the movaps's. //===---------------------------------------------------------------------===// @@ -1718,6 +1712,10 @@ return **p; } +This can be seen at: +$ clang t.c -S -o - -mkernel -O0 -emit-llvm | opt -functionattrs -S + + //===---------------------------------------------------------------------===// Missed instcombine transformation: From sabre at nondot.org Sat Jan 1 16:57:32 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 01 Jan 2011 22:57:32 -0000 Subject: [llvm-commits] [llvm] r122676 - /llvm/trunk/lib/Target/README.txt Message-ID: <20110101225732.2807C2A6C12C@llvm.org> Author: lattner Date: Sat Jan 1 16:57:31 2011 New Revision: 122676 URL: http://llvm.org/viewvc/llvm-project?rev=122676&view=rev Log: a missed __builtin_object_size case. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=122676&r1=122675&r2=122676&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Jan 1 16:57:31 2011 @@ -2074,3 +2074,20 @@ } //===---------------------------------------------------------------------===// + +This code can be seen in viterbi: + + %64 = call noalias i8* @malloc(i64 %62) nounwind +... + %67 = call i64 @llvm.objectsize.i64(i8* %64, i1 false) nounwind + %68 = call i8* @__memset_chk(i8* %64, i32 0, i64 %62, i64 %67) nounwind + +llvm.objectsize.i64 should be taught about malloc/calloc, allowing it to +fold to %62. This is a security win (overflows of malloc will get caught) +and also a performance win by exposing more memsets to the optimizer. + +This occurs several times in viterbi. + +//===---------------------------------------------------------------------===// + + From fvbommel at gmail.com Sat Jan 1 18:54:45 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 2 Jan 2011 01:54:45 +0100 Subject: [llvm-commits] [llvm] r122659 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: <20110101193901.C288E2A6C12C@llvm.org> References: <20110101193901.C288E2A6C12C@llvm.org> Message-ID: On Sat, Jan 1, 2011 at 8:39 PM, Chris Lattner wrote: > +/// mayLoopModRefLocation - Return true if the specified loop might do a load or > +/// store to the same location that the specified store could store to, which is > +/// a loop-strided access. > +static bool mayLoopModRefLocation(StoreInst *SI, Loop *L, AliasAnalysis &AA) { > + ?// Get the location that may be stored across the loop. ?Since the access is > + ?// strided positively through memory, we say that the modified location starts > + ?// at the pointer and has infinite size. > + ?// TODO: Could improve this for constant trip-count loops. > + ?AliasAnalysis::Location StoreLoc = > + ? ?AliasAnalysis::Location(SI->getPointerOperand()); > + > + ?for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; > + ? ? ? ++BI) > + ? ?for (BasicBlock::iterator I = (*BI)->begin(), E = (*BI)->end(); I != E; ++I) > + ? ? ?if (AA.getModRefInfo(I, StoreLoc) != AliasAnalysis::NoModRef) > + ? ? ? ?return true; Wouldn't it be cleaner to add an 'I != SI &&' to the condition here instead of temporarily removing SI from the block in before calling this? (The name of the function would probably have to be changed, but I think it's currently a bit confusing anyway: the comment implies SI is in the loop but the function checks whether any instruction in the loop modrefs the pointer operand, which would *normally* trivially be true...) Of course, checking that extra condition for every instruction in the loop is probably less efficient, which I'm guessing is the reason you did it this way? At the very least, it'd be nice to update the comment so it mentions the store should be temporarily removed before calling this. > + > + ?return false; > +} > + > ?/// processLoopStoreOfSplatValue - We see a strided store of a memsetable value. > ?/// If we can transform this into a memset in the loop preheader, do so. > ?bool LoopIdiomRecognize:: > ?processLoopStoreOfSplatValue(StoreInst *SI, unsigned StoreSize, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Value *SplatValue, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const SCEVAddRecExpr *Ev, const SCEV *BECount) { > + ?// Temporarily remove the store from the loop, to avoid the mod/ref query from > + ?// seeing it. > + ?Instruction *InstAfterStore = ++BasicBlock::iterator(SI); > + ?SI->removeFromParent(); > + > ? // Okay, we have a strided store "p[i]" of a splattable value. ?We can turn > ? // this into a memset in the loop preheader now if we want. ?However, this > ? // would be unsafe to do if there is anything else in the loop that may read > ? // or write to the aliased location. ?Check for an alias. > + ?bool Unsafe=mayLoopModRefLocation(SI, CurLoop, getAnalysis()); > + > + ?SI->insertBefore(InstAfterStore); From nicholas at mxc.ca Sat Jan 1 20:46:33 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 02 Jan 2011 02:46:33 -0000 Subject: [llvm-commits] [llvm] r122677 - /llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Message-ID: <20110102024633.BD7A32A6C12C@llvm.org> Author: nicholas Date: Sat Jan 1 20:46:33 2011 New Revision: 122677 URL: http://llvm.org/viewvc/llvm-project?rev=122677&view=rev Log: Remove functions from the FnSet when one of their callee's is being merged. This maintains the guarantee that the DenseSet expects two elements it contains to not go from inequal to equal under its nose. As a side-effect, this also lets us switch from iterating to a fixed-point to actually maintaining a work queue of functions to look at again, and we don't add thunks to our work queue so we don't need to detect and ignore them. Modified: llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Modified: llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp?rev=122677&r1=122676&r2=122677&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Sat Jan 1 20:46:33 2011 @@ -160,20 +160,36 @@ private: typedef DenseSet FnSetType; + /// A work queue of functions that may have been modified and should be + /// analyzed again. + std::vector Deferred; /// Insert a ComparableFunction into the FnSet, or merge it away if it's /// equal to one that's already present. - bool Insert(FnSetType &FnSet, ComparableFunction &NewF); + bool Insert(ComparableFunction &NewF); + + /// Remove a Function from the FnSet and queue it up for a second sweep of + /// analysis. + void Remove(Function *F); + + /// Find the functions that use this Value and remove them from FnSet and + /// queue the functions. + void RemoveUsers(Value *V); /// MergeTwoFunctions - Merge two equivalent functions. Upon completion, G /// may be deleted, or may be converted into a thunk. In either case, it /// should never be visited again. - void MergeTwoFunctions(Function *F, Function *G) const; + void MergeTwoFunctions(Function *F, Function *G); /// WriteThunk - Replace G with a simple tail call to bitcast(F). Also /// replace direct uses of G with bitcast(F). Deletes G. - void WriteThunk(Function *F, Function *G) const; + void WriteThunk(Function *F, Function *G); + + /// The set of all distinct functions. Use the Insert and Remove methods to + /// modify it. + FnSetType FnSet; + /// TargetData for more accurate GEP comparisons. May be NULL. TargetData *TD; }; @@ -560,7 +576,7 @@ /// WriteThunk - Replace G with a simple tail call to bitcast(F). Also replace /// direct uses of G with bitcast(F). Deletes G. -void MergeFunctions::WriteThunk(Function *F, Function *G) const { +void MergeFunctions::WriteThunk(Function *F, Function *G) { if (!G->mayBeOverridden()) { // Redirect direct callers of G to F. Constant *BitcastF = ConstantExpr::getBitCast(F, G->getType()); @@ -569,8 +585,10 @@ Value::use_iterator TheIter = UI; ++UI; CallSite CS(*TheIter); - if (CS && CS.isCallee(TheIter)) + if (CS && CS.isCallee(TheIter)) { + Remove(CS.getInstruction()->getParent()->getParent()); TheIter.getUse().set(BitcastF); + } } } @@ -606,6 +624,7 @@ NewG->copyAttributesFrom(G); NewG->takeName(G); + RemoveUsers(G); G->replaceAllUsesWith(NewG); G->eraseFromParent(); @@ -615,7 +634,7 @@ /// MergeTwoFunctions - Merge two equivalent functions. Upon completion, /// Function G is deleted. -void MergeFunctions::MergeTwoFunctions(Function *F, Function *G) const { +void MergeFunctions::MergeTwoFunctions(Function *F, Function *G) { if (F->mayBeOverridden()) { assert(G->mayBeOverridden()); @@ -624,6 +643,7 @@ F->getParent()); H->copyAttributesFrom(F); H->takeName(F); + RemoveUsers(F); F->replaceAllUsesWith(H); unsigned MaxAlignment = std::max(G->getAlignment(), H->getAlignment()); @@ -632,7 +652,7 @@ WriteThunk(F, H); F->setAlignment(MaxAlignment); - F->setLinkage(GlobalValue::InternalLinkage); + F->setLinkage(GlobalValue::PrivateLinkage); ++NumDoubleWeak; } else { @@ -644,7 +664,7 @@ // Insert - Insert a ComparableFunction into the FnSet, or merge it away if // equal to one that's already inserted. -bool MergeFunctions::Insert(FnSetType &FnSet, ComparableFunction &NewF) { +bool MergeFunctions::Insert(ComparableFunction &NewF) { std::pair Result = FnSet.insert(NewF); if (Result.second) return false; @@ -664,91 +684,52 @@ return true; } -// IsThunk - This method determines whether or not a given Function is a thunk\// like the ones emitted by this pass and therefore not subject to further -// merging. -static bool IsThunk(const Function *F) { - // The safe direction to fail is to return true. In that case, the function - // will be removed from merging analysis. If we failed to including functions - // then we may try to merge unmergable thing (ie., identical weak functions) - // which will push us into an infinite loop. - - assert(!F->isDeclaration() && "Expected a function definition."); - - const BasicBlock *BB = &F->front(); - // A thunk is: - // bitcast-inst* - // optional-reg tail call @thunkee(args...*) - // ret void|optional-reg - // where the args are in the same order as the arguments. - - // Put this at the top since it triggers most often. - const ReturnInst *RI = dyn_cast(BB->getTerminator()); - if (!RI) return false; - - // Verify that the sequence of bitcast-inst's are all casts of arguments and - // that there aren't any extras (ie. no repeated casts). - int LastArgNo = -1; - BasicBlock::const_iterator I = BB->begin(); - while (const BitCastInst *BCI = dyn_cast(I)) { - const Argument *A = dyn_cast(BCI->getOperand(0)); - if (!A) return false; - if ((int)A->getArgNo() <= LastArgNo) return false; - LastArgNo = A->getArgNo(); - ++I; - } - - // Verify that we have a direct tail call and that the calling conventions - // and number of arguments match. - const CallInst *CI = dyn_cast(I++); - if (!CI || !CI->isTailCall() || !CI->getCalledFunction() || - CI->getCallingConv() != CI->getCalledFunction()->getCallingConv() || - CI->getNumArgOperands() != F->arg_size()) - return false; - - // Verify that the call instruction has the same arguments as this function - // and that they're all either the incoming argument or a cast of the right - // argument. - for (unsigned i = 0, e = CI->getNumArgOperands(); i != e; ++i) { - const Value *V = CI->getArgOperand(i); - const Argument *A = dyn_cast(V); - if (!A) { - const BitCastInst *BCI = dyn_cast(V); - if (!BCI) return false; - A = cast(BCI->getOperand(0)); - } - if (A->getArgNo() != i) return false; +// Remove - Remove a function from FnSet. If it was already in FnSet, add it to +// Deferred so that we'll look at it in the next round. +void MergeFunctions::Remove(Function *F) { + ComparableFunction CF = ComparableFunction(F, TD); + if (FnSet.erase(CF)) { + Deferred.push_back(F); } +} - // Verify that the terminator is a ret void (if we're void) or a ret of the - // call's return, or a ret of a bitcast of the call's return. - if (const BitCastInst *BCI = dyn_cast(I)) { - ++I; - if (BCI->getOperand(0) != CI) return false; - } - if (RI != I) return false; - if (RI->getNumOperands() == 0) - return CI->getType()->isVoidTy(); - return RI->getReturnValue() == CI; +// RemoveUsers - For each instruction used by the value, Remove() the function +// that contains the instruction. This should happen right before a call to RAUW. +void MergeFunctions::RemoveUsers(Value *V) { + for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); + UI != UE; ++UI) { + Use &U = UI.getUse(); + if (Instruction *I = dyn_cast(U.getUser())) { + Remove(I->getParent()->getParent()); + } + } } bool MergeFunctions::runOnModule(Module &M) { bool Changed = false; TD = getAnalysisIfAvailable(); - bool LocalChanged; + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { + Deferred.push_back(WeakVH(I)); + } + do { + std::vector Worklist; + Deferred.swap(Worklist); + DEBUG(dbgs() << "size of module: " << M.size() << '\n'); - LocalChanged = false; - FnSetType FnSet; + DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n'); // Insert only strong functions and merge them. Strong function merging // always deletes one of them. - for (Module::iterator I = M.begin(), E = M.end(); I != E;) { - Function *F = I++; + for (std::vector::iterator I = Worklist.begin(), + E = Worklist.end(); I != E; ++I) { + if (!*I) continue; + Function *F = cast(*I); if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() && - !F->mayBeOverridden() && !IsThunk(F)) { + !F->mayBeOverridden()) { ComparableFunction CF = ComparableFunction(F, TD); - LocalChanged |= Insert(FnSet, CF); + Changed |= Insert(CF); } } @@ -756,17 +737,20 @@ // create thunks to the strong function when possible. When two weak // functions are identical, we create a new strong function with two weak // weak thunks to it which are identical but not mergable. - for (Module::iterator I = M.begin(), E = M.end(); I != E;) { - Function *F = I++; + for (std::vector::iterator I = Worklist.begin(), + E = Worklist.end(); I != E; ++I) { + if (!*I) continue; + Function *F = cast(*I); if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() && - F->mayBeOverridden() && !IsThunk(F)) { + F->mayBeOverridden()) { ComparableFunction CF = ComparableFunction(F, TD); - LocalChanged |= Insert(FnSet, CF); + Changed |= Insert(CF); } } DEBUG(dbgs() << "size of FnSet: " << FnSet.size() << '\n'); - Changed |= LocalChanged; - } while (LocalChanged); + } while (!Deferred.empty()); + + FnSet.clear(); return Changed; } From sabre at nondot.org Sat Jan 1 21:37:56 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 03:37:56 -0000 Subject: [llvm-commits] [llvm] r122678 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110102033756.880E62A6C12C@llvm.org> Author: lattner Date: Sat Jan 1 21:37:56 2011 New Revision: 122678 URL: http://llvm.org/viewvc/llvm-project?rev=122678&view=rev Log: teach loop idiom recognition to form memcpy's from simple loops. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/LoopIdiom/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122678&r1=122677&r2=122678&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sat Jan 1 21:37:56 2011 @@ -49,7 +49,11 @@ Value *SplatValue, const SCEVAddRecExpr *Ev, const SCEV *BECount); - + bool processLoopStoreOfLoopLoad(StoreInst *SI, unsigned StoreSize, + const SCEVAddRecExpr *StoreEv, + const SCEVAddRecExpr *LoadEv, + const SCEV *BECount); + /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG. /// @@ -172,14 +176,15 @@ // See if the pointer expression is an AddRec like {base,+,1} on the current // loop, which indicates a strided store. If we have something else, it's a // random store we can't handle. - const SCEVAddRecExpr *Ev = dyn_cast(SE->getSCEV(StorePtr)); - if (Ev == 0 || Ev->getLoop() != CurLoop || !Ev->isAffine()) + const SCEVAddRecExpr *StoreEv = + dyn_cast(SE->getSCEV(StorePtr)); + if (StoreEv == 0 || StoreEv->getLoop() != CurLoop || !StoreEv->isAffine()) return false; // Check to see if the stride matches the size of the store. If so, then we // know that every byte is touched in the loop. unsigned StoreSize = (unsigned)SizeInBits >> 3; - const SCEVConstant *Stride = dyn_cast(Ev->getOperand(1)); + const SCEVConstant *Stride = dyn_cast(StoreEv->getOperand(1)); // TODO: Could also handle negative stride here someday, that will require the // validity check in mayLoopModRefLocation to be updated though. @@ -190,10 +195,22 @@ // turned into a memset of i8 -1, assuming that all the consequtive bytes // are stored. A store of i32 0x01020304 can never be turned into a memset. if (Value *SplatValue = isBytewiseValue(StoredVal)) - return processLoopStoreOfSplatValue(SI, StoreSize, SplatValue, Ev, BECount); - - // Handle the memcpy case here. - // errs() << "Found strided store: " << *Ev << "\n"; + if (processLoopStoreOfSplatValue(SI, StoreSize, SplatValue, StoreEv, + BECount)) + return true; + + // If the stored value is a strided load in the same loop with the same stride + // this this may be transformable into a memcpy. This kicks in for stuff like + // for (i) A[i] = B[i]; + if (LoadInst *LI = dyn_cast(StoredVal)) { + const SCEVAddRecExpr *LoadEv = + dyn_cast(SE->getSCEV(LI->getOperand(0))); + if (LoadEv && LoadEv->getLoop() == CurLoop && LoadEv->isAffine() && + StoreEv->getOperand(1) == LoadEv->getOperand(1) && !LI->isVolatile()) + if (processLoopStoreOfLoopLoad(SI, StoreSize, StoreEv, LoadEv, BECount)) + return true; + } + // errs() << "UNHANDLED strided store: " << *Ev << " - " << *SI << "\n"; return false; } @@ -201,8 +218,9 @@ /// mayLoopModRefLocation - Return true if the specified loop might do a load or /// store to the same location that the specified store could store to, which is /// a loop-strided access. -static bool mayLoopModRefLocation(StoreInst *SI, Loop *L, const SCEV *BECount, - unsigned StoreSize, AliasAnalysis &AA) { +static bool mayLoopModRefLocation(Value *Ptr, Loop *L, const SCEV *BECount, + unsigned StoreSize, AliasAnalysis &AA, + StoreInst *IgnoredStore) { // Get the location that may be stored across the loop. Since the access is // strided positively through memory, we say that the modified location starts // at the pointer and has infinite size. @@ -217,12 +235,13 @@ // operand in the store. Store to &A[i] of 100 will always return may alias // with store of &A[100], we need to StoreLoc to be "A" with size of 100, // which will then no-alias a store to &A[100]. - AliasAnalysis::Location StoreLoc(SI->getPointerOperand(), AccessSize); + AliasAnalysis::Location StoreLoc(Ptr, AccessSize); for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; ++BI) for (BasicBlock::iterator I = (*BI)->begin(), E = (*BI)->end(); I != E; ++I) - if (AA.getModRefInfo(I, StoreLoc) != AliasAnalysis::NoModRef) + if (&*I != IgnoredStore && + AA.getModRefInfo(I, StoreLoc) != AliasAnalysis::NoModRef) return true; return false; @@ -239,21 +258,13 @@ if (!CurLoop->isLoopInvariant(SplatValue)) return false; - // Temporarily remove the store from the loop, to avoid the mod/ref query from - // seeing it. - Instruction *InstAfterStore = ++BasicBlock::iterator(SI); - SI->removeFromParent(); - // Okay, we have a strided store "p[i]" of a splattable value. We can turn // this into a memset in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read // or write to the aliased location. Check for an alias. - bool Unsafe = mayLoopModRefLocation(SI, CurLoop, BECount, StoreSize, - getAnalysis()); - - SI->insertBefore(InstAfterStore); - - if (Unsafe) return false; + if (mayLoopModRefLocation(SI->getPointerOperand(), CurLoop, BECount, + StoreSize, getAnalysis(), SI)) + return false; // Okay, everything looks good, insert the memset. BasicBlock *Preheader = CurLoop->getLoopPreheader(); @@ -301,3 +312,72 @@ return true; } +/// processLoopStoreOfLoopLoad - We see a strided store whose value is a +/// same-strided load. +bool LoopIdiomRecognize:: +processLoopStoreOfLoopLoad(StoreInst *SI, unsigned StoreSize, + const SCEVAddRecExpr *StoreEv, + const SCEVAddRecExpr *LoadEv, + const SCEV *BECount) { + LoadInst *LI = cast(SI->getValueOperand()); + + // Okay, we have a strided store "p[i]" of a loaded value. We can turn + // this into a memcmp in the loop preheader now if we want. However, this + // would be unsafe to do if there is anything else in the loop that may read + // or write to the aliased location (including the load feeding the stores). + // Check for an alias. + if (mayLoopModRefLocation(SI->getPointerOperand(), CurLoop, BECount, + StoreSize, getAnalysis(), SI)) + return false; + + // Okay, everything looks good, insert the memcpy. + BasicBlock *Preheader = CurLoop->getLoopPreheader(); + + IRBuilder<> Builder(Preheader->getTerminator()); + + // The trip count of the loop and the base pointer of the addrec SCEV is + // guaranteed to be loop invariant, which means that it should dominate the + // header. Just insert code for it in the preheader. + SCEVExpander Expander(*SE); + + Value *LoadBasePtr = + Expander.expandCodeFor(LoadEv->getStart(), + Builder.getInt8PtrTy(LI->getPointerAddressSpace()), + Preheader->getTerminator()); + Value *StoreBasePtr = + Expander.expandCodeFor(StoreEv->getStart(), + Builder.getInt8PtrTy(SI->getPointerAddressSpace()), + Preheader->getTerminator()); + + // The # stored bytes is (BECount+1)*Size. Expand the trip count out to + // pointer size if it isn't already. + const Type *IntPtr = TD->getIntPtrType(SI->getContext()); + unsigned BESize = SE->getTypeSizeInBits(BECount->getType()); + if (BESize < TD->getPointerSizeInBits()) + BECount = SE->getZeroExtendExpr(BECount, IntPtr); + else if (BESize > TD->getPointerSizeInBits()) + BECount = SE->getTruncateExpr(BECount, IntPtr); + + const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), + true, true /*nooverflow*/); + if (StoreSize != 1) + NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize), + true, true /*nooverflow*/); + + Value *NumBytes = + Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); + + Value *NewCall = + Builder.CreateMemCpy(StoreBasePtr, LoadBasePtr, NumBytes, + std::min(SI->getAlignment(), LI->getAlignment())); + + DEBUG(dbgs() << " Formed memcpy: " << *NewCall << "\n" + << " from load ptr=" << *LoadEv << " at: " << *LI << "\n" + << " from store ptr=" << *StoreEv << " at: " << *SI << "\n"); + (void)NewCall; + + // Okay, the memset has been formed. Zap the original store and anything that + // feeds into it. + DeleteDeadInstruction(SI, *SE); + return true; +} Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122678&r1=122677&r2=122678&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sat Jan 1 21:37:56 2011 @@ -114,3 +114,31 @@ ; CHECK: ret void } + +;; memcpy formation +define void @test6(i64 %Size) nounwind ssp { +bb.nph: + %Base = alloca i8, i32 10000 + %Dest = alloca i8, i32 10000 + br label %for.body + +for.body: ; preds = %bb.nph, %for.body + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] + %I.0.014 = getelementptr i8* %Base, i64 %indvar + %DestI = getelementptr i8* %Dest, i64 %indvar + %V = load i8* %I.0.014, align 1 + store i8 %V, i8* %DestI, align 1 + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, %Size + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK: @test6 +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Dest, i8* %Base, i64 %Size, i32 1, i1 false) +; CHECK-NOT: store +; CHECK: ret void +} + + + From sabre at nondot.org Sat Jan 1 21:42:18 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 1 Jan 2011 19:42:18 -0800 Subject: [llvm-commits] [llvm] r122659 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: References: <20110101193901.C288E2A6C12C@llvm.org> Message-ID: <4B7920D6-2B48-4EC5-A115-6FBC3634E5F4@nondot.org> On Jan 1, 2011, at 4:54 PM, Frits van Bommel wrote: > On Sat, Jan 1, 2011 at 8:39 PM, Chris Lattner wrote: >> +/// mayLoopModRefLocation - Return true if the specified loop might do a load or >> +/// store to the same location that the specified store could store to, which is >> +/// a loop-strided access. >> +static bool mayLoopModRefLocation(StoreInst *SI, Loop *L, AliasAnalysis &AA) { >> + // Get the location that may be stored across the loop. Since the access is >> + // strided positively through memory, we say that the modified location starts >> + // at the pointer and has infinite size. >> + // TODO: Could improve this for constant trip-count loops. >> + AliasAnalysis::Location StoreLoc = >> + AliasAnalysis::Location(SI->getPointerOperand()); >> + >> + for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; >> + ++BI) >> + for (BasicBlock::iterator I = (*BI)->begin(), E = (*BI)->end(); I != E; ++I) >> + if (AA.getModRefInfo(I, StoreLoc) != AliasAnalysis::NoModRef) >> + return true; > > Wouldn't it be cleaner to add an 'I != SI &&' to the condition here > instead of temporarily removing SI from the block in before calling > this? Yes, I did this because I thought it would be useful for memcpy formation, but I changed my mind. I switched to this approach. > Of course, checking that extra condition for every instruction in the > loop is probably less efficient, which I'm guessing is the reason you > did it this way? I did it this way because I wanted memcpy formation to take the load *and* store out, but I realize now that it would be a bad idea because I *want* an interference when the store aliases the load. Anyway, please take a look at r122678. -Chris From pichet2000 at gmail.com Sat Jan 1 22:23:50 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Sat, 1 Jan 2011 23:23:50 -0500 Subject: [llvm-commits] [llvm] r122648 - /llvm/trunk/cmake/modules/LLVMProcessSources.cmake In-Reply-To: <20101231191049.3AD9B2A6C12C@llvm.org> References: <20101231191049.3AD9B2A6C12C@llvm.org> Message-ID: On Fri, Dec 31, 2010 at 2:10 PM, Oscar Fuentes wrote: > Author: ofv > Date: Fri Dec 31 13:10:49 2010 > New Revision: 122648 > > URL: http://llvm.org/viewvc/llvm-project?rev=122648&view=rev > Log: > CMake (MSVC): cmake automatically adds the /EHsc and /GR compiler > options. If we are building with exceptions/rtti disabled, we replace > /EHsc with /EHs-c- and /GR with /GR-, respectively. If we just add the > disabling options we get warnings like this: > > cl : Command line warning D9025 : overriding '/EHs' with '/EHs-' > > Hi Oscar, This patch doesn't work for me using MSVC 2008. I get RTTI and exception enabled all over again. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110101/8d453b12/attachment.html From zwarich at apple.com Sun Jan 2 01:03:00 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 02 Jan 2011 07:03:00 -0000 Subject: [llvm-commits] [llvm] r122680 - in /llvm/trunk/include/llvm/Analysis: DominatorInternals.h Dominators.h Message-ID: <20110102070300.9107C2A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 01:03:00 2011 New Revision: 122680 URL: http://llvm.org/viewvc/llvm-project?rev=122680&view=rev Log: Speed up dominator computation some more by optimizing bucket processing. When naively implemented, the Lengauer-Tarjan algorithm requires a separate bucket for each vertex. However, this is unnecessary, because each vertex is only placed into a single bucket (that of its semidominator), and each vertex's bucket is processed before it is added to any bucket itself. Instead of using a bucket per vertex, we use a single array Buckets that has two purposes. Before the vertex V with DFS number i is processed, Buckets[i] stores the index of the first element in V's bucket. After V's bucket is processed, Buckets[i] stores the index of the next element in the bucket to which V now belongs, if any. Reading from the buckets can also be optimized. Instead of processing the bucket of V's parent at the end of processing V, we process the bucket of V itself at the beginning of processing V. This means that the case of the root vertex can be simplified somewhat. It also means that we don't need to look up the DFS number of the semidominator of every node in the bucket we are processing, since we know it is the current index being processed. This is a 6.5% speedup running -domtree on test-suite + SPEC2000/2006, with larger speedups of around 12% on the larger benchmarks like GCC. Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h llvm/trunk/include/llvm/Analysis/Dominators.h Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=122680&r1=122679&r2=122680&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 01:03:00 2011 @@ -257,12 +257,24 @@ // infinite loops). In these cases an artificial exit node is required. MultipleRoots |= (DT.isPostDominator() && N != F.size()); + std::vector Buckets; + Buckets.reserve(N + 1); + for (unsigned i = 1; i <= N; ++i) + Buckets[i] = i; + for (unsigned i = N; i >= 2; --i) { typename GraphT::NodeType* W = DT.Vertex[i]; typename DominatorTreeBase::InfoRec &WInfo = DT.Info[W]; - // Step #2: Calculate the semidominators of all vertices + // Step #2: Implicitly define the immediate dominator of vertices + for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) { + typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; + typename GraphT::NodeType* U = Eval(DT, V); + DT.IDoms[V] = DT.Info[U].Semi < i ? U : W; + } + + // Step #3: Calculate the semidominators of all vertices // initialize the semi dominator to point to the parent node WInfo.Semi = WInfo.Parent; @@ -283,21 +295,21 @@ // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is // necessarily parent(V). In this case, set idom(V) here and avoid placing // V into a bucket. - if (WInfo.Semi == WInfo.Parent) + if (WInfo.Semi == WInfo.Parent) { DT.IDoms[W] = WParent; - else - DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W); + } else { + Buckets[i] = Buckets[WInfo.Semi]; + Buckets[WInfo.Semi] = i; + } Link(DT, WInfo.Parent, W, WInfo); + } - // Step #3: Implicitly define the immediate dominator of vertices - std::vector &WParentBucket = - DT.Info[WParent].Bucket; - while (!WParentBucket.empty()) { - typename GraphT::NodeType* V = WParentBucket.back(); - WParentBucket.pop_back(); - typename GraphT::NodeType* U = Eval(DT, V); - DT.IDoms[V] = DT.Info[U].Semi < DT.Info[V].Semi ? U : WParent; + if (N >= 1) { + typename GraphT::NodeType* Root = DT.Vertex[1]; + for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) { + typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; + DT.IDoms[V] = Root; } } Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=122680&r1=122679&r2=122680&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Sun Jan 2 01:03:00 2011 @@ -210,8 +210,6 @@ NodeT *Label, *Child; unsigned Parent, Ancestor; - std::vector Bucket; - InfoRec() : DFSNum(0), Semi(0), Size(0), Label(0), Child(0), Parent(0), Ancestor(0) {} }; From sabre at nondot.org Sun Jan 2 01:35:53 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 07:35:53 -0000 Subject: [llvm-commits] [llvm] r122681 - in /llvm/trunk/lib/Transforms/Scalar: LoopRotation.cpp LoopUnrollPass.cpp Message-ID: <20110102073553.5ECB02A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 01:35:53 2011 New Revision: 122681 URL: http://llvm.org/viewvc/llvm-project?rev=122681&view=rev Log: improve loop rotation to use CodeMetrics to analyze the size of a loop header instead of its own code size estimator. This allows it to handle bitcasts etc more precisely. Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=122681&r1=122680&r2=122681&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sun Jan 2 01:35:53 2011 @@ -14,9 +14,9 @@ #define DEBUG_TYPE "loop-rotate" #include "llvm/Transforms/Scalar.h" #include "llvm/Function.h" -#include "llvm/IntrinsicInst.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -142,23 +142,14 @@ if (ExitBlocks.size() > 1) return false; - // Check size of original header and reject - // loop if it is very big. - unsigned Size = 0; - - // FIXME: Use common api to estimate size. - for (BasicBlock::const_iterator OI = OrigHeader->begin(), - OE = OrigHeader->end(); OI != OE; ++OI) { - if (isa(OI)) - continue; // PHI nodes don't count. - if (isa(OI)) - continue; // Debug intrinsics don't count as size. - ++Size; + // Check size of original header and reject loop if it is very big. + { + CodeMetrics Metrics; + Metrics.analyzeBasicBlock(OrigHeader); + if (Metrics.NumInsts > MAX_HEADER_SIZE) + return false; } - if (Size > MAX_HEADER_SIZE) - return false; - // Now, this loop is suitable for rotation. // Anything ScalarEvolution may know about this loop or the PHI nodes Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp?rev=122681&r1=122680&r2=122681&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp Sun Jan 2 01:35:53 2011 @@ -16,7 +16,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/InlineCost.h" +#include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" From sabre at nondot.org Sun Jan 2 01:36:44 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 07:36:44 -0000 Subject: [llvm-commits] [llvm] r122682 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20110102073644.641162A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 01:36:44 2011 New Revision: 122682 URL: http://llvm.org/viewvc/llvm-project?rev=122682&view=rev Log: add some -stats output. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122682&r1=122681&r2=122682&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 01:36:44 2011 @@ -25,10 +25,13 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/Statistic.h" using namespace llvm; // TODO: Recognize "N" size array multiplies: replace with call to blas or // something. +STATISTIC(NumMemSet, "Number of memset's formed from loop stores"); +STATISTIC(NumMemCpy, "Number of memcpy's formed from loop load+stores"); namespace { class LoopIdiomRecognize : public LoopPass { @@ -123,6 +126,10 @@ bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) { CurLoop = L; + if (L->getHeader()->getName().startswith("bb29")) { + errs() << *L->getHeader(); + } + // We only look at trivial single basic block loops. // TODO: eventually support more complex loops, scanning the header. if (L->getBlocks().size() != 1) @@ -210,7 +217,7 @@ if (processLoopStoreOfLoopLoad(SI, StoreSize, StoreEv, LoadEv, BECount)) return true; } - // errs() << "UNHANDLED strided store: " << *Ev << " - " << *SI << "\n"; + //errs() << "UNHANDLED strided store: " << *StoreEv << " - " << *SI << "\n"; return false; } @@ -309,6 +316,7 @@ // Okay, the memset has been formed. Zap the original store and anything that // feeds into it. DeleteDeadInstruction(SI, *SE); + ++NumMemSet; return true; } @@ -379,5 +387,6 @@ // Okay, the memset has been formed. Zap the original store and anything that // feeds into it. DeleteDeadInstruction(SI, *SE); + ++NumMemCpy; return true; } From sabre at nondot.org Sun Jan 2 01:37:13 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 07:37:13 -0000 Subject: [llvm-commits] [llvm] r122683 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20110102073713.64F282A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 01:37:13 2011 New Revision: 122683 URL: http://llvm.org/viewvc/llvm-project?rev=122683&view=rev Log: remove debugging code. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122683&r1=122682&r2=122683&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 01:37:13 2011 @@ -126,10 +126,6 @@ bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) { CurLoop = L; - if (L->getHeader()->getName().startswith("bb29")) { - errs() << *L->getHeader(); - } - // We only look at trivial single basic block loops. // TODO: eventually support more complex loops, scanning the header. if (L->getBlocks().size() != 1) From zwarich at apple.com Sun Jan 2 01:53:49 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 02 Jan 2011 07:53:49 -0000 Subject: [llvm-commits] [llvm] r122684 - /llvm/trunk/include/llvm/Analysis/DominatorInternals.h Message-ID: <20110102075349.448672A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 01:53:49 2011 New Revision: 122684 URL: http://llvm.org/viewvc/llvm-project?rev=122684&view=rev Log: Remove the #ifdef'd code for balancing the eval-link data structure. It doesn't compile, and everyone's tests have shown it to be slower in practice, even for quite large graphs. I also hope to do an optimization that is only correct with the simpler data structure, which would break this even further. Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=122684&r1=122683&r2=122684&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 01:53:49 2011 @@ -22,13 +22,9 @@ // A Fast Algorithm for Finding Dominators in a Flowgraph // T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. // -// This implements both the O(n*ack(n)) and the O(n*log(n)) versions of EVAL and -// LINK, but it turns out that the theoretically slower O(n*log(n)) -// implementation is actually faster than the "efficient" algorithm (even for -// large CFGs) because the constant overheads are substantially smaller. The -// lower-complexity version can be enabled with the following #define: -// -#define BALANCE_IDOM_TREE 0 +// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns +// out that the theoretically slower O(n*log(n)) implementation is actually +// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs. // //===----------------------------------------------------------------------===// @@ -157,75 +153,17 @@ typename GraphT::NodeType *V) { typename DominatorTreeBase::InfoRec &VInfo = DT.Info[V]; -#if !BALANCE_IDOM_TREE - // Higher-complexity but faster implementation if (VInfo.Ancestor == 0) return V; Compress(DT, V); return VInfo.Label; -#else - // Lower-complexity but slower implementation - if (VInfo.Ancestor == 0) - return VInfo.Label; - Compress(DT, V); - GraphT::NodeType* VLabel = VInfo.Label; - - GraphT::NodeType* VAncestorLabel = DT.Info[VInfo.Ancestor].Label; - if (DT.Info[VAncestorLabel].Semi >= DT.Info[VLabel].Semi) - return VLabel; - else - return VAncestorLabel; -#endif } template void Link(DominatorTreeBase& DT, unsigned DFSNumV, typename GraphT::NodeType* W, typename DominatorTreeBase::InfoRec &WInfo) { -#if !BALANCE_IDOM_TREE - // Higher-complexity but faster implementation WInfo.Ancestor = DFSNumV; -#else - // Lower-complexity but slower implementation - GraphT::NodeType* WLabel = WInfo.Label; - unsigned WLabelSemi = DT.Info[WLabel].Semi; - GraphT::NodeType* S = W; - InfoRec *SInfo = &DT.Info[S]; - - GraphT::NodeType* SChild = SInfo->Child; - InfoRec *SChildInfo = &DT.Info[SChild]; - - while (WLabelSemi < DT.Info[SChildInfo->Label].Semi) { - GraphT::NodeType* SChildChild = SChildInfo->Child; - if (SInfo->Size+DT.Info[SChildChild].Size >= 2*SChildInfo->Size) { - SChildInfo->Ancestor = S; - SInfo->Child = SChild = SChildChild; - SChildInfo = &DT.Info[SChild]; - } else { - SChildInfo->Size = SInfo->Size; - S = SInfo->Ancestor = SChild; - SInfo = SChildInfo; - SChild = SChildChild; - SChildInfo = &DT.Info[SChild]; - } - } - - DominatorTreeBase::InfoRec &VInfo = DT.Info[V]; - SInfo->Label = WLabel; - - assert(V != W && "The optimization here will not work in this case!"); - unsigned WSize = WInfo.Size; - unsigned VSize = (VInfo.Size += WSize); - - if (VSize < 2*WSize) - std::swap(S, VInfo.Child); - - while (S) { - SInfo = &DT.Info[S]; - SInfo->Ancestor = V; - S = SInfo->Child; - } -#endif } template From sabre at nondot.org Sun Jan 2 01:58:36 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 07:58:36 -0000 Subject: [llvm-commits] [llvm] r122685 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110102075836.939272A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 01:58:36 2011 New Revision: 122685 URL: http://llvm.org/viewvc/llvm-project?rev=122685&view=rev Log: Allow loop-idiom to run on multiple BB loops, but still only scan the loop header for now for memset/memcpy opportunities. It turns out that loop-rotate is successfully rotating loops, but *DOESN'T MERGE THE BLOCKS*, turning "for loops" into 2 basic block loops that loop-idiom was ignoring. With this fix, we form many *many* more memcpy and memsets than before, including on the "history" loops in the viterbi benchmark, which look like this: for (j=0; jgetBlocks().size() != 1) - return false; - // The trip count of the loop must be analyzable. SE = &getAnalysis(); if (!SE->hasLoopInvariantBackedgeTakenCount(L)) @@ -142,6 +137,11 @@ TD = getAnalysisIfAvailable(); if (TD == 0) return false; + // TODO: We currently only scan the header of the loop, because it is the only + // part that is known to execute and we don't want to make a conditional store + // into an unconditional one in the preheader. However, there can be diamonds + // and other things in the loop that would make other blocks "always executed" + // we should get the full set and scan each block. BasicBlock *BB = L->getHeader(); DEBUG(dbgs() << "loop-idiom Scanning: F[" << BB->getParent()->getName() << "] Loop %" << BB->getName() << "\n"); Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122685&r1=122684&r2=122685&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sun Jan 2 01:58:36 2011 @@ -21,6 +21,30 @@ ; CHECK-NOT: store } +; This is a loop that was rotated but where the blocks weren't merged. This +; shouldn't perturb us. +define void @test1a(i8* %Base, i64 %Size) nounwind ssp { +bb.nph: ; preds = %entry + br label %for.body + +for.body: ; preds = %bb.nph, %for.body + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body.cont ] + %I.0.014 = getelementptr i8* %Base, i64 %indvar + store i8 0, i8* %I.0.014, align 1 + %indvar.next = add i64 %indvar, 1 + br label %for.body.cont +for.body.cont: + %exitcond = icmp eq i64 %indvar.next, %Size + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK: @test1a +; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false) +; CHECK-NOT: store +} + + define void @test2(i32* %Base, i64 %Size) nounwind ssp { entry: %cmp10 = icmp eq i64 %Size, 0 From fvbommel at gmail.com Sun Jan 2 04:08:52 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 2 Jan 2011 11:08:52 +0100 Subject: [llvm-commits] [llvm] r122678 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: <20110102033756.880E62A6C12C@llvm.org> References: <20110102033756.880E62A6C12C@llvm.org> Message-ID: On Sun, Jan 2, 2011 at 4:37 AM, Chris Lattner wrote: > +/// processLoopStoreOfLoopLoad - We see a strided store whose value is a > +/// same-strided load. > +bool LoopIdiomRecognize:: > +processLoopStoreOfLoopLoad(StoreInst *SI, unsigned StoreSize, > + ? ? ? ? ? ? ? ? ? ? ? ? ? const SCEVAddRecExpr *StoreEv, > + ? ? ? ? ? ? ? ? ? ? ? ? ? const SCEVAddRecExpr *LoadEv, > + ? ? ? ? ? ? ? ? ? ? ? ? ? const SCEV *BECount) { > + ?LoadInst *LI = cast(SI->getValueOperand()); > + > + ?// Okay, we have a strided store "p[i]" of a loaded value. ?We can turn > + ?// this into a memcmp in the loop preheader now if we want. ?However, this s/memcmp/memcpy/ > + ?// would be unsafe to do if there is anything else in the loop that may read > + ?// or write to the aliased location (including the load feeding the stores). > + ?// Check for an alias. TODO: If *only* the load feeding the stores aliases them, turn it into memmove instead :). (unless the load has other uses) From zwarich at apple.com Sun Jan 2 04:06:44 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 02 Jan 2011 10:06:44 -0000 Subject: [llvm-commits] [llvm] r122687 - /llvm/trunk/include/llvm/Analysis/DominatorInternals.h Message-ID: <20110102100644.878112A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 04:06:44 2011 New Revision: 122687 URL: http://llvm.org/viewvc/llvm-project?rev=122687&view=rev Log: Fix a typo, which should also fix the failure on llvm-x86_64-linux-checks. Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=122687&r1=122686&r2=122687&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 04:06:44 2011 @@ -196,7 +196,7 @@ MultipleRoots |= (DT.isPostDominator() && N != F.size()); std::vector Buckets; - Buckets.reserve(N + 1); + Buckets.resize(N + 1); for (unsigned i = 1; i <= N; ++i) Buckets[i] = i; From zwarich at apple.com Sun Jan 2 04:10:02 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 02 Jan 2011 10:10:02 -0000 Subject: [llvm-commits] [llvm] r122688 - /llvm/trunk/include/llvm/Analysis/DominatorInternals.h Message-ID: <20110102101002.628962A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 04:10:02 2011 New Revision: 122688 URL: http://llvm.org/viewvc/llvm-project?rev=122688&view=rev Log: Tidy up indentation. Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=122688&r1=122687&r2=122688&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 04:10:02 2011 @@ -207,9 +207,9 @@ // Step #2: Implicitly define the immediate dominator of vertices for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) { - typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; - typename GraphT::NodeType* U = Eval(DT, V); - DT.IDoms[V] = DT.Info[U].Semi < i ? U : W; + typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; + typename GraphT::NodeType* U = Eval(DT, V); + DT.IDoms[V] = DT.Info[U].Semi < i ? U : W; } // Step #3: Calculate the semidominators of all vertices @@ -246,8 +246,8 @@ if (N >= 1) { typename GraphT::NodeType* Root = DT.Vertex[1]; for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) { - typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; - DT.IDoms[V] = Root; + typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; + DT.IDoms[V] = Root; } } From fvbommel at gmail.com Sun Jan 2 04:27:59 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 2 Jan 2011 11:27:59 +0100 Subject: [llvm-commits] [llvm] r122677 - /llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp In-Reply-To: <20110102024633.BD7A32A6C12C@llvm.org> References: <20110102024633.BD7A32A6C12C@llvm.org> Message-ID: On Sun, Jan 2, 2011 at 3:46 AM, Nick Lewycky wrote: > +// RemoveUsers - For each instruction used by the value, Remove() the function > +// that contains the instruction. This should happen right before a call to RAUW. > +void MergeFunctions::RemoveUsers(Value *V) { > + ?for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); > + ? ? ? UI != UE; ++UI) { > + ? ?Use &U = UI.getUse(); > + ? ?if (Instruction *I = dyn_cast(U.getUser())) { > + ? ? ?Remove(I->getParent()->getParent()); > + ? ?} > + ?} > ?} This doesn't handle uses in constant expressions, which can also make two functions suddenly compare equal when they change. From zwarich at apple.com Sun Jan 2 04:40:14 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 02 Jan 2011 10:40:14 -0000 Subject: [llvm-commits] [llvm] r122689 - /llvm/trunk/include/llvm/Analysis/DominatorInternals.h Message-ID: <20110102104014.AE5AF2A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 04:40:14 2011 New Revision: 122689 URL: http://llvm.org/viewvc/llvm-project?rev=122689&view=rev Log: Add the explanatory comment from r122680's commit message to the code itself. Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=122689&r1=122688&r2=122689&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 04:40:14 2011 @@ -195,6 +195,16 @@ // infinite loops). In these cases an artificial exit node is required. MultipleRoots |= (DT.isPostDominator() && N != F.size()); + // When naively implemented, the Lengauer-Tarjan algorithm requires a separate + // bucket for each vertex. However, this is unnecessary, because each vertex + // is only placed into a single bucket (that of its semidominator), and each + // vertex's bucket is processed before it is added to any bucket itself. + // + // Instead of using a bucket per vertex, we use a single array Buckets that + // has two purposes. Before the vertex V with preorder number i is processed, + // Buckets[i] stores the index of the first element in V's bucket. After V's + // bucket is processed, Buckets[i] stores the index of the next element in the + // bucket containing V, if any. std::vector Buckets; Buckets.resize(N + 1); for (unsigned i = 1; i <= N; ++i) From zwarich at apple.com Sun Jan 2 04:50:15 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 02 Jan 2011 10:50:15 -0000 Subject: [llvm-commits] [llvm] r122690 - /llvm/trunk/include/llvm/Analysis/DominatorInternals.h Message-ID: <20110102105015.1240A2A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 04:50:14 2011 New Revision: 122690 URL: http://llvm.org/viewvc/llvm-project?rev=122690&view=rev Log: Move a load into the only branch where it is used and eliminate a temporary. Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=122690&r1=122689&r2=122690&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 04:50:14 2011 @@ -238,13 +238,11 @@ } } - typename GraphT::NodeType* WParent = DT.Vertex[WInfo.Parent]; - // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is // necessarily parent(V). In this case, set idom(V) here and avoid placing // V into a bucket. if (WInfo.Semi == WInfo.Parent) { - DT.IDoms[W] = WParent; + DT.IDoms[W] = DT.Vertex[WInfo.Parent]; } else { Buckets[i] = Buckets[WInfo.Semi]; Buckets[WInfo.Semi] = i; From zwarich at apple.com Sun Jan 2 06:17:10 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 02 Jan 2011 12:17:10 -0000 Subject: [llvm-commits] [llvm] r122691 - /llvm/trunk/include/llvm/Analysis/DominatorInternals.h Message-ID: <20110102121710.5BE402A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 06:17:10 2011 New Revision: 122691 URL: http://llvm.org/viewvc/llvm-project?rev=122691&view=rev Log: Fix a typo in a variable name. Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=122691&r1=122690&r2=122691&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 06:17:10 2011 @@ -54,7 +54,7 @@ } } #else - bool IsChilOfArtificialExit = (N != 0); + bool IsChildOfArtificialExit = (N != 0); std::vector > Worklist; @@ -76,10 +76,10 @@ //BBInfo[V].Child = 0; // Child[v] = 0 BBInfo.Size = 1; // Size[v] = 1 - if (IsChilOfArtificialExit) + if (IsChildOfArtificialExit) BBInfo.Parent = 1; - IsChilOfArtificialExit = false; + IsChildOfArtificialExit = false; } // store the DFS number of the current BB - the reference to BBInfo might From ofv at wanadoo.es Sun Jan 2 06:30:19 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sun, 02 Jan 2011 12:30:19 -0000 Subject: [llvm-commits] [llvm] r122692 - /llvm/trunk/cmake/modules/LLVMProcessSources.cmake Message-ID: <20110102123019.0B9BF2A6C12C@llvm.org> Author: ofv Date: Sun Jan 2 06:30:18 2011 New Revision: 122692 URL: http://llvm.org/viewvc/llvm-project?rev=122692&view=rev Log: Propagate to parent scope changes made to CMAKE_CXX_FLAGS. Modified: llvm/trunk/cmake/modules/LLVMProcessSources.cmake Modified: llvm/trunk/cmake/modules/LLVMProcessSources.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMProcessSources.cmake?rev=122692&r1=122691&r2=122692&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMProcessSources.cmake (original) +++ llvm/trunk/cmake/modules/LLVMProcessSources.cmake Sun Jan 2 06:30:18 2011 @@ -54,6 +54,7 @@ endif() endif() + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE ) set( ${OUT_VAR} ${sources} PARENT_SCOPE ) endfunction(llvm_process_sources) From ofv at wanadoo.es Sun Jan 2 06:34:29 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sun, 02 Jan 2011 13:34:29 +0100 Subject: [llvm-commits] [llvm] r122648 - /llvm/trunk/cmake/modules/LLVMProcessSources.cmake In-Reply-To: (Francois Pichet's message of "Sat, 1 Jan 2011 23:23:50 -0500") References: <20101231191049.3AD9B2A6C12C@llvm.org> Message-ID: <87y6731o2y.fsf@telefonica.net> Francois Pichet writes: > On Fri, Dec 31, 2010 at 2:10 PM, Oscar Fuentes wrote: > >> Author: ofv >> Date: Fri Dec 31 13:10:49 2010 >> New Revision: 122648 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122648&view=rev >> Log: >> CMake (MSVC): cmake automatically adds the /EHsc and /GR compiler >> options. If we are building with exceptions/rtti disabled, we replace >> /EHsc with /EHs-c- and /GR with /GR-, respectively. If we just add the >> disabling options we get warnings like this: >> >> cl : Command line warning D9025 : overriding '/EHs' with '/EHs-' >> >> > Hi Oscar, > > This patch doesn't work for me using MSVC 2008. I get RTTI and exception > enabled all over again. Ooops! Please try again. From zwarich at apple.com Sun Jan 2 06:37:22 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 02 Jan 2011 12:37:22 -0000 Subject: [llvm-commits] [llvm] r122693 - /llvm/trunk/include/llvm/Analysis/Dominators.h Message-ID: <20110102123722.4F7262A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 06:37:22 2011 New Revision: 122693 URL: http://llvm.org/viewvc/llvm-project?rev=122693&view=rev Log: Remove an unused member function. Modified: llvm/trunk/include/llvm/Analysis/Dominators.h Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=122693&r1=122692&r2=122693&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Sun Jan 2 06:37:22 2011 @@ -301,9 +301,6 @@ : DominatorBase(isPostDom), DFSInfoValid(false), SlowQueries(0) {} virtual ~DominatorTreeBase() { reset(); } - // FIXME: Should remove this - virtual bool runOnFunction(Function &F) { return false; } - /// compare - Return false if the other dominator tree base matches this /// dominator tree base. Otherwise return true. bool compare(DominatorTreeBase &Other) const { From aggarwa4 at illinois.edu Sun Jan 2 07:34:02 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Sun, 02 Jan 2011 13:34:02 -0000 Subject: [llvm-commits] [poolalloc] r122694 - in /poolalloc/trunk/test: TEST.poolalloc.Makefile TEST.poolalloc.report Message-ID: <20110102133402.D8E1F2A6C12C@llvm.org> Author: aggarwa4 Date: Sun Jan 2 07:34:02 2011 New Revision: 122694 URL: http://llvm.org/viewvc/llvm-project?rev=122694&view=rev Log: Tracking dynamic pools. Modified: poolalloc/trunk/test/TEST.poolalloc.Makefile poolalloc/trunk/test/TEST.poolalloc.report Modified: poolalloc/trunk/test/TEST.poolalloc.Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/TEST.poolalloc.Makefile?rev=122694&r1=122693&r2=122694&view=diff ============================================================================== --- poolalloc/trunk/test/TEST.poolalloc.Makefile (original) +++ poolalloc/trunk/test/TEST.poolalloc.Makefile Sun Jan 2 07:34:02 2011 @@ -268,6 +268,10 @@ printf "RUN-TIME-POOLALLOC: " >> $@;\ grep "^program" Output/$*.poolalloc.out.time >> $@;\ fi + @-if test -f Output/$*.poolalloc.diff-nat; then \ + printf "DYNPOOLS: " >> $@;\ + grep '*** .* DYNAMIC POOLS ALLOCATED FROM ***' Output/$*.poolalloc.out >> $@;\ + fi @-if test -f Output/$*.poolalloc.bc.info; then \ printf "PATIME: " >> $@;\ grep ' Pool allocate disjoint' Output/$*.poolalloc.bc.info >> $@;\ Modified: poolalloc/trunk/test/TEST.poolalloc.report URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/TEST.poolalloc.report?rev=122694&r1=122693&r2=122694&view=diff ============================================================================== --- poolalloc/trunk/test/TEST.poolalloc.report (original) +++ poolalloc/trunk/test/TEST.poolalloc.report Sun Jan 2 07:34:02 2011 @@ -104,6 +104,7 @@ ["MaxArgs", '([0-9]+).*Maximum function arguments added'], ["UnresolvedCalls",'([0-9]+).*Number of calls that could not be resolved'], #["Nonprofit", '([0-9]+).*Number of DSNodes not profitable'], - [] + [], + ["DynamicPools", '([0-9]+).*DYNAMIC POOLS ALLOCATED FROM ...'], ); From baldrick at free.fr Sun Jan 2 07:38:21 2011 From: baldrick at free.fr (Duncan Sands) Date: Sun, 02 Jan 2011 13:38:21 -0000 Subject: [llvm-commits] [llvm] r122695 - in /llvm/trunk: lib/Transforms/Utils/LoopSimplify.cpp test/Transforms/LoopSimplify/2010-12-26-PHIInfiniteLoop.ll Message-ID: <20110102133821.C5C302A6C12C@llvm.org> Author: baldrick Date: Sun Jan 2 07:38:21 2011 New Revision: 122695 URL: http://llvm.org/viewvc/llvm-project?rev=122695&view=rev Log: Fix PR8702 by not having LoopSimplify claim to preserve LCSSA form. As described in the PR, the pass could break LCSSA form when inserting preheaders. It probably would be easy enough to fix this, but since currently we always go into LCSSA form after running this pass, doing so is not urgent. Added: llvm/trunk/test/Transforms/LoopSimplify/2010-12-26-PHIInfiniteLoop.ll Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=122695&r1=122694&r2=122695&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Sun Jan 2 07:38:21 2011 @@ -91,7 +91,6 @@ AU.addPreserved(); AU.addPreservedID(BreakCriticalEdgesID); // No critical edges added. AU.addPreserved(); - AU.addPreservedID(LCSSAID); } /// verifyAnalysis() - Verify LoopSimplifyForm's guarantees. @@ -269,12 +268,11 @@ PHINode *PN; for (BasicBlock::iterator I = L->getHeader()->begin(); (PN = dyn_cast(I++)); ) - if (Value *V = SimplifyInstruction(PN, 0, DT)) - if (LI->replacementPreservesLCSSAForm(PN, V)) { - if (AA) AA->deleteValue(PN); - PN->replaceAllUsesWith(V); - PN->eraseFromParent(); - } + if (Value *V = SimplifyInstruction(PN, 0, DT)) { + if (AA) AA->deleteValue(PN); + PN->replaceAllUsesWith(V); + PN->eraseFromParent(); + } // If this loop has multiple exits and the exits all go to the same // block, attempt to merge the exits. This helps several passes, such @@ -450,14 +448,13 @@ for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ) { PHINode *PN = cast(I); ++I; - if (Value *V = SimplifyInstruction(PN, 0, DT)) - if (LI->replacementPreservesLCSSAForm(PN, V)) { - // This is a degenerate PHI already, don't modify it! - PN->replaceAllUsesWith(V); - if (AA) AA->deleteValue(PN); - PN->eraseFromParent(); - continue; - } + if (Value *V = SimplifyInstruction(PN, 0, DT)) { + // This is a degenerate PHI already, don't modify it! + PN->replaceAllUsesWith(V); + if (AA) AA->deleteValue(PN); + PN->eraseFromParent(); + continue; + } // Scan this PHI node looking for a use of the PHI node by itself. for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) Added: llvm/trunk/test/Transforms/LoopSimplify/2010-12-26-PHIInfiniteLoop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopSimplify/2010-12-26-PHIInfiniteLoop.ll?rev=122695&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopSimplify/2010-12-26-PHIInfiniteLoop.ll (added) +++ llvm/trunk/test/Transforms/LoopSimplify/2010-12-26-PHIInfiniteLoop.ll Sun Jan 2 07:38:21 2011 @@ -0,0 +1,43 @@ +; RUN: opt < %s -loopsimplify -S +; PR8702 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-freebsd9.0" + +declare void @foo(i32 %x) + +define fastcc void @inm_merge() nounwind { +entry: + br label %for.cond + +for.cond: ; preds = %while.cond36.i, %entry + br i1 undef, label %do.body, label %for.body + +for.body: ; preds = %for.cond + br i1 undef, label %while.cond36.i, label %if.end44 + +if.end44: ; preds = %for.body + %call49 = call fastcc i32 @inm_get_source() + br i1 undef, label %if.end54, label %for.cond64 + +if.end54: ; preds = %if.end44 + br label %while.cond36.i + +while.cond36.i: ; preds = %if.end54, %for.body + br label %for.cond + +for.cond64: ; preds = %if.end88, %for.cond64, %if.end44 + %error.161 = phi i32 [ %error.161, %for.cond64 ], [ %error.161, %if.end88 ], [ %call49, %if.end44 ] + call void @foo(i32 %error.161) + br i1 undef, label %for.cond64, label %if.end88 + +if.end88: ; preds = %for.cond64 + br i1 undef, label %for.cond64, label %if.end98 + +if.end98: ; preds = %if.end88 + unreachable + +do.body: ; preds = %for.cond + unreachable +} + +declare fastcc i32 @inm_get_source() nounwind From aggarwa4 at illinois.edu Sun Jan 2 07:38:27 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Sun, 02 Jan 2011 13:38:27 -0000 Subject: [llvm-commits] [poolalloc] r122696 - /poolalloc/trunk/runtime/FL2Allocator/PoolAllocator.cpp Message-ID: <20110102133827.115322A6C12D@llvm.org> Author: aggarwa4 Date: Sun Jan 2 07:38:26 2011 New Revision: 122696 URL: http://llvm.org/viewvc/llvm-project?rev=122696&view=rev Log: Tracking dynamic pools. Modified: poolalloc/trunk/runtime/FL2Allocator/PoolAllocator.cpp Modified: poolalloc/trunk/runtime/FL2Allocator/PoolAllocator.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/FL2Allocator/PoolAllocator.cpp?rev=122696&r1=122695&r2=122696&view=diff ============================================================================== --- poolalloc/trunk/runtime/FL2Allocator/PoolAllocator.cpp (original) +++ poolalloc/trunk/runtime/FL2Allocator/PoolAllocator.cpp Sun Jan 2 07:38:26 2011 @@ -27,6 +27,8 @@ #define INITIAL_SLAB_SIZE 4096 #define LARGE_SLAB_SIZE 4096 +#define PRINT_NUM_POOLS // Print use dynamic # pools info + #ifndef NDEBUG #define NDEBUG #endif From aggarwa4 at illinois.edu Sun Jan 2 11:40:46 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Sun, 02 Jan 2011 17:40:46 -0000 Subject: [llvm-commits] [poolalloc] r122697 - /poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Message-ID: <20110102174046.9FEC02A6C12C@llvm.org> Author: aggarwa4 Date: Sun Jan 2 11:40:46 2011 New Revision: 122697 URL: http://llvm.org/viewvc/llvm-project?rev=122697&view=rev Log: Recalculate after inlining all callees in an SCCGraph. New knowledge might be gotten. Fixes infinite loop in test/dsa/callgraph/scc3.ll Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=122697&r1=122696&r2=122697&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original) +++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Sun Jan 2 11:40:46 2011 @@ -407,12 +407,14 @@ // // SCCFunctions - Keep track of the functions in the current SCC // - std::vector SCCGraphs; + std::vector SCCFunctions; unsigned SCCSize = 1; const Function *NF = Stack.back(); - ValMap[NF] = ~0U; + if(NF != F) + ValMap[NF] = ~0U; DSGraph* SCCGraph = getDSGraph(*NF); + SCCFunctions.push_back(NF); // // First thing first: collapse all of the DSGraphs into a single graph for @@ -422,7 +424,9 @@ while (NF != F) { Stack.pop_back(); NF = Stack.back(); - ValMap[NF] = ~0U; + SCCFunctions.push_back(NF); + if(NF != F) + ValMap[NF] = ~0U; DSGraph* NFG = getDSGraph(*NF); @@ -455,6 +459,14 @@ DEBUG(errs() << " [BU] Done inlining SCC [" << SCCGraph->getGraphSize() << "+" << SCCGraph->getAuxFunctionCalls().size() << "]\n" << "DONE with SCC #: " << MyID << "\n"); + getAllAuxCallees(SCCGraph, CalleeFunctions); + if (!CalleeFunctions.empty()) { + DEBUG(errs() << "Recalculating SCC Graph " << F->getName() << " due to new knowledge\n"); + ValMap.erase(F); + return calculateGraphs(F, Stack, NextID, ValMap); + } else { + ValMap[F] = ~0U; + } // We never have to revisit "SCC" processed functions... return MyID; From aggarwa4 at illinois.edu Sun Jan 2 11:51:38 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Sun, 02 Jan 2011 17:51:38 -0000 Subject: [llvm-commits] [poolalloc] r122698 - in /poolalloc/trunk/test/dsa/callgraph: scc3.c scc3a.c Message-ID: <20110102175138.4CA892A6C12C@llvm.org> Author: aggarwa4 Date: Sun Jan 2 11:51:38 2011 New Revision: 122698 URL: http://llvm.org/viewvc/llvm-project?rev=122698&view=rev Log: Updated tests. Added: poolalloc/trunk/test/dsa/callgraph/scc3a.c Modified: poolalloc/trunk/test/dsa/callgraph/scc3.c Modified: poolalloc/trunk/test/dsa/callgraph/scc3.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/callgraph/scc3.c?rev=122698&r1=122697&r2=122698&view=diff ============================================================================== --- poolalloc/trunk/test/dsa/callgraph/scc3.c (original) +++ poolalloc/trunk/test/dsa/callgraph/scc3.c Sun Jan 2 11:51:38 2011 @@ -10,12 +10,12 @@ // we inline the SCC graph again, pulling in the unresolved call site // again. This causes an infinte looping in BU. -;XFAIL:* -;RUN: not +//RUN: llvm-gcc %s -c --emit-llvm -o - | \ +//RUN: dsaopt -dsa-bu -dsa-td -disable-output typedef int* (*funcptr)(int *); -static int* A(); +static int* A(void); static int* func(int * arg) { A(); Added: poolalloc/trunk/test/dsa/callgraph/scc3a.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/callgraph/scc3a.c?rev=122698&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/callgraph/scc3a.c (added) +++ poolalloc/trunk/test/dsa/callgraph/scc3a.c Sun Jan 2 11:51:38 2011 @@ -0,0 +1,47 @@ +// similiar to scc3. But with 2 SCCs + +//RUN: llvm-gcc %s -c --emit-llvm -o - | \ +//RUN: dsaopt -dsa-bu -dsa-td -disable-output + + +typedef int* (*funcptr)(int *); + +static int* A1(void); +static int* A2(void); + +static int* func1(int * arg) { + A1(); + return arg; +} +static int* func2(int * arg) { + A2(); + return arg; +} + +static int* C1(funcptr f, int *arg) { + (*f)(arg); +} +static int* C2(funcptr f, int *arg) { + (*f)(arg); +} + +static int *B1() { + func1(A1()); + return C1(func2, A1()); +} +static int *B2() { + func2(A2()); + return C2(func1, A2()); +} +static int* A1() { + return func1(B1()); +} + +static int* A2() { + return func2(B2()); +} + +static int* D() { + A2(); + return A1(); +} From aggarwa4 at illinois.edu Sun Jan 2 11:56:14 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Sun, 02 Jan 2011 17:56:14 -0000 Subject: [llvm-commits] [poolalloc] r122699 - /poolalloc/trunk/test/dsa/callgraph/scc3b.c Message-ID: <20110102175614.D02F02A6C12C@llvm.org> Author: aggarwa4 Date: Sun Jan 2 11:56:14 2011 New Revision: 122699 URL: http://llvm.org/viewvc/llvm-project?rev=122699&view=rev Log: Example for infinite looping in BU. Added: poolalloc/trunk/test/dsa/callgraph/scc3b.c Added: poolalloc/trunk/test/dsa/callgraph/scc3b.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/callgraph/scc3b.c?rev=122699&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/callgraph/scc3b.c (added) +++ poolalloc/trunk/test/dsa/callgraph/scc3b.c Sun Jan 2 11:56:14 2011 @@ -0,0 +1,47 @@ +// A, B, C, func are in an SCC +// C is called indirectly from B +// The indirect call site in C is resolved, once we inline C into B. + +// But since, B and C are in the same graph, inlining C with B, +// merges the arguments for C with the actual arguments passed in +// from B. This makes the function pointer being called to be +// marked incomplete(coming from argument). + +// when we inline the SCCGraph into D(due to call to A), the unresolved +// call site is also inlined. As it is complete and can be resolved +// we inline the SCC graph again, pulling in the unresolved call site +// again. This causes an infinte looping in BU. +// XFAIL:* +// RUN: not +#include + +typedef int* (*funcptr)(int *); + +static int* A(void); +static int* B(void); +static int* func(int*); +static int* C(funcptr f, int *arg) ; + +static int* func(int * arg) { + A(); + return C(NULL, arg); +} + +static int* C(funcptr f, int *arg) { + A(); + func(B()); + (*f)(arg); +} + +static int *B() { + func(A()); + return C(func, A()); +} + +static int* A() { + return C(NULL,func(B())); +} + +static int* D() { + return A(); +} From sabre at nondot.org Sun Jan 2 12:31:38 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 18:31:38 -0000 Subject: [llvm-commits] [llvm] r122700 - in /llvm/trunk/lib/Target: README.txt X86/README.txt Message-ID: <20110102183138.9EAE72A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 12:31:38 2011 New Revision: 122700 URL: http://llvm.org/viewvc/llvm-project?rev=122700&view=rev Log: update a bunch of entries. Modified: llvm/trunk/lib/Target/README.txt llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=122700&r1=122699&r2=122700&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sun Jan 2 12:31:38 2011 @@ -2,38 +2,6 @@ //===---------------------------------------------------------------------===// -We should recognize idioms for add-with-carry and turn it into the appropriate -intrinsics. This example: - -unsigned add32carry(unsigned sum, unsigned x) { - unsigned z = sum + x; - if (sum + x < x) - z++; - return z; -} - -Compiles to: clang t.c -S -o - -O3 -fomit-frame-pointer -m64 -mkernel - -_add32carry: ## @add32carry - addl %esi, %edi - cmpl %esi, %edi - sbbl %eax, %eax - andl $1, %eax - addl %edi, %eax - ret - -with clang, but to: - -_add32carry: - leal (%rsi,%rdi), %eax - cmpl %esi, %eax - adcl $0, %eax - ret - -with gcc. - -//===---------------------------------------------------------------------===// - Dead argument elimination should be enhanced to handle cases when an argument is dead to an externally visible function. Though the argument can't be removed from the externally visible function, the caller doesn't need to pass it in. @@ -82,6 +50,9 @@ return a*b; } +The legalization code for mul-with-overflow needs to be made more robust before +this can be implemented though. + //===---------------------------------------------------------------------===// Get the C front-end to expand hypot(x,y) -> llvm.sqrt(x*x+y*y) when errno and @@ -92,41 +63,6 @@ //===---------------------------------------------------------------------===// -Solve this DAG isel folding deficiency: - -int X, Y; - -void fn1(void) -{ - X = X | (Y << 3); -} - -compiles to - -fn1: - movl Y, %eax - shll $3, %eax - orl X, %eax - movl %eax, X - ret - -The problem is the store's chain operand is not the load X but rather -a TokenFactor of the load X and load Y, which prevents the folding. - -There are two ways to fix this: - -1. The dag combiner can start using alias analysis to realize that y/x - don't alias, making the store to X not dependent on the load from Y. -2. The generated isel could be made smarter in the case it can't - disambiguate the pointers. - -Number 1 is the preferred solution. - -This has been "fixed" by a TableGen hack. But that is a short term workaround -which will be removed once the proper fix is made. - -//===---------------------------------------------------------------------===// - On targets with expensive 64-bit multiply, we could LSR this: for (i = ...; ++i) { @@ -339,14 +275,6 @@ return v ^ (t >> 8); } -Neither is this (very standard idiom): - -int f(int n) -{ - return (((n) << 24) | (((n) & 0xff00) << 8) - | (((n) >> 8) & 0xff00) | ((n) >> 24)); -} - //===---------------------------------------------------------------------===// [LOOP RECOGNITION] @@ -382,9 +310,7 @@ return count; } -This is a form of idiom recognition for loops, the same thing that could be -useful for recognizing memset/memcpy. This sort of thing should be added to the -loop idiom pass. +This sort of thing should be added to the loop idiom pass. //===---------------------------------------------------------------------===// @@ -639,46 +565,21 @@ extern THotKey m_HotKey; THotKey GetHotKey () { return m_HotKey; } -into (-O3 -fno-exceptions -static -fomit-frame-pointer): +into (-m64 -O3 -fno-exceptions -static -fomit-frame-pointer): -__Z9GetHotKeyv: - pushl %esi - movl 8(%esp), %eax - movb _m_HotKey+3, %cl - movb _m_HotKey+4, %dl - movb _m_HotKey+2, %ch - movw _m_HotKey, %si - movw %si, (%eax) - movb %ch, 2(%eax) - movb %cl, 3(%eax) - movb %dl, 4(%eax) - popl %esi - ret $4 - -GCC produces: - -__Z9GetHotKeyv: - movl _m_HotKey, %edx - movl 4(%esp), %eax - movl %edx, (%eax) - movzwl _m_HotKey+4, %edx - movw %dx, 4(%eax) - ret $4 - -The LLVM IR contains the needed alignment info, so we should be able to -merge the loads and stores into 4-byte loads: - - %struct.THotKey = type { i16, i8, i8, i8 } -define void @_Z9GetHotKeyv(%struct.THotKey* sret %agg.result) nounwind { -... - %tmp2 = load i16* getelementptr (@m_HotKey, i32 0, i32 0), align 8 - %tmp5 = load i8* getelementptr (@m_HotKey, i32 0, i32 1), align 2 - %tmp8 = load i8* getelementptr (@m_HotKey, i32 0, i32 2), align 1 - %tmp11 = load i8* getelementptr (@m_HotKey, i32 0, i32 3), align 2 - -Alternatively, we should use a small amount of base-offset alias analysis -to make it so the scheduler doesn't need to hold all the loads in regs at -once. +__Z9GetHotKeyv: ## @_Z9GetHotKeyv + movq _m_HotKey at GOTPCREL(%rip), %rax + movzwl (%rax), %ecx + movzbl 2(%rax), %edx + shlq $16, %rdx + orq %rcx, %rdx + movzbl 3(%rax), %ecx + shlq $24, %rcx + orq %rdx, %rcx + movzbl 4(%rax), %eax + shlq $32, %rax + orq %rcx, %rax + ret //===---------------------------------------------------------------------===// @@ -764,20 +665,6 @@ matching code in dag combine doesn't look through truncates aggressively enough. Here are some testcases reduces from GCC PR17886: -unsigned long long f(unsigned long long x, int y) { - return (x << y) | (x >> 64-y); -} -unsigned f2(unsigned x, int y){ - return (x << y) | (x >> 32-y); -} -unsigned long long f3(unsigned long long x){ - int y = 9; - return (x << y) | (x >> 64-y); -} -unsigned f4(unsigned x){ - int y = 10; - return (x << y) | (x >> 32-y); -} unsigned long long f5(unsigned long long x, unsigned long long y) { return (x << 8) | ((y >> 48) & 0xffull); } @@ -796,11 +683,6 @@ } } -On X86-64, we only handle f2/f3/f4 right. On x86-32, a few of these -generate truly horrible code, instead of using shld and friends. On -ARM, we end up with calls to L___lshrdi3/L___ashldi3 in f, which is -badness. PPC64 misses f, f5 and f6. CellSPU aborts in isel. - //===---------------------------------------------------------------------===// This (and similar related idioms): Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=122700&r1=122699&r2=122700&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Sun Jan 2 12:31:38 2011 @@ -1507,6 +1507,8 @@ RegsForValue::getCopyFromRegs doesn't know how to put an AssertSext on the constructed BUILD_PAIR which represents the cast value. +This can be handled by making CodeGenPrepare sink the cast. + //===---------------------------------------------------------------------===// Test instructions can be eliminated by using EFLAGS values from arithmetic @@ -1847,3 +1849,38 @@ 0 is the only unsigned number < 1. //===---------------------------------------------------------------------===// + +This code: + +%0 = type { i32, i1 } + +define i32 @add32carry(i32 %sum, i32 %x) nounwind readnone ssp { +entry: + %uadd = tail call %0 @llvm.uadd.with.overflow.i32(i32 %sum, i32 %x) + %cmp = extractvalue %0 %uadd, 1 + %inc = zext i1 %cmp to i32 + %add = add i32 %x, %sum + %z.0 = add i32 %add, %inc + ret i32 %z.0 +} + +declare %0 @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone + +compiles to: + +_add32carry: ## @add32carry + addl %esi, %edi + sbbl %ecx, %ecx + movl %edi, %eax + subl %ecx, %eax + ret + +But it could be: + +_add32carry: + leal (%rsi,%rdi), %eax + cmpl %esi, %eax + adcl $0, %eax + ret + +//===---------------------------------------------------------------------===// From sabre at nondot.org Sun Jan 2 12:32:10 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 18:32:10 -0000 Subject: [llvm-commits] [llvm] r122701 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20110102183210.0FEE72A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 12:32:09 2011 New Revision: 122701 URL: http://llvm.org/viewvc/llvm-project?rev=122701&view=rev Log: add a list of opportunities for future improvement. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122701&r1=122700&r2=122701&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 12:32:09 2011 @@ -12,6 +12,27 @@ // performance win. // //===----------------------------------------------------------------------===// +// +// TODO List: +// +// Future loop memory idioms to recognize: +// memcmp, memmove, strlen, etc. +// Future floating point idioms to recognize in -ffast-math mode: +// fpowi +// Future integer operation idioms to recognize: +// ctpop, ctlz, cttz +// +// Beware that isel's default lowering for ctpop is highly inefficient for +// i64 and larger types when i64 is legal and the value has few bits set. It +// would be good to enhance isel to emit a loop for ctpop in this case. +// +// We should enhance the memset/memcpy recognition to handle multiple stores in +// the loop. This would handle things like: +// void foo(_Complex float *P) +// for (i) { __real__(*P) = 0; __imag__(*P) = 0; } +// this is also "Example 2" from http://blog.regehr.org/archives/320 +// +//===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-idiom" #include "llvm/Transforms/Scalar.h" @@ -326,7 +347,7 @@ LoadInst *LI = cast(SI->getValueOperand()); // Okay, we have a strided store "p[i]" of a loaded value. We can turn - // this into a memcmp in the loop preheader now if we want. However, this + // this into a memcpy in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read // or write to the aliased location (including the load feeding the stores). // Check for an alias. From sabre at nondot.org Sun Jan 2 12:35:44 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 2 Jan 2011 10:35:44 -0800 Subject: [llvm-commits] [llvm] r122678 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: References: <20110102033756.880E62A6C12C@llvm.org> Message-ID: <2EFFB65C-BA23-492B-AAE8-9331AF70F717@nondot.org> On Jan 2, 2011, at 2:08 AM, Frits van Bommel wrote: > On Sun, Jan 2, 2011 at 4:37 AM, Chris Lattner wrote: >> +/// processLoopStoreOfLoopLoad - We see a strided store whose value is a >> +/// same-strided load. >> +bool LoopIdiomRecognize:: >> +processLoopStoreOfLoopLoad(StoreInst *SI, unsigned StoreSize, >> + const SCEVAddRecExpr *StoreEv, >> + const SCEVAddRecExpr *LoadEv, >> + const SCEV *BECount) { >> + LoadInst *LI = cast(SI->getValueOperand()); >> + >> + // Okay, we have a strided store "p[i]" of a loaded value. We can turn >> + // this into a memcmp in the loop preheader now if we want. However, this > > s/memcmp/memcpy/ Thanks, fixed in r122701. >> + // would be unsafe to do if there is anything else in the loop that may read >> + // or write to the aliased location (including the load feeding the stores). >> + // Check for an alias. > > TODO: If *only* the load feeding the stores aliases them, turn it into > memmove instead :). (unless the load has other uses) Yep, that occurred to me. This is somewhat tricky to do though, I don't plan to do this in the short term. -Chris From sabre at nondot.org Sun Jan 2 12:45:39 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 18:45:39 -0000 Subject: [llvm-commits] [llvm] r122702 - /llvm/trunk/lib/Transforms/Scalar/LICM.cpp Message-ID: <20110102184539.E91BF2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 12:45:39 2011 New Revision: 122702 URL: http://llvm.org/viewvc/llvm-project?rev=122702&view=rev Log: rip out isExitBlockDominatedByBlockInLoop, calling DomTree::dominates instead. isExitBlockDominatedByBlockInLoop is a relic of the days when domtree was *just* a tree and didn't have DFS numbers. Checking DFS numbers is faster and easier than "limiting the search of the tree". Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=122702&r1=122701&r2=122702&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Sun Jan 2 12:45:39 2011 @@ -137,38 +137,6 @@ return false; } - /// isExitBlockDominatedByBlockInLoop - This method checks to see if the - /// specified exit block of the loop is dominated by the specified block - /// that is in the body of the loop. We use these constraints to - /// dramatically limit the amount of the dominator tree that needs to be - /// searched. - bool isExitBlockDominatedByBlockInLoop(BasicBlock *ExitBlock, - BasicBlock *BlockInLoop) const { - // If the block in the loop is the loop header, it must be dominated! - BasicBlock *LoopHeader = CurLoop->getHeader(); - if (BlockInLoop == LoopHeader) - return true; - - DomTreeNode *BlockInLoopNode = DT->getNode(BlockInLoop); - DomTreeNode *IDom = DT->getNode(ExitBlock); - - // Because the exit block is not in the loop, we know we have to get _at - // least_ its immediate dominator. - IDom = IDom->getIDom(); - - while (IDom && IDom != BlockInLoopNode) { - // If we have got to the header of the loop, then the instructions block - // did not dominate the exit node, so we can't hoist it. - if (IDom->getBlock() == LoopHeader) - return false; - - // Get next Immediate Dominator. - IDom = IDom->getIDom(); - }; - - return true; - } - /// sink - When an instruction is found to only be used outside of the loop, /// this function moves it to the exit blocks and patches up SSA form as /// needed. @@ -480,7 +448,7 @@ // enough that we handle it as a special (more efficient) case. It is more // efficient to handle because there are no PHI nodes that need to be placed. if (ExitBlocks.size() == 1) { - if (!isExitBlockDominatedByBlockInLoop(ExitBlocks[0], I.getParent())) { + if (!DT->dominates(I.getParent(), ExitBlocks[0])) { // Instruction is not used, just delete it. CurAST->deleteValue(&I); // If I has users in unreachable blocks, eliminate. @@ -531,7 +499,7 @@ for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { BasicBlock *ExitBlock = ExitBlocks[i]; - if (!isExitBlockDominatedByBlockInLoop(ExitBlock, InstOrigBB)) + if (!DT->dominates(InstOrigBB, ExitBlock)) continue; // Insert the code after the last PHI node. @@ -622,10 +590,9 @@ SmallVector ExitBlocks; CurLoop->getExitBlocks(ExitBlocks); - // For each exit block, get the DT node and walk up the DT until the - // instruction's basic block is found or we exit the loop. + // Verify that the block dominates each of the exit blocks of the loop. for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) - if (!isExitBlockDominatedByBlockInLoop(ExitBlocks[i], Inst.getParent())) + if (!DT->dominates(Inst.getParent(), ExitBlocks[i])) return false; return true; From sabre at nondot.org Sun Jan 2 12:53:09 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 18:53:09 -0000 Subject: [llvm-commits] [llvm] r122703 - /llvm/trunk/lib/Transforms/Scalar/LICM.cpp Message-ID: <20110102185309.0F6082A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 12:53:08 2011 New Revision: 122703 URL: http://llvm.org/viewvc/llvm-project?rev=122703&view=rev Log: make inSubLoop much more efficient. Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=122703&r1=122702&r2=122703&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Sun Jan 2 12:53:08 2011 @@ -131,10 +131,7 @@ /// bool inSubLoop(BasicBlock *BB) { assert(CurLoop->contains(BB) && "Only valid if BB is IN the loop"); - for (Loop::iterator I = CurLoop->begin(), E = CurLoop->end(); I != E; ++I) - if ((*I)->contains(BB)) - return true; // A subloop actually contains this block! - return false; + return LI->getLoopFor(BB) != CurLoop; } /// sink - When an instruction is found to only be used outside of the loop, From sabre at nondot.org Sun Jan 2 13:01:03 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 19:01:03 -0000 Subject: [llvm-commits] [llvm] r122704 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110102190103.6EECD2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 13:01:03 2011 New Revision: 122704 URL: http://llvm.org/viewvc/llvm-project?rev=122704&view=rev Log: enhance loop idiom recognition to scan *all* unconditionally executed blocks in a loop, instead of just the header block. This makes it more aggressive, able to handle Duncan's Ada examples. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/LoopIdiom/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122704&r1=122703&r2=122704&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 13:01:03 2011 @@ -58,6 +58,7 @@ class LoopIdiomRecognize : public LoopPass { Loop *CurLoop; const TargetData *TD; + DominatorTree *DT; ScalarEvolution *SE; public: static char ID; @@ -66,6 +67,8 @@ } bool runOnLoop(Loop *L, LPPassManager &LPM); + bool runOnLoopBlock(BasicBlock *BB, const SCEV *BECount, + SmallVectorImpl &ExitBlocks); bool processLoopStore(StoreInst *SI, const SCEV *BECount); @@ -93,6 +96,7 @@ AU.addRequired(); AU.addPreserved(); AU.addPreserved(); + AU.addRequired(); } }; } @@ -101,6 +105,7 @@ INITIALIZE_PASS_BEGIN(LoopIdiomRecognize, "loop-idiom", "Recognize loop idioms", false, false) INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(LoopSimplify) INITIALIZE_PASS_DEPENDENCY(LCSSA) INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) @@ -157,17 +162,42 @@ // We require target data for now. TD = getAnalysisIfAvailable(); if (TD == 0) return false; + + DT = &getAnalysis(); + LoopInfo &LI = getAnalysis(); - // TODO: We currently only scan the header of the loop, because it is the only - // part that is known to execute and we don't want to make a conditional store - // into an unconditional one in the preheader. However, there can be diamonds - // and other things in the loop that would make other blocks "always executed" - // we should get the full set and scan each block. - BasicBlock *BB = L->getHeader(); - DEBUG(dbgs() << "loop-idiom Scanning: F[" << BB->getParent()->getName() - << "] Loop %" << BB->getName() << "\n"); + SmallVector ExitBlocks; + CurLoop->getUniqueExitBlocks(ExitBlocks); bool MadeChange = false; + // Scan all the blocks in the loop that are not in subloops. + for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; + ++BI) { + // Ignore blocks in subloops. + if (LI.getLoopFor(*BI) != CurLoop) + continue; + + MadeChange |= runOnLoopBlock(*BI, BECount, ExitBlocks); + } + return MadeChange; +} + +/// runOnLoopBlock - Process the specified block, which lives in a counted loop +/// with the specified backedge count. This block is known to be in the current +/// loop and not in any subloops. +bool LoopIdiomRecognize::runOnLoopBlock(BasicBlock *BB, const SCEV *BECount, + SmallVectorImpl &ExitBlocks) { + // We can only promote stores in this block if they are unconditionally + // executed in the loop. For a block to be unconditionally executed, it has + // to dominate all the exit blocks of the loop. Verify this now. + for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) + if (!DT->dominates(BB, ExitBlocks[i])) + return false; + + DEBUG(dbgs() << "loop-idiom Scanning: F[" << BB->getParent()->getName() + << "] Loop %" << BB->getName() << "\n"); + + bool MadeChange = false; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { // Look for store instructions, which may be memsets. StoreInst *SI = dyn_cast(I++); @@ -187,6 +217,7 @@ return MadeChange; } + /// scanBlock - Look over a block to see if we can promote anything out of it. bool LoopIdiomRecognize::processLoopStore(StoreInst *SI, const SCEV *BECount) { Value *StoredVal = SI->getValueOperand(); Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122704&r1=122703&r2=122704&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sun Jan 2 13:01:03 2011 @@ -165,4 +165,27 @@ } +; This is a loop that was rotated but where the blocks weren't merged. This +; shouldn't perturb us. +define void @test7(i8* %Base, i64 %Size) nounwind ssp { +bb.nph: ; preds = %entry + br label %for.body + +for.body: ; preds = %bb.nph, %for.body + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body.cont ] + br label %for.body.cont +for.body.cont: + %I.0.014 = getelementptr i8* %Base, i64 %indvar + store i8 0, i8* %I.0.014, align 1 + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, %Size + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK: @test7 +; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false) +; CHECK-NOT: store +} + From nicholas at mxc.ca Sun Jan 2 13:16:44 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 02 Jan 2011 19:16:44 -0000 Subject: [llvm-commits] [llvm] r122705 - /llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Message-ID: <20110102191644.B762A2A6C12C@llvm.org> Author: nicholas Date: Sun Jan 2 13:16:44 2011 New Revision: 122705 URL: http://llvm.org/viewvc/llvm-project?rev=122705&view=rev Log: Also remove functions that use complex constant expressions in terms of another function. Modified: llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Modified: llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp?rev=122705&r1=122704&r2=122705&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Sun Jan 2 13:16:44 2011 @@ -696,11 +696,24 @@ // RemoveUsers - For each instruction used by the value, Remove() the function // that contains the instruction. This should happen right before a call to RAUW. void MergeFunctions::RemoveUsers(Value *V) { - for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); - UI != UE; ++UI) { - Use &U = UI.getUse(); - if (Instruction *I = dyn_cast(U.getUser())) { - Remove(I->getParent()->getParent()); + std::vector Worklist; + Worklist.push_back(V); + while (!Worklist.empty()) { + Value *V = Worklist.back(); + Worklist.pop_back(); + + for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); + UI != UE; ++UI) { + Use &U = UI.getUse(); + if (Instruction *I = dyn_cast(U.getUser())) { + Remove(I->getParent()->getParent()); + } else if (isa(U.getUser())) { + // do nothing + } else if (Constant *C = dyn_cast(U.getUser())) { + for (Value::use_iterator CUI = C->use_begin(), CUE = C->use_end(); + CUI != CUE; ++CUI) + Worklist.push_back(*CUI); + } } } } From nicholas at mxc.ca Sun Jan 2 13:19:33 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 02 Jan 2011 11:19:33 -0800 Subject: [llvm-commits] [llvm] r122677 - /llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp In-Reply-To: References: <20110102024633.BD7A32A6C12C@llvm.org> Message-ID: <4D20CFC5.7010902@mxc.ca> On 01/02/2011 02:27 AM, Frits van Bommel wrote: > On Sun, Jan 2, 2011 at 3:46 AM, Nick Lewycky wrote: >> +// RemoveUsers - For each instruction used by the value, Remove() the function >> +// that contains the instruction. This should happen right before a call to RAUW. >> +void MergeFunctions::RemoveUsers(Value *V) { >> + for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); >> + UI != UE; ++UI) { >> + Use&U = UI.getUse(); >> + if (Instruction *I = dyn_cast(U.getUser())) { >> + Remove(I->getParent()->getParent()); >> + } >> + } >> } > > This doesn't handle uses in constant expressions, which can also make > two functions suddenly compare equal when they change. Thanks! I didn't need it in the case where we only update direct callers but forgot to add it after some refactoring. Nick From ofv at wanadoo.es Sun Jan 2 13:32:32 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sun, 02 Jan 2011 19:32:32 -0000 Subject: [llvm-commits] [llvm] r122706 - /llvm/trunk/lib/Target/X86/CMakeLists.txt Message-ID: <20110102193232.2A5322A6C12C@llvm.org> Author: ofv Date: Sun Jan 2 13:32:31 2011 New Revision: 122706 URL: http://llvm.org/viewvc/llvm-project?rev=122706&view=rev Log: A workaround for a bug in cmake 2.8.3 diagnosed on PR 8885. Modified: llvm/trunk/lib/Target/X86/CMakeLists.txt Modified: llvm/trunk/lib/Target/X86/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/CMakeLists.txt?rev=122706&r1=122705&r2=122706&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/X86/CMakeLists.txt Sun Jan 2 13:32:31 2011 @@ -41,6 +41,11 @@ ) if( CMAKE_CL_64 ) + # A workaround for a bug in cmake 2.8.3. See PR 8885. + if( CMAKE_VERSION STREQUAL "2.8.3" ) + include(CMakeDetermineCompilerId) + endif() + # end of workaround. enable_language(ASM_MASM) ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/X86CompilationCallback_Win64.obj From benny.kra at googlemail.com Sun Jan 2 13:44:58 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sun, 02 Jan 2011 19:44:58 -0000 Subject: [llvm-commits] [llvm] r122707 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/X86/memset-2.ll Message-ID: <20110102194458.C7C462A6C12C@llvm.org> Author: d0k Date: Sun Jan 2 13:44:58 2011 New Revision: 122707 URL: http://llvm.org/viewvc/llvm-project?rev=122707&view=rev Log: Lower the i8 extension in memset to a multiply instead of a potentially long series of shifts and ors. We could implement a DAGCombine to turn x * 0x0101 back into logic operations on targets that doesn't support the multiply or it is slow (p4) if someone cares enough. Example code: void test(char *s, int a) { __builtin_memset(s, a, 4); } before: _test: ## @test movzbl 8(%esp), %eax movl %eax, %ecx shll $8, %ecx orl %eax, %ecx movl %ecx, %eax shll $16, %eax orl %ecx, %eax movl 4(%esp), %ecx movl %eax, 4(%ecx) movl %eax, (%ecx) ret after: _test: ## @test movzbl 8(%esp), %eax imull $16843009, %eax, %eax ## imm = 0x1010101 movl 4(%esp), %ecx movl %eax, 4(%ecx) movl %eax, (%ecx) ret Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/test/CodeGen/X86/memset-2.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=122707&r1=122706&r2=122707&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sun Jan 2 13:44:58 2011 @@ -3132,6 +3132,17 @@ &ArgChains[0], ArgChains.size()); } +/// SplatByte - Distribute ByteVal over NumBits bits. +static APInt SplatByte(unsigned NumBits, uint8_t ByteVal) { + APInt Val = APInt(NumBits, ByteVal); + unsigned Shift = 8; + for (unsigned i = NumBits; i > 8; i >>= 1) { + Val = (Val << Shift) | Val; + Shift <<= 1; + } + return Val; +} + /// getMemsetValue - Vectorized representation of the memset value /// operand. static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG, @@ -3140,27 +3151,18 @@ unsigned NumBits = VT.getScalarType().getSizeInBits(); if (ConstantSDNode *C = dyn_cast(Value)) { - APInt Val = APInt(NumBits, C->getZExtValue() & 255); - unsigned Shift = 8; - for (unsigned i = NumBits; i > 8; i >>= 1) { - Val = (Val << Shift) | Val; - Shift <<= 1; - } + APInt Val = SplatByte(NumBits, C->getZExtValue() & 255); if (VT.isInteger()) return DAG.getConstant(Val, VT); return DAG.getConstantFP(APFloat(Val), VT); } - const TargetLowering &TLI = DAG.getTargetLoweringInfo(); Value = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, Value); - unsigned Shift = 8; - for (unsigned i = NumBits; i > 8; i >>= 1) { - Value = DAG.getNode(ISD::OR, dl, VT, - DAG.getNode(ISD::SHL, dl, VT, Value, - DAG.getConstant(Shift, - TLI.getShiftAmountTy())), - Value); - Shift <<= 1; + if (NumBits > 8) { + // Use a multiplication with 0x010101... to extend the input to the + // required length. + APInt Magic = SplatByte(NumBits, 0x01); + Value = DAG.getNode(ISD::MUL, dl, VT, Value, DAG.getConstant(Magic, VT)); } return Value; Modified: llvm/trunk/test/CodeGen/X86/memset-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset-2.ll?rev=122707&r1=122706&r2=122707&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memset-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/memset-2.ll Sun Jan 2 13:44:58 2011 @@ -17,3 +17,14 @@ call void @llvm.memset.i32( i8* undef, i8 %c, i32 76, i32 1 ) nounwind unreachable } + +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind + +define void @t3(i8* nocapture %s, i8 %a) nounwind { +entry: + tail call void @llvm.memset.p0i8.i32(i8* %s, i8 %a, i32 8, i32 1, i1 false) + ret void +; CHECK: t3: +; CHECK: imull $16843009 +} + From benny.kra at googlemail.com Sun Jan 2 13:57:05 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sun, 02 Jan 2011 19:57:05 -0000 Subject: [llvm-commits] [llvm] r122710 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/X86/README-X86-64.txt test/CodeGen/X86/memset-2.ll Message-ID: <20110102195705.B5CCF2A6C12C@llvm.org> Author: d0k Date: Sun Jan 2 13:57:05 2011 New Revision: 122710 URL: http://llvm.org/viewvc/llvm-project?rev=122710&view=rev Log: Try to reuse the value when lowering memset. This allows us to compile: void test(char *s, int a) { __builtin_memset(s, a, 15); } into 1 mul + 3 stores instead of 3 muls + 3 stores. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/Target/X86/README-X86-64.txt llvm/trunk/test/CodeGen/X86/memset-2.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=122710&r1=122709&r2=122710&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sun Jan 2 13:57:05 2011 @@ -3527,16 +3527,34 @@ SmallVector OutChains; uint64_t DstOff = 0; unsigned NumMemOps = MemOps.size(); + + // Find the largest store and generate the bit pattern for it. + EVT LargestVT = MemOps[0]; + for (unsigned i = 1; i < NumMemOps; i++) + if (MemOps[i].bitsGT(LargestVT)) + LargestVT = MemOps[i]; + SDValue MemSetValue = getMemsetValue(Src, LargestVT, DAG, dl); + for (unsigned i = 0; i < NumMemOps; i++) { EVT VT = MemOps[i]; - unsigned VTSize = VT.getSizeInBits() / 8; - SDValue Value = getMemsetValue(Src, VT, DAG, dl); + + // If this store is smaller than the largest store see whether we can get + // the smaller value for free with a truncate. + SDValue Value = MemSetValue; + if (VT.bitsLT(LargestVT)) { + if (!LargestVT.isVector() && !VT.isVector() && + TLI.isTruncateFree(LargestVT, VT)) + Value = DAG.getNode(ISD::TRUNCATE, dl, VT, MemSetValue); + else + Value = getMemsetValue(Src, VT, DAG, dl); + } + assert(Value.getValueType() == VT && "Value with wrong type."); SDValue Store = DAG.getStore(Chain, dl, Value, getMemBasePlusOffset(Dst, DstOff, DAG), DstPtrInfo.getWithOffset(DstOff), isVol, false, Align); OutChains.push_back(Store); - DstOff += VTSize; + DstOff += VT.getSizeInBits() / 8; } return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Modified: llvm/trunk/lib/Target/X86/README-X86-64.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README-X86-64.txt?rev=122710&r1=122709&r2=122710&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README-X86-64.txt (original) +++ llvm/trunk/lib/Target/X86/README-X86-64.txt Sun Jan 2 13:57:05 2011 @@ -41,50 +41,6 @@ //===---------------------------------------------------------------------===// -Poor codegen: - -int X[2]; -int b; -void test(void) { - memset(X, b, 2*sizeof(X[0])); -} - -llc: - movq _b at GOTPCREL(%rip), %rax - movzbq (%rax), %rax - movq %rax, %rcx - shlq $8, %rcx - orq %rax, %rcx - movq %rcx, %rax - shlq $16, %rax - orq %rcx, %rax - movq %rax, %rcx - shlq $32, %rcx - movq _X at GOTPCREL(%rip), %rdx - orq %rax, %rcx - movq %rcx, (%rdx) - ret - -gcc: - movq _b at GOTPCREL(%rip), %rax - movabsq $72340172838076673, %rdx - movzbq (%rax), %rax - imulq %rdx, %rax - movq _X at GOTPCREL(%rip), %rdx - movq %rax, (%rdx) - ret - -And the codegen is even worse for the following -(from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33103): - void fill1(char *s, int a) - { - __builtin_memset(s, a, 15); - } - -For this version, we duplicate the computation of the constant to store. - -//===---------------------------------------------------------------------===// - It's not possible to reference AH, BH, CH, and DH registers in an instruction requiring REX prefix. However, divb and mulb both produce results in AH. If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a Modified: llvm/trunk/test/CodeGen/X86/memset-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset-2.ll?rev=122710&r1=122709&r2=122710&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memset-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/memset-2.ll Sun Jan 2 13:57:05 2011 @@ -28,3 +28,12 @@ ; CHECK: imull $16843009 } +define void @t4(i8* nocapture %s, i8 %a) nounwind { +entry: + tail call void @llvm.memset.p0i8.i32(i8* %s, i8 %a, i32 15, i32 1, i1 false) + ret void +; CHECK: t4: +; CHECK: imull $16843009 +; CHECK-NOT: imul +; CHECK: ret +} From sabre at nondot.org Sun Jan 2 14:24:21 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 20:24:21 -0000 Subject: [llvm-commits] [llvm] r122711 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110102202422.03FC72A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 14:24:21 2011 New Revision: 122711 URL: http://llvm.org/viewvc/llvm-project?rev=122711&view=rev Log: If a loop iterates exactly once (has backedge count = 0) then don't mess with it. We'd rather peel/unroll it than convert all of its stores into memsets. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/LoopIdiom/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122711&r1=122710&r2=122711&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 14:24:21 2011 @@ -159,6 +159,12 @@ const SCEV *BECount = SE->getBackedgeTakenCount(L); if (isa(BECount)) return false; + // If this loop executes exactly one time, then it should be peeled, not + // optimized by this pass. + if (const SCEVConstant *BECst = dyn_cast(BECount)) + if (BECst->getValue()->getValue() == 0) + return false; + // We require target data for now. TD = getAnalysisIfAvailable(); if (TD == 0) return false; Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122711&r1=122710&r2=122711&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sun Jan 2 14:24:21 2011 @@ -188,4 +188,22 @@ ; CHECK-NOT: store } +; This is a loop should not be transformed, it only executes one iteration. +define void @test8(i64* %Ptr, i64 %Size) nounwind ssp { +bb.nph: ; preds = %entry + br label %for.body + +for.body: ; preds = %bb.nph, %for.body + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] + %PI = getelementptr i64* %Ptr, i64 %indvar + store i64 0, i64 *%PI + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, 1 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK: @test8 +; CHECK: store i64 0, i64* %PI +} From sabre at nondot.org Sun Jan 2 15:14:18 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 21:14:18 -0000 Subject: [llvm-commits] [llvm] r122712 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110102211418.D851C2A6C12D@llvm.org> Author: lattner Date: Sun Jan 2 15:14:18 2011 New Revision: 122712 URL: http://llvm.org/viewvc/llvm-project?rev=122712&view=rev Log: fix a miscompilation of tramp3d-v4: when forming a memcpy, we have to make sure that the loop we're promoting into a memcpy doesn't mutate the input of the memcpy. Before we were just checking that the dest of the memcpy wasn't mod/ref'd by the loop. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/LoopIdiom/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122712&r1=122711&r2=122712&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 15:14:18 2011 @@ -175,6 +175,10 @@ SmallVector ExitBlocks; CurLoop->getUniqueExitBlocks(ExitBlocks); + DEBUG(dbgs() << "loop-idiom Scanning: F[" + << L->getHeader()->getParent()->getName() + << "] Loop %" << L->getHeader()->getName() << "\n"); + bool MadeChange = false; // Scan all the blocks in the loop that are not in subloops. for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; @@ -200,9 +204,6 @@ if (!DT->dominates(BB, ExitBlocks[i])) return false; - DEBUG(dbgs() << "loop-idiom Scanning: F[" << BB->getParent()->getName() - << "] Loop %" << BB->getName() << "\n"); - bool MadeChange = false; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { // Look for store instructions, which may be memsets. @@ -276,10 +277,11 @@ return false; } -/// mayLoopModRefLocation - Return true if the specified loop might do a load or -/// store to the same location that the specified store could store to, which is -/// a loop-strided access. -static bool mayLoopModRefLocation(Value *Ptr, Loop *L, const SCEV *BECount, +/// mayLoopAccessLocation - Return true if the specified loop might access the +/// specified pointer location, which is a loop-strided access. The 'Access' +/// argument specifies what the verboten forms of access are (read or write). +static bool mayLoopAccessLocation(Value *Ptr,AliasAnalysis::ModRefResult Access, + Loop *L, const SCEV *BECount, unsigned StoreSize, AliasAnalysis &AA, StoreInst *IgnoredStore) { // Get the location that may be stored across the loop. Since the access is @@ -302,7 +304,7 @@ ++BI) for (BasicBlock::iterator I = (*BI)->begin(), E = (*BI)->end(); I != E; ++I) if (&*I != IgnoredStore && - AA.getModRefInfo(I, StoreLoc) != AliasAnalysis::NoModRef) + (AA.getModRefInfo(I, StoreLoc) & Access)) return true; return false; @@ -323,7 +325,8 @@ // this into a memset in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read // or write to the aliased location. Check for an alias. - if (mayLoopModRefLocation(SI->getPointerOperand(), CurLoop, BECount, + if (mayLoopAccessLocation(SI->getPointerOperand(), AliasAnalysis::ModRef, + CurLoop, BECount, StoreSize, getAnalysis(), SI)) return false; @@ -386,10 +389,18 @@ // Okay, we have a strided store "p[i]" of a loaded value. We can turn // this into a memcpy in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read - // or write to the aliased location (including the load feeding the stores). + // or write to the stored location (including the load feeding the stores). // Check for an alias. - if (mayLoopModRefLocation(SI->getPointerOperand(), CurLoop, BECount, - StoreSize, getAnalysis(), SI)) + if (mayLoopAccessLocation(SI->getPointerOperand(), AliasAnalysis::ModRef, + CurLoop, BECount, StoreSize, + getAnalysis(), SI)) + return false; + + // For a memcpy, we have to make sure that the input array is not being + // mutated by the loop. + if (mayLoopAccessLocation(LI->getPointerOperand(), AliasAnalysis::Mod, + CurLoop, BECount, StoreSize, + getAnalysis(), SI)) return false; // Okay, everything looks good, insert the memcpy. Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122712&r1=122711&r2=122712&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sun Jan 2 15:14:18 2011 @@ -207,3 +207,36 @@ ; CHECK: store i64 0, i64* %PI } +declare i8* @external(i8*) + +;; This cannot be transformed into a memcpy, because the read-from location is +;; mutated by the loop. +define void @test9(i64 %Size) nounwind ssp { +bb.nph: + %Base = alloca i8, i32 10000 + %Dest = alloca i8, i32 10000 + + %BaseAlias = call i8* @external(i8* %Base) + br label %for.body + +for.body: ; preds = %bb.nph, %for.body + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] + %I.0.014 = getelementptr i8* %Base, i64 %indvar + %DestI = getelementptr i8* %Dest, i64 %indvar + %V = load i8* %I.0.014, align 1 + store i8 %V, i8* %DestI, align 1 + + ;; This store can clobber the input. + store i8 4, i8* %BaseAlias + + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, %Size + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK: @test9 +; CHECK-NOT: llvm.memcpy +; CHECK: ret void +} + From sabre at nondot.org Sun Jan 2 15:47:06 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 21:47:06 -0000 Subject: [llvm-commits] [llvm] r122713 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/EarlyCSE.cpp lib/Transforms/Scalar/Scalar.cpp Message-ID: <20110102214706.2F96B2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 15:47:05 2011 New Revision: 122713 URL: http://llvm.org/viewvc/llvm-project?rev=122713&view=rev Log: sketch out a new early cse pass. No functionality yet. Added: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/include/llvm/InitializePasses.h llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/include/llvm/Transforms/Scalar.h llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Modified: llvm/trunk/include/llvm/InitializePasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=122713&r1=122712&r2=122713&view=diff ============================================================================== --- llvm/trunk/include/llvm/InitializePasses.h (original) +++ llvm/trunk/include/llvm/InitializePasses.h Sun Jan 2 15:47:05 2011 @@ -92,6 +92,7 @@ void initializeDominanceFrontierPass(PassRegistry&); void initializeDominatorTreePass(PassRegistry&); void initializeEdgeProfilerPass(PassRegistry&); +void initializeEarlyCSEPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&); void initializeFindUsedTypesPass(PassRegistry&); void initializeFunctionAttrsPass(PassRegistry&); Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=122713&r1=122712&r2=122713&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Sun Jan 2 15:47:05 2011 @@ -128,6 +128,7 @@ (void) llvm::createUnifyFunctionExitNodesPass(); (void) llvm::createInstCountPass(); (void) llvm::createCodeGenPreparePass(); + (void) llvm::createEarlyCSEPass(); (void) llvm::createGVNPass(); (void) llvm::createMemCpyOptPass(); (void) llvm::createLoopDeletionPass(); Modified: llvm/trunk/include/llvm/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=122713&r1=122712&r2=122713&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm/Transforms/Scalar.h Sun Jan 2 15:47:05 2011 @@ -260,6 +260,13 @@ //===----------------------------------------------------------------------===// // +// EarlyCSE - This pass performs a simple and fast CSE pass over the dominator +// tree. +// +FunctionPass *createEarlyCSEPass(); + +//===----------------------------------------------------------------------===// +// // GVN - This pass performs global value numbering and redundant load // elimination cotemporaneously. // Added: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122713&view=auto ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (added) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 15:47:05 2011 @@ -0,0 +1,62 @@ +//===- EarlyCSE.cpp - Simple and fast CSE pass ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass performs a simple dominator tree walk that eliminates trivially +// redundant instructions. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "early-cse" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Pass.h" +using namespace llvm; + +namespace { +/// EarlyCSE - This pass does a simple depth-first walk over the dominator +/// tree, eliminating trivially redundant instructions and using instsimplify +/// to canonicalize things as it goes. It is intended to be fast and catch +/// obvious cases so that instcombine and other passes are more effective. It +/// is expected that a later pass of GVN will catch the interesting/hard +/// cases. +class EarlyCSE : public FunctionPass { +public: + static char ID; + explicit EarlyCSE() + : FunctionPass(ID) { + initializeEarlyCSEPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F); + +private: + // This transformation requires dominator postdominator info + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesCFG(); + } +}; +} + +char EarlyCSE::ID = 0; + +// createEarlyCSEPass - The public interface to this file. +FunctionPass *llvm::createEarlyCSEPass() { + return new EarlyCSE(); +} + +INITIALIZE_PASS_BEGIN(EarlyCSE, "early-cse", "Early CSE", false, false) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false) + +bool EarlyCSE::runOnFunction(Function &F) { + DominatorTree &DT = getAnalysis(); + (void)DT; + return false; +} Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=122713&r1=122712&r2=122713&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Sun Jan 2 15:47:05 2011 @@ -36,6 +36,7 @@ initializeDSEPass(Registry); initializeGEPSplitterPass(Registry); initializeGVNPass(Registry); + initializeEarlyCSEPass(Registry); initializeIndVarSimplifyPass(Registry); initializeJumpThreadingPass(Registry); initializeLICMPass(Registry); From sabre at nondot.org Sun Jan 2 16:09:34 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 22:09:34 -0000 Subject: [llvm-commits] [llvm] r122714 - in /llvm/trunk: include/llvm/Analysis/ lib/Analysis/ lib/CodeGen/AsmPrinter/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ tools/opt/ Message-ID: <20110102220934.60D822A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 16:09:33 2011 New Revision: 122714 URL: http://llvm.org/viewvc/llvm-project?rev=122714&view=rev Log: split dom frontier handling stuff out to its own DominanceFrontier header, so that Dominators.h is *just* domtree. Also prune #includes a bit. Added: llvm/trunk/include/llvm/Analysis/DominanceFrontier.h Modified: llvm/trunk/include/llvm/Analysis/Dominators.h llvm/trunk/include/llvm/Analysis/LoopInfo.h llvm/trunk/include/llvm/Analysis/PostDominators.h llvm/trunk/lib/Analysis/DomPrinter.cpp llvm/trunk/lib/Analysis/IVUsers.cpp llvm/trunk/lib/Analysis/LiveValues.cpp llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp llvm/trunk/lib/Analysis/PHITransAddr.cpp llvm/trunk/lib/Analysis/PostDominators.cpp llvm/trunk/lib/Analysis/RegionInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp llvm/trunk/lib/Transforms/Utils/LCSSA.cpp llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp llvm/trunk/lib/VMCore/Dominators.cpp llvm/trunk/tools/opt/GraphPrinters.cpp Added: llvm/trunk/include/llvm/Analysis/DominanceFrontier.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominanceFrontier.h?rev=122714&view=auto ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominanceFrontier.h (added) +++ llvm/trunk/include/llvm/Analysis/DominanceFrontier.h Sun Jan 2 16:09:33 2011 @@ -0,0 +1,218 @@ +//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the DominanceFrontier class, which calculate and holds the +// dominance frontier for a function. +// +// This should be considered deprecated, don't add any more uses of this data +// structure. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H +#define LLVM_ANALYSIS_DOMINANCEFRONTIER_H + +#include "llvm/Analysis/Dominators.h" +#include +#include + +namespace llvm { + +//===----------------------------------------------------------------------===// +/// DominanceFrontierBase - Common base class for computing forward and inverse +/// dominance frontiers for a function. +/// +class DominanceFrontierBase : public FunctionPass { +public: + typedef std::set DomSetType; // Dom set for a bb + typedef std::map DomSetMapType; // Dom set map +protected: + DomSetMapType Frontiers; + std::vector Roots; + const bool IsPostDominators; + +public: + DominanceFrontierBase(char &ID, bool isPostDom) + : FunctionPass(ID), IsPostDominators(isPostDom) {} + + /// getRoots - Return the root blocks of the current CFG. This may include + /// multiple blocks if we are computing post dominators. For forward + /// dominators, this will always be a single block (the entry node). + /// + inline const std::vector &getRoots() const { return Roots; } + + /// isPostDominator - Returns true if analysis based of postdoms + /// + bool isPostDominator() const { return IsPostDominators; } + + virtual void releaseMemory() { Frontiers.clear(); } + + // Accessor interface: + typedef DomSetMapType::iterator iterator; + typedef DomSetMapType::const_iterator const_iterator; + iterator begin() { return Frontiers.begin(); } + const_iterator begin() const { return Frontiers.begin(); } + iterator end() { return Frontiers.end(); } + const_iterator end() const { return Frontiers.end(); } + iterator find(BasicBlock *B) { return Frontiers.find(B); } + const_iterator find(BasicBlock *B) const { return Frontiers.find(B); } + + iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) { + assert(find(BB) == end() && "Block already in DominanceFrontier!"); + return Frontiers.insert(std::make_pair(BB, frontier)).first; + } + + /// removeBlock - Remove basic block BB's frontier. + void removeBlock(BasicBlock *BB) { + assert(find(BB) != end() && "Block is not in DominanceFrontier!"); + for (iterator I = begin(), E = end(); I != E; ++I) + I->second.erase(BB); + Frontiers.erase(BB); + } + + void addToFrontier(iterator I, BasicBlock *Node) { + assert(I != end() && "BB is not in DominanceFrontier!"); + I->second.insert(Node); + } + + void removeFromFrontier(iterator I, BasicBlock *Node) { + assert(I != end() && "BB is not in DominanceFrontier!"); + assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB"); + I->second.erase(Node); + } + + /// compareDomSet - Return false if two domsets match. Otherwise + /// return true; + bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const { + std::set tmpSet; + for (DomSetType::const_iterator I = DS2.begin(), + E = DS2.end(); I != E; ++I) + tmpSet.insert(*I); + + for (DomSetType::const_iterator I = DS1.begin(), + E = DS1.end(); I != E; ) { + BasicBlock *Node = *I++; + + if (tmpSet.erase(Node) == 0) + // Node is in DS1 but not in DS2. + return true; + } + + if (!tmpSet.empty()) + // There are nodes that are in DS2 but not in DS1. + return true; + + // DS1 and DS2 matches. + return false; + } + + /// compare - Return true if the other dominance frontier base matches + /// this dominance frontier base. Otherwise return false. + bool compare(DominanceFrontierBase &Other) const { + DomSetMapType tmpFrontiers; + for (DomSetMapType::const_iterator I = Other.begin(), + E = Other.end(); I != E; ++I) + tmpFrontiers.insert(std::make_pair(I->first, I->second)); + + for (DomSetMapType::iterator I = tmpFrontiers.begin(), + E = tmpFrontiers.end(); I != E; ) { + BasicBlock *Node = I->first; + const_iterator DFI = find(Node); + if (DFI == end()) + return true; + + if (compareDomSet(I->second, DFI->second)) + return true; + + ++I; + tmpFrontiers.erase(Node); + } + + if (!tmpFrontiers.empty()) + return true; + + return false; + } + + /// print - Convert to human readable form + /// + virtual void print(raw_ostream &OS, const Module* = 0) const; + + /// dump - Dump the dominance frontier to dbgs(). + void dump() const; +}; + + +//===------------------------------------- +/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is +/// used to compute a forward dominator frontiers. +/// +class DominanceFrontier : public DominanceFrontierBase { +public: + static char ID; // Pass ID, replacement for typeid + DominanceFrontier() : + DominanceFrontierBase(ID, false) { + initializeDominanceFrontierPass(*PassRegistry::getPassRegistry()); + } + + BasicBlock *getRoot() const { + assert(Roots.size() == 1 && "Should always have entry node!"); + return Roots[0]; + } + + virtual bool runOnFunction(Function &) { + Frontiers.clear(); + DominatorTree &DT = getAnalysis(); + Roots = DT.getRoots(); + assert(Roots.size() == 1 && "Only one entry block for forward domfronts!"); + calculate(DT, DT[Roots[0]]); + return false; + } + + virtual void verifyAnalysis() const; + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + } + + /// splitBlock - BB is split and now it has one successor. Update dominance + /// frontier to reflect this change. + void splitBlock(BasicBlock *BB); + + /// BasicBlock BB's new dominator is NewBB. Update BB's dominance frontier + /// to reflect this change. + void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB, + DominatorTree *DT) { + // NewBB is now dominating BB. Which means BB's dominance + // frontier is now part of NewBB's dominance frontier. However, BB + // itself is not member of NewBB's dominance frontier. + DominanceFrontier::iterator NewDFI = find(NewBB); + DominanceFrontier::iterator DFI = find(BB); + // If BB was an entry block then its frontier is empty. + if (DFI == end()) + return; + DominanceFrontier::DomSetType BBSet = DFI->second; + for (DominanceFrontier::DomSetType::iterator BBSetI = BBSet.begin(), + BBSetE = BBSet.end(); BBSetI != BBSetE; ++BBSetI) { + BasicBlock *DFMember = *BBSetI; + // Insert only if NewBB dominates DFMember. + if (!DT->dominates(NewBB, DFMember)) + NewDFI->second.insert(DFMember); + } + NewDFI->second.erase(BB); + } + + const DomSetType &calculate(const DominatorTree &DT, + const DomTreeNode *Node); +}; + +} // End llvm namespace + +#endif Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Sun Jan 2 16:09:33 2011 @@ -7,14 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file defines the following classes: -// 1. DominatorTree: Represent dominators as an explicit tree structure. -// 2. DominanceFrontier: Calculate and hold the dominance frontier for a -// function. -// -// These data structures are listed in increasing order of complexity. It -// takes longer to calculate the dominator frontier, for example, than the -// DominatorTree mapping. +// This file defines the DominatorTree class, which provides fast and efficient +// dominance queries. // //===----------------------------------------------------------------------===// @@ -23,19 +17,15 @@ #include "llvm/Pass.h" #include "llvm/Function.h" -#include "llvm/Instructions.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" #include -#include -#include namespace llvm { @@ -891,196 +881,6 @@ }; -//===----------------------------------------------------------------------===// -/// DominanceFrontierBase - Common base class for computing forward and inverse -/// dominance frontiers for a function. -/// -class DominanceFrontierBase : public FunctionPass { -public: - typedef std::set DomSetType; // Dom set for a bb - typedef std::map DomSetMapType; // Dom set map -protected: - DomSetMapType Frontiers; - std::vector Roots; - const bool IsPostDominators; - -public: - DominanceFrontierBase(char &ID, bool isPostDom) - : FunctionPass(ID), IsPostDominators(isPostDom) {} - - /// getRoots - Return the root blocks of the current CFG. This may include - /// multiple blocks if we are computing post dominators. For forward - /// dominators, this will always be a single block (the entry node). - /// - inline const std::vector &getRoots() const { return Roots; } - - /// isPostDominator - Returns true if analysis based of postdoms - /// - bool isPostDominator() const { return IsPostDominators; } - - virtual void releaseMemory() { Frontiers.clear(); } - - // Accessor interface: - typedef DomSetMapType::iterator iterator; - typedef DomSetMapType::const_iterator const_iterator; - iterator begin() { return Frontiers.begin(); } - const_iterator begin() const { return Frontiers.begin(); } - iterator end() { return Frontiers.end(); } - const_iterator end() const { return Frontiers.end(); } - iterator find(BasicBlock *B) { return Frontiers.find(B); } - const_iterator find(BasicBlock *B) const { return Frontiers.find(B); } - - iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) { - assert(find(BB) == end() && "Block already in DominanceFrontier!"); - return Frontiers.insert(std::make_pair(BB, frontier)).first; - } - - /// removeBlock - Remove basic block BB's frontier. - void removeBlock(BasicBlock *BB) { - assert(find(BB) != end() && "Block is not in DominanceFrontier!"); - for (iterator I = begin(), E = end(); I != E; ++I) - I->second.erase(BB); - Frontiers.erase(BB); - } - - void addToFrontier(iterator I, BasicBlock *Node) { - assert(I != end() && "BB is not in DominanceFrontier!"); - I->second.insert(Node); - } - - void removeFromFrontier(iterator I, BasicBlock *Node) { - assert(I != end() && "BB is not in DominanceFrontier!"); - assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB"); - I->second.erase(Node); - } - - /// compareDomSet - Return false if two domsets match. Otherwise - /// return true; - bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const { - std::set tmpSet; - for (DomSetType::const_iterator I = DS2.begin(), - E = DS2.end(); I != E; ++I) - tmpSet.insert(*I); - - for (DomSetType::const_iterator I = DS1.begin(), - E = DS1.end(); I != E; ) { - BasicBlock *Node = *I++; - - if (tmpSet.erase(Node) == 0) - // Node is in DS1 but not in DS2. - return true; - } - - if (!tmpSet.empty()) - // There are nodes that are in DS2 but not in DS1. - return true; - - // DS1 and DS2 matches. - return false; - } - - /// compare - Return true if the other dominance frontier base matches - /// this dominance frontier base. Otherwise return false. - bool compare(DominanceFrontierBase &Other) const { - DomSetMapType tmpFrontiers; - for (DomSetMapType::const_iterator I = Other.begin(), - E = Other.end(); I != E; ++I) - tmpFrontiers.insert(std::make_pair(I->first, I->second)); - - for (DomSetMapType::iterator I = tmpFrontiers.begin(), - E = tmpFrontiers.end(); I != E; ) { - BasicBlock *Node = I->first; - const_iterator DFI = find(Node); - if (DFI == end()) - return true; - - if (compareDomSet(I->second, DFI->second)) - return true; - - ++I; - tmpFrontiers.erase(Node); - } - - if (!tmpFrontiers.empty()) - return true; - - return false; - } - - /// print - Convert to human readable form - /// - virtual void print(raw_ostream &OS, const Module* = 0) const; - - /// dump - Dump the dominance frontier to dbgs(). - void dump() const; -}; - - -//===------------------------------------- -/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is -/// used to compute a forward dominator frontiers. -/// -class DominanceFrontier : public DominanceFrontierBase { -public: - static char ID; // Pass ID, replacement for typeid - DominanceFrontier() : - DominanceFrontierBase(ID, false) { - initializeDominanceFrontierPass(*PassRegistry::getPassRegistry()); - } - - BasicBlock *getRoot() const { - assert(Roots.size() == 1 && "Should always have entry node!"); - return Roots[0]; - } - - virtual bool runOnFunction(Function &) { - Frontiers.clear(); - DominatorTree &DT = getAnalysis(); - Roots = DT.getRoots(); - assert(Roots.size() == 1 && "Only one entry block for forward domfronts!"); - calculate(DT, DT[Roots[0]]); - return false; - } - - virtual void verifyAnalysis() const; - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); - } - - /// splitBlock - BB is split and now it has one successor. Update dominance - /// frontier to reflect this change. - void splitBlock(BasicBlock *BB); - - /// BasicBlock BB's new dominator is NewBB. Update BB's dominance frontier - /// to reflect this change. - void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB, - DominatorTree *DT) { - // NewBB is now dominating BB. Which means BB's dominance - // frontier is now part of NewBB's dominance frontier. However, BB - // itself is not member of NewBB's dominance frontier. - DominanceFrontier::iterator NewDFI = find(NewBB); - DominanceFrontier::iterator DFI = find(BB); - // If BB was an entry block then its frontier is empty. - if (DFI == end()) - return; - DominanceFrontier::DomSetType BBSet = DFI->second; - for (DominanceFrontier::DomSetType::iterator BBSetI = BBSet.begin(), - BBSetE = BBSet.end(); BBSetI != BBSetE; ++BBSetI) { - BasicBlock *DFMember = *BBSetI; - // Insert only if NewBB dominates DFMember. - if (!DT->dominates(NewBB, DFMember)) - NewDFI->second.insert(DFMember); - } - NewDFI->second.erase(BB); - } - - const DomSetType &calculate(const DominatorTree &DT, - const DomTreeNode *Node); -}; - - } // End llvm namespace #endif Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Sun Jan 2 16:09:33 2011 @@ -41,6 +41,7 @@ #include "llvm/Support/CFG.h" #include "llvm/Support/raw_ostream.h" #include +#include namespace llvm { @@ -54,6 +55,7 @@ class DominatorTree; class LoopInfo; class Loop; +class PHINode; template class LoopInfoBase; template class LoopBase; Modified: llvm/trunk/include/llvm/Analysis/PostDominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PostDominators.h?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PostDominators.h (original) +++ llvm/trunk/include/llvm/Analysis/PostDominators.h Sun Jan 2 16:09:33 2011 @@ -14,7 +14,7 @@ #ifndef LLVM_ANALYSIS_POST_DOMINATORS_H #define LLVM_ANALYSIS_POST_DOMINATORS_H -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" namespace llvm { Modified: llvm/trunk/lib/Analysis/DomPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DomPrinter.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DomPrinter.cpp (original) +++ llvm/trunk/lib/Analysis/DomPrinter.cpp Sun Jan 2 16:09:33 2011 @@ -19,8 +19,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/DomPrinter.h" - -#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/DOTGraphTraitsPass.h" #include "llvm/Analysis/PostDominators.h" Modified: llvm/trunk/lib/Analysis/IVUsers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IVUsers.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IVUsers.cpp (original) +++ llvm/trunk/lib/Analysis/IVUsers.cpp Sun Jan 2 16:09:33 2011 @@ -21,6 +21,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Assembly/Writer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" Modified: llvm/trunk/lib/Analysis/LiveValues.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LiveValues.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LiveValues.cpp (original) +++ llvm/trunk/lib/Analysis/LiveValues.cpp Sun Jan 2 16:09:33 2011 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/LiveValues.h" +#include "llvm/Instructions.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" using namespace llvm; Modified: llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp Sun Jan 2 16:09:33 2011 @@ -28,6 +28,7 @@ #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Instructions.h" #include "llvm/Operator.h" #include "llvm/Support/Allocator.h" Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Sun Jan 2 16:09:33 2011 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/PHITransAddr.h" +#include "llvm/Instructions.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Support/Debug.h" Modified: llvm/trunk/lib/Analysis/PostDominators.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PostDominators.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PostDominators.cpp (original) +++ llvm/trunk/lib/Analysis/PostDominators.cpp Sun Jan 2 16:09:33 2011 @@ -19,6 +19,7 @@ #include "llvm/Support/Debug.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SetOperations.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Analysis/DominatorInternals.h" using namespace llvm; Modified: llvm/trunk/lib/Analysis/RegionInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/RegionInfo.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/RegionInfo.cpp (original) +++ llvm/trunk/lib/Analysis/RegionInfo.cpp Sun Jan 2 16:09:33 2011 @@ -16,8 +16,8 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Assembly/Writer.h" #define DEBUG_TYPE "region" #include "llvm/Support/Debug.h" Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Sun Jan 2 16:09:33 2011 @@ -38,6 +38,7 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Assembly/Writer.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/ErrorHandling.h" Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sun Jan 2 16:09:33 2011 @@ -33,6 +33,7 @@ #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/PHITransAddr.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Sun Jan 2 16:09:33 2011 @@ -17,6 +17,7 @@ #define DEBUG_TYPE "loop-delete" #include "llvm/Transforms/Scalar.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/SmallVector.h" Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sun Jan 2 16:09:33 2011 @@ -15,7 +15,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Function.h" #include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Transforms/Utils/Local.h" Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sun Jan 2 16:09:33 2011 @@ -63,6 +63,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpander.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/SmallBitVector.h" Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sun Jan 2 16:09:33 2011 @@ -30,7 +30,7 @@ #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/Pass.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Sun Jan 2 16:09:33 2011 @@ -20,7 +20,7 @@ #include "llvm/Type.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Scalar.h" Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Sun Jan 2 16:09:33 2011 @@ -19,7 +19,7 @@ #define DEBUG_TYPE "break-crit-edges" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Function.h" Modified: llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp Sun Jan 2 16:09:33 2011 @@ -14,7 +14,7 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/BasicBlock.h" #include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" using namespace llvm; Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Sun Jan 2 16:09:33 2011 @@ -67,10 +67,7 @@ AU.setPreservesCFG(); AU.addRequired(); - AU.addPreserved(); - AU.addPreserved(); AU.addRequired(); - AU.addPreserved(); AU.addPreservedID(LoopSimplifyID); AU.addPreserved(); } Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Sun Jan 2 16:09:33 2011 @@ -46,7 +46,7 @@ #include "llvm/LLVMContext.h" #include "llvm/Type.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" @@ -163,9 +163,8 @@ for (SmallPtrSet::iterator I = BadPreds.begin(), E = BadPreds.end(); I != E; ++I) { - DEBUG(dbgs() << "LoopSimplify: Deleting edge from dead predecessor "; - WriteAsOperand(dbgs(), *I, false); - dbgs() << "\n"); + DEBUG(dbgs() << "LoopSimplify: Deleting edge from dead predecessor " + << (*I)->getName() << "\n"); // Inform each successor of each dead pred. for (succ_iterator SI = succ_begin(*I), SE = succ_end(*I); SI != SE; ++SI) @@ -190,9 +189,8 @@ if (BI->isConditional()) { if (UndefValue *Cond = dyn_cast(BI->getCondition())) { - DEBUG(dbgs() << "LoopSimplify: Resolving \"br i1 undef\" to exit in "; - WriteAsOperand(dbgs(), *I, false); - dbgs() << "\n"); + DEBUG(dbgs() << "LoopSimplify: Resolving \"br i1 undef\" to exit in " + << (*I)->getName() << "\n"); BI->setCondition(ConstantInt::get(Cond->getType(), !L->contains(BI->getSuccessor(0)))); @@ -324,10 +322,8 @@ // Success. The block is now dead, so remove it from the loop, // update the dominator tree and dominance frontier, and delete it. - - DEBUG(dbgs() << "LoopSimplify: Eliminating exiting block "; - WriteAsOperand(dbgs(), ExitingBlock, false); - dbgs() << "\n"); + DEBUG(dbgs() << "LoopSimplify: Eliminating exiting block " + << ExitingBlock->getName() << "\n"); assert(pred_begin(ExitingBlock) == pred_end(ExitingBlock)); Changed = true; @@ -384,9 +380,8 @@ SplitBlockPredecessors(Header, &OutsideBlocks[0], OutsideBlocks.size(), ".preheader", this); - DEBUG(dbgs() << "LoopSimplify: Creating pre-header "; - WriteAsOperand(dbgs(), NewBB, false); - dbgs() << "\n"); + DEBUG(dbgs() << "LoopSimplify: Creating pre-header " << NewBB->getName() + << "\n"); // Make sure that NewBB is put someplace intelligent, which doesn't mess up // code layout too horribly. @@ -415,10 +410,8 @@ LoopBlocks.size(), ".loopexit", this); - DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block "; - WriteAsOperand(dbgs(), NewBB, false); - dbgs() << "\n"); - + DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block " + << NewBB->getName() << "\n"); return NewBB; } @@ -649,9 +642,8 @@ Header->getName()+".backedge", F); BranchInst *BETerminator = BranchInst::Create(Header, BEBlock); - DEBUG(dbgs() << "LoopSimplify: Inserting unique backedge block "; - WriteAsOperand(dbgs(), BEBlock, false); - dbgs() << "\n"); + DEBUG(dbgs() << "LoopSimplify: Inserting unique backedge block " + << BEBlock->getName() << "\n"); // Move the new backedge block to right after the last backedge block. Function::iterator InsertPos = BackedgeBlocks.back(); ++InsertPos; Modified: llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp Sun Jan 2 16:09:33 2011 @@ -16,7 +16,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Instructions.h" #include "llvm/Function.h" #include "llvm/ADT/Statistic.h" Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Sun Jan 2 16:09:33 2011 @@ -26,7 +26,7 @@ #include "llvm/Metadata.h" #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/DebugInfo.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" Modified: llvm/trunk/lib/VMCore/Dominators.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Dominators.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Dominators.cpp (original) +++ llvm/trunk/lib/VMCore/Dominators.cpp Sun Jan 2 16:09:33 2011 @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" @@ -23,6 +23,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/DominatorInternals.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Instructions.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/CommandLine.h" Modified: llvm/trunk/tools/opt/GraphPrinters.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/GraphPrinters.cpp?rev=122714&r1=122713&r2=122714&view=diff ============================================================================== --- llvm/trunk/tools/opt/GraphPrinters.cpp (original) +++ llvm/trunk/tools/opt/GraphPrinters.cpp Sun Jan 2 16:09:33 2011 @@ -18,7 +18,7 @@ #include "llvm/Pass.h" #include "llvm/Value.h" #include "llvm/Analysis/CallGraph.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Support/ToolOutputFile.h" using namespace llvm; @@ -61,8 +61,7 @@ static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { if (Node->getFunction()) return ((Value*)Node->getFunction())->getName(); - else - return "external node"; + return "external node"; } }; } @@ -109,10 +108,8 @@ } virtual bool runOnFunction(Function &F) { - DominatorTree &DT = getAnalysis(); - DT.dump(); - DominanceFrontier &DF = getAnalysis(); - DF.dump(); + getAnalysis().dump(); + getAnalysis().dump(); return false; } }; From sabre at nondot.org Sun Jan 2 17:04:14 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 23:04:14 -0000 Subject: [llvm-commits] [llvm] r122715 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/ test/Transforms/EarlyCSE/basic.ll test/Transforms/EarlyCSE/dg.exp Message-ID: <20110102230414.B3B9B2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 17:04:14 2011 New Revision: 122715 URL: http://llvm.org/viewvc/llvm-project?rev=122715&view=rev Log: Enhance earlycse to do CSE of casts, instsimplify and die. Add a testcase. Added: llvm/trunk/test/Transforms/EarlyCSE/ llvm/trunk/test/Transforms/EarlyCSE/basic.ll llvm/trunk/test/Transforms/EarlyCSE/dg.exp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122715&r1=122714&r2=122715&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 17:04:14 2011 @@ -14,11 +14,84 @@ #define DEBUG_TYPE "early-cse" #include "llvm/Transforms/Scalar.h" -#include "llvm/Analysis/Dominators.h" #include "llvm/Pass.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Transforms/Utils/Local.h" +#include "llvm/ADT/ScopedHashTable.h" using namespace llvm; namespace { + /// InstValue - Instances of this struct represent available values in the + /// scoped hash table. + struct InstValue { + Instruction *Inst; + + bool isSentinel() const { + return Inst == DenseMapInfo::getEmptyKey() || + Inst == DenseMapInfo::getTombstoneKey(); + } + + static bool canHandle(Instruction *Inst) { + return isa(Inst); + } + + static InstValue get(Instruction *I) { + InstValue X; X.Inst = I; + assert((X.isSentinel() || canHandle(I)) && "Inst can't be handled!"); + return X; + } + }; +} + +namespace llvm { +// InstValue is POD. +template<> struct isPodLike { + static const bool value = true; +}; + +template<> struct DenseMapInfo { + static inline InstValue getEmptyKey() { + return InstValue::get(DenseMapInfo::getEmptyKey()); + } + static inline InstValue getTombstoneKey() { + return InstValue::get(DenseMapInfo::getTombstoneKey()); + } + static unsigned getHashValue(InstValue Val); + static bool isEqual(InstValue LHS, InstValue RHS); +}; +} + +unsigned getHash(const void *V) { + return DenseMapInfo::getHashValue(V); +} + +unsigned DenseMapInfo::getHashValue(InstValue Val) { + Instruction *Inst = Val.Inst; + unsigned Res = 0; + if (CastInst *CI = dyn_cast(Inst)) + Res = getHash(CI->getOperand(0)) ^ getHash(CI->getType()); + else + assert(0 && "Unhandled instruction kind"); + + return (Res << 1) ^ Inst->getOpcode(); +} + +bool DenseMapInfo::isEqual(InstValue LHS, InstValue RHS) { + Instruction *LHSI = LHS.Inst, *RHSI = RHS.Inst; + + if (LHS.isSentinel() || RHS.isSentinel()) + return LHSI == RHSI; + + if (LHSI->getOpcode() != RHSI->getOpcode()) return false; + return LHSI->isIdenticalTo(RHSI); +} + + +namespace { + /// EarlyCSE - This pass does a simple depth-first walk over the dominator /// tree, eliminating trivially redundant instructions and using instsimplify /// to canonicalize things as it goes. It is intended to be fast and catch @@ -27,6 +100,10 @@ /// cases. class EarlyCSE : public FunctionPass { public: + const TargetData *TD; + DominatorTree *DT; + ScopedHashTable *AvailableValues; + static char ID; explicit EarlyCSE() : FunctionPass(ID) { @@ -36,6 +113,9 @@ bool runOnFunction(Function &F); private: + + bool processNode(DomTreeNode *Node); + // This transformation requires dominator postdominator info virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -55,8 +135,65 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false) +// FIXME: Should bump pointer allocate entries in scoped hash table. + +bool EarlyCSE::processNode(DomTreeNode *Node) { + // Define a scope in the scoped hash table. + ScopedHashTableScope Scope(*AvailableValues); + + BasicBlock *BB = Node->getBlock(); + + bool Changed = false; + + // See if any instructions in the block can be eliminated. If so, do it. If + // not, add them to AvailableValues. + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { + Instruction *Inst = I++; + + // Dead instructions should just be removed. + if (isInstructionTriviallyDead(Inst)) { + Inst->eraseFromParent(); + Changed = true; + continue; + } + + // If the instruction can be simplified (e.g. X+0 = X) then replace it with + // its simpler value. + if (Value *V = SimplifyInstruction(Inst, TD, DT)) { + Inst->replaceAllUsesWith(V); + Inst->eraseFromParent(); + Changed = true; + continue; + } + + // If this instruction is something that we can't value number, ignore it. + if (!InstValue::canHandle(Inst)) + continue; + + // See if the instruction has an available value. If so, use it. + if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) { + Inst->replaceAllUsesWith(V); + Inst->eraseFromParent(); + Changed = true; + continue; + } + + // Otherwise, just remember that this value is available. + AvailableValues->insert(InstValue::get(Inst), Inst); + } + + + for (DomTreeNode::iterator I = Node->begin(), E = Node->end(); I != E; ++I) + Changed |= processNode(*I); + return Changed; +} + + bool EarlyCSE::runOnFunction(Function &F) { - DominatorTree &DT = getAnalysis(); - (void)DT; - return false; + TD = getAnalysisIfAvailable(); + DT = &getAnalysis(); + ScopedHashTable AVTable; + AvailableValues = &AVTable; + return processNode(DT->getRootNode()); } + Added: llvm/trunk/test/Transforms/EarlyCSE/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/basic.ll?rev=122715&view=auto ============================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/basic.ll (added) +++ llvm/trunk/test/Transforms/EarlyCSE/basic.ll Sun Jan 2 17:04:14 2011 @@ -0,0 +1,21 @@ +; RUN: opt < %s -S -early-cse | FileCheck %s + + +; CHECK: @test1 +define void @test1(i8 %V, i32 *%P) { + %A = bitcast i64 42 to double ;; dead + %B = add i32 4, 19 ;; constant folds + store i32 %B, i32* %P + + ; CHECK-NEXT: store i32 23, i32* %P + + %C = zext i8 %V to i32 + %D = zext i8 %V to i32 ;; CSE + volatile store i32 %C, i32* %P + volatile store i32 %D, i32* %P + + ; CHECK-NEXT: %C = zext i8 %V to i32 + ; CHECK-NEXT: volatile store i32 %C + ; CHECK-NEXT: volatile store i32 %C + ret void +} Added: llvm/trunk/test/Transforms/EarlyCSE/dg.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/dg.exp?rev=122715&view=auto ============================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/dg.exp (added) +++ llvm/trunk/test/Transforms/EarlyCSE/dg.exp Sun Jan 2 17:04:14 2011 @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.ll]] From sabre at nondot.org Sun Jan 2 17:19:45 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 23:19:45 -0000 Subject: [llvm-commits] [llvm] r122716 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/EarlyCSE/basic.ll Message-ID: <20110102231945.6A42B2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 17:19:45 2011 New Revision: 122716 URL: http://llvm.org/viewvc/llvm-project?rev=122716&view=rev Log: add DEBUG and -stats output to earlycse. Teach it to CSE the rest of the non-side-effecting instructions. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/EarlyCSE/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122716&r1=122715&r2=122716&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 17:19:45 2011 @@ -14,15 +14,21 @@ #define DEBUG_TYPE "early-cse" #include "llvm/Transforms/Scalar.h" +#include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Support/Debug.h" #include "llvm/ADT/ScopedHashTable.h" +#include "llvm/ADT/Statistic.h" using namespace llvm; +STATISTIC(NumSimplify, "Number of insts simplified or DCE'd"); +STATISTIC(NumCSE, "Number of insts CSE'd"); + namespace { /// InstValue - Instances of this struct represent available values in the /// scoped hash table. @@ -35,7 +41,11 @@ } static bool canHandle(Instruction *Inst) { - return isa(Inst); + return isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst); } static InstValue get(Instruction *I) { @@ -73,8 +83,24 @@ unsigned Res = 0; if (CastInst *CI = dyn_cast(Inst)) Res = getHash(CI->getOperand(0)) ^ getHash(CI->getType()); - else - assert(0 && "Unhandled instruction kind"); + else if (BinaryOperator *BO = dyn_cast(Inst)) + Res = getHash(BO->getOperand(0)) ^ (getHash(BO->getOperand(1)) << 1); + else if (GetElementPtrInst *GEP = dyn_cast(Inst)) { + Res = getHash(CI->getOperand(0)); + for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) + Res ^= getHash(CI->getOperand(i)) << i; + } else if (CmpInst *CI = dyn_cast(Inst)) { + Res = getHash(CI->getOperand(0)) ^ (getHash(CI->getOperand(1)) << 1) ^ + CI->getPredicate(); + } else { + assert((isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst)) && + "Unhandled instruction kind"); + Res = getHash(CI->getType()) << 4; + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) + Res ^= getHash(CI->getOperand(i)) << i; + } return (Res << 1) ^ Inst->getOpcode(); } @@ -152,17 +178,21 @@ // Dead instructions should just be removed. if (isInstructionTriviallyDead(Inst)) { + DEBUG(dbgs() << "EarlyCSE DCE: " << *Inst << '\n'); Inst->eraseFromParent(); Changed = true; + ++NumSimplify; continue; } // If the instruction can be simplified (e.g. X+0 = X) then replace it with // its simpler value. if (Value *V = SimplifyInstruction(Inst, TD, DT)) { + DEBUG(dbgs() << "EarlyCSE Simplify: " << *Inst << " to: " << *V << '\n'); Inst->replaceAllUsesWith(V); Inst->eraseFromParent(); Changed = true; + ++NumSimplify; continue; } @@ -172,9 +202,11 @@ // See if the instruction has an available value. If so, use it. if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) { + DEBUG(dbgs() << "EarlyCSE CSE: " << *Inst << " to: " << *V << '\n'); Inst->replaceAllUsesWith(V); Inst->eraseFromParent(); Changed = true; + ++NumCSE; continue; } Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122716&r1=122715&r2=122716&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 17:19:45 2011 @@ -31,7 +31,10 @@ // void foo(_Complex float *P) // for (i) { __real__(*P) = 0; __imag__(*P) = 0; } // this is also "Example 2" from http://blog.regehr.org/archives/320 -// +// +// This could regognize common matrix multiplies and dot product idioms and +// replace them with calls to BLAS (if linked in??). +// //===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-idiom" @@ -49,8 +52,6 @@ #include "llvm/ADT/Statistic.h" using namespace llvm; -// TODO: Recognize "N" size array multiplies: replace with call to blas or -// something. STATISTIC(NumMemSet, "Number of memset's formed from loop stores"); STATISTIC(NumMemCpy, "Number of memcpy's formed from loop load+stores"); Modified: llvm/trunk/test/Transforms/EarlyCSE/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/basic.ll?rev=122716&r1=122715&r2=122716&view=diff ============================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/basic.ll (original) +++ llvm/trunk/test/Transforms/EarlyCSE/basic.ll Sun Jan 2 17:19:45 2011 @@ -6,16 +6,27 @@ %A = bitcast i64 42 to double ;; dead %B = add i32 4, 19 ;; constant folds store i32 %B, i32* %P - ; CHECK-NEXT: store i32 23, i32* %P %C = zext i8 %V to i32 %D = zext i8 %V to i32 ;; CSE volatile store i32 %C, i32* %P volatile store i32 %D, i32* %P - ; CHECK-NEXT: %C = zext i8 %V to i32 ; CHECK-NEXT: volatile store i32 %C ; CHECK-NEXT: volatile store i32 %C + + %E = add i32 %C, %C + %F = add i32 %C, %C + volatile store i32 %E, i32* %P + volatile store i32 %F, i32* %P + ; CHECK-NEXT: %E = add i32 %C, %C + ; CHECK-NEXT: volatile store i32 %E + ; CHECK-NEXT: volatile store i32 %E + + %G = add nuw i32 %C, %C ;; not a CSE with E + volatile store i32 %G, i32* %P + ; CHECK-NEXT: %G = add nuw i32 %C, %C + ; CHECK-NEXT: volatile store i32 %G ret void } From sabre at nondot.org Sun Jan 2 17:22:48 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 23:22:48 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r122717 - /llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Message-ID: <20110102232248.B01412A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 17:22:48 2011 New Revision: 122717 URL: http://llvm.org/viewvc/llvm-project?rev=122717&view=rev Log: link in new pass. Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp?rev=122717&r1=122716&r2=122717&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Sun Jan 2 17:22:48 2011 @@ -61,6 +61,7 @@ llvm::createDefaultScheduler(NULL, llvm::CodeGenOpt::Default); llvm::createGVNPass(); + llvm::createEarlyCSEPass(); llvm::createLoopRotatePass(); llvm::createLICMPass(); llvm::createSCCPPass(); From sabre at nondot.org Sun Jan 2 17:29:58 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 02 Jan 2011 23:29:58 -0000 Subject: [llvm-commits] [llvm] r122718 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Message-ID: <20110102232958.BF77A2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 17:29:58 2011 New Revision: 122718 URL: http://llvm.org/viewvc/llvm-project?rev=122718&view=rev Log: fix some pastos Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122718&r1=122717&r2=122718&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 17:29:58 2011 @@ -86,9 +86,9 @@ else if (BinaryOperator *BO = dyn_cast(Inst)) Res = getHash(BO->getOperand(0)) ^ (getHash(BO->getOperand(1)) << 1); else if (GetElementPtrInst *GEP = dyn_cast(Inst)) { - Res = getHash(CI->getOperand(0)); + Res = getHash(GEP->getOperand(0)); for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) - Res ^= getHash(CI->getOperand(i)) << i; + Res ^= getHash(GEP->getOperand(i)) << i; } else if (CmpInst *CI = dyn_cast(Inst)) { Res = getHash(CI->getOperand(0)) ^ (getHash(CI->getOperand(1)) << 1) ^ CI->getPredicate(); @@ -97,9 +97,9 @@ isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst)) && "Unhandled instruction kind"); - Res = getHash(CI->getType()) << 4; + Res = getHash(Inst->getType()) << 4; for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) - Res ^= getHash(CI->getOperand(i)) << i; + Res ^= getHash(Inst->getOperand(i)) << i; } return (Res << 1) ^ Inst->getOpcode(); From fvbommel at gmail.com Sun Jan 2 17:42:42 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 3 Jan 2011 00:42:42 +0100 Subject: [llvm-commits] [llvm] r122715 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/ test/Transforms/EarlyCSE/basic.ll test/Transforms/EarlyCSE/dg.exp In-Reply-To: <20110102230414.B3B9B2A6C12C@llvm.org> References: <20110102230414.B3B9B2A6C12C@llvm.org> Message-ID: On Mon, Jan 3, 2011 at 12:04 AM, Chris Lattner wrote: > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan ?2 17:04:14 2011 > @@ -14,11 +14,84 @@ > > ?#define DEBUG_TYPE "early-cse" > ?#include "llvm/Transforms/Scalar.h" > -#include "llvm/Analysis/Dominators.h" > ?#include "llvm/Pass.h" > +#include "llvm/Analysis/Dominators.h" > +#include "llvm/Analysis/InstructionSimplify.h" > +#include "llvm/Analysis/InstructionSimplify.h" Duplicate import. From fvbommel at gmail.com Sun Jan 2 18:02:16 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 3 Jan 2011 01:02:16 +0100 Subject: [llvm-commits] [llvm] r122716 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/EarlyCSE/basic.ll In-Reply-To: <20110102231945.6A42B2A6C12C@llvm.org> References: <20110102231945.6A42B2A6C12C@llvm.org> Message-ID: On Mon, Jan 3, 2011 at 12:19 AM, Chris Lattner wrote: > + ?else if (GetElementPtrInst *GEP = dyn_cast(Inst)) { > + ? ?Res = getHash(CI->getOperand(0)); > + ? ?for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) > + ? ? ?Res ^= getHash(CI->getOperand(i)) << i; > + ?} else if (CmpInst *CI = dyn_cast(Inst)) { > + ? ? ?Res = getHash(CI->getOperand(0)) ^ (getHash(CI->getOperand(1)) << 1) ^ > + ? ? ? ? CI->getPredicate(); > + ?} else { > + ? ?assert((isa(Inst) || isa(Inst) || > + ? ? ? ? ? ?isa(Inst) || isa(Inst) || > + ? ? ? ? ? ?isa(Inst) || isa(Inst)) && > + ? ? ? ? ? "Unhandled instruction kind"); > + ? ?Res = getHash(CI->getType()) << 4; > + ? ?for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) > + ? ? ?Res ^= getHash(CI->getOperand(i)) << i; > + ?} ExtractValue/InsertValue indices aren't operands, so they're not taken into account here. Also, it might make sense to simplify the code by handling operands more generically instead of duplicating the code in each if clause. > +// This could regognize common matrix multiplies and dot product idioms and > +// replace them with calls to BLAS (if linked in??). s/regognize/recognize/ From zwarich at apple.com Sun Jan 2 18:25:16 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 03 Jan 2011 00:25:16 -0000 Subject: [llvm-commits] [llvm] r122719 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/CMakeLists.txt lib/Transforms/Scalar/LoopInstSimplify.cpp lib/Transforms/Scalar/Scalar.cpp Message-ID: <20110103002516.F06722A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 18:25:16 2011 New Revision: 122719 URL: http://llvm.org/viewvc/llvm-project?rev=122719&view=rev Log: Add a new loop-instsimplify pass, with the intention of replacing the instance of instcombine that is currently in the middle of the loop pass pipeline. This commit only checks in the pass; it will hopefully be enabled by default later. Added: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Modified: llvm/trunk/include/llvm/InitializePasses.h llvm/trunk/include/llvm/Transforms/Scalar.h llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Modified: llvm/trunk/include/llvm/InitializePasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=122719&r1=122718&r2=122719&view=diff ============================================================================== --- llvm/trunk/include/llvm/InitializePasses.h (original) +++ llvm/trunk/include/llvm/InitializePasses.h Sun Jan 2 18:25:16 2011 @@ -128,6 +128,7 @@ void initializeLoopDependenceAnalysisPass(PassRegistry&); void initializeLoopExtractorPass(PassRegistry&); void initializeLoopInfoPass(PassRegistry&); +void initializeLoopInstSimplifyPass(PassRegistry&); void initializeLoopRotatePass(PassRegistry&); void initializeLoopSimplifyPass(PassRegistry&); void initializeLoopSplitterPass(PassRegistry&); Modified: llvm/trunk/include/llvm/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=122719&r1=122718&r2=122719&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm/Transforms/Scalar.h Sun Jan 2 18:25:16 2011 @@ -119,6 +119,12 @@ //===----------------------------------------------------------------------===// // +// LoopInstSimplify - This pass simplifies instructions in a loop's body. +// +Pass *createLoopInstSimplifyPass(); + +//===----------------------------------------------------------------------===// +// // LoopUnroll - This pass is a simple loop unrolling pass. // Pass *createLoopUnrollPass(); Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=122719&r1=122718&r2=122719&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Sun Jan 2 18:25:16 2011 @@ -13,6 +13,7 @@ LICM.cpp LoopDeletion.cpp LoopIdiomRecognize.cpp + LoopInstSimplify.cpp LoopRotation.cpp LoopStrengthReduce.cpp LoopUnrollPass.cpp Added: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=122719&view=auto ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (added) +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Sun Jan 2 18:25:16 2011 @@ -0,0 +1,112 @@ +//===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass performs lightweight instruction simplification on loop bodies. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "loop-instsimplify" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/Local.h" +#include "llvm/ADT/Statistic.h" +using namespace llvm; + +STATISTIC(NumSimplified, "Number of redundant instructions simplified"); + +namespace { + class LoopInstSimplify : public LoopPass { + public: + static char ID; // Pass ID, replacement for typeid + LoopInstSimplify() : LoopPass(ID) { + initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry()); + } + + bool runOnLoop(Loop*, LPPassManager&); + + virtual void getAnalysisUsage(AnalysisUsage& AU) const { + AU.setPreservesCFG(); + AU.addRequired(); + AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + AU.addPreservedID(LCSSAID); + } + }; +} + +char LoopInstSimplify::ID = 0; +INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify", + "Simplify instructions in loops", false, false) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(LCSSA) +INITIALIZE_PASS_END(LoopInstSimplify, "loop-instsimplify", + "Simplify instructions in loops", false, false) + +Pass* llvm::createLoopInstSimplifyPass() { + return new LoopInstSimplify(); +} + +bool LoopInstSimplify::runOnLoop(Loop* L, LPPassManager& LPM) { + DominatorTree* DT = &getAnalysis(); + const LoopInfo* LI = &getAnalysis(); + const TargetData* TD = getAnalysisIfAvailable(); + + bool Changed = false; + bool LocalChanged; + do { + LocalChanged = false; + + SmallPtrSet Visited; + SmallVector VisitStack; + + VisitStack.push_back(L->getHeader()); + + while (!VisitStack.empty()) { + BasicBlock* BB = VisitStack.back(); + VisitStack.pop_back(); + + if (Visited.count(BB)) + continue; + Visited.insert(BB); + + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { + Instruction* I = BI++; + // Don't bother simplifying unused instructions. + if (!I->use_empty()) { + if (Value* V = SimplifyInstruction(I, TD, DT)) { + I->replaceAllUsesWith(V); + LocalChanged = true; + ++NumSimplified; + } + } + LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); + } + Changed |= LocalChanged; + + DomTreeNode* Node = DT->getNode(BB); + const std::vector& Children = Node->getChildren(); + for (unsigned i = 0; i < Children.size(); ++i) { + // Only visit children that are in the same loop. + BasicBlock* ChildBB = Children[i]->getBlock(); + if (!Visited.count(ChildBB) && LI->getLoopFor(ChildBB) == L) + VisitStack.push_back(ChildBB); + } + } + } while (LocalChanged); + + // Nothing that SimplifyInstruction() does should invalidate LCSSA form. + assert(L->isLCSSAForm(*DT)); + + return Changed; +} Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=122719&r1=122718&r2=122719&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Sun Jan 2 18:25:16 2011 @@ -41,6 +41,7 @@ initializeJumpThreadingPass(Registry); initializeLICMPass(Registry); initializeLoopDeletionPass(Registry); + initializeLoopInstSimplifyPass(Registry); initializeLoopRotatePass(Registry); initializeLoopStrengthReducePass(Registry); initializeLoopUnrollPass(Registry); From sabre at nondot.org Sun Jan 2 19:06:27 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 2 Jan 2011 17:06:27 -0800 Subject: [llvm-commits] [llvm] r122716 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/EarlyCSE/basic.ll In-Reply-To: References: <20110102231945.6A42B2A6C12C@llvm.org> Message-ID: On Jan 2, 2011, at 4:02 PM, Frits van Bommel wrote: > On Mon, Jan 3, 2011 at 12:19 AM, Chris Lattner wrote: >> + else if (GetElementPtrInst *GEP = dyn_cast(Inst)) { >> + Res = getHash(CI->getOperand(0)); >> + for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) >> + Res ^= getHash(CI->getOperand(i)) << i; >> + } else if (CmpInst *CI = dyn_cast(Inst)) { >> + Res = getHash(CI->getOperand(0)) ^ (getHash(CI->getOperand(1)) << 1) ^ >> + CI->getPredicate(); >> + } else { >> + assert((isa(Inst) || isa(Inst) || >> + isa(Inst) || isa(Inst) || >> + isa(Inst) || isa(Inst)) && >> + "Unhandled instruction kind"); >> + Res = getHash(CI->getType()) << 4; >> + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) >> + Res ^= getHash(CI->getOperand(i)) << i; >> + } > > ExtractValue/InsertValue indices aren't operands, so they're not taken > into account here. Good point, I'll fix this so they don't hash to the same thing. > Also, it might make sense to simplify the code by handling operands > more generically instead of duplicating the code in each if clause. This is a work in progress. >> +// This could regognize common matrix multiplies and dot product idioms and >> +// replace them with calls to BLAS (if linked in??). > > s/regognize/recognize/ Thanks. -Chris From sabre at nondot.org Sun Jan 2 19:10:08 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 01:10:08 -0000 Subject: [llvm-commits] [llvm] r122720 - in /llvm/trunk/lib/Transforms/Scalar: EarlyCSE.cpp LoopIdiomRecognize.cpp Message-ID: <20110103011008.89A5B2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 19:10:08 2011 New Revision: 122720 URL: http://llvm.org/viewvc/llvm-project?rev=122720&view=rev Log: reduce redundancy in the hashing code and other misc cleanups. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122720&r1=122719&r2=122720&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 19:10:08 2011 @@ -18,7 +18,6 @@ #include "llvm/Pass.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" -#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/Debug.h" @@ -80,28 +79,33 @@ unsigned DenseMapInfo::getHashValue(InstValue Val) { Instruction *Inst = Val.Inst; + + // Hash in all of the operands as pointers. unsigned Res = 0; + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) + Res ^= getHash(Inst->getOperand(i)) << i; + if (CastInst *CI = dyn_cast(Inst)) - Res = getHash(CI->getOperand(0)) ^ getHash(CI->getType()); - else if (BinaryOperator *BO = dyn_cast(Inst)) - Res = getHash(BO->getOperand(0)) ^ (getHash(BO->getOperand(1)) << 1); - else if (GetElementPtrInst *GEP = dyn_cast(Inst)) { - Res = getHash(GEP->getOperand(0)); - for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) - Res ^= getHash(GEP->getOperand(i)) << i; - } else if (CmpInst *CI = dyn_cast(Inst)) { - Res = getHash(CI->getOperand(0)) ^ (getHash(CI->getOperand(1)) << 1) ^ - CI->getPredicate(); + Res ^= getHash(CI->getType()); + else if (CmpInst *CI = dyn_cast(Inst)) + Res ^= CI->getPredicate(); + else if (const ExtractValueInst *EVI = dyn_cast(Inst)) { + for (ExtractValueInst::idx_iterator I = EVI->idx_begin(), + E = EVI->idx_end(); I != E; ++I) + Res ^= *I; + } else if (const InsertValueInst *IVI = dyn_cast(Inst)) { + for (InsertValueInst::idx_iterator I = IVI->idx_begin(), + E = IVI->idx_end(); I != E; ++I) + Res ^= *I; } else { - assert((isa(Inst) || isa(Inst) || - isa(Inst) || isa(Inst) || - isa(Inst) || isa(Inst)) && - "Unhandled instruction kind"); - Res = getHash(Inst->getType()) << 4; - for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) - Res ^= getHash(Inst->getOperand(i)) << i; + // nothing extra to hash in. + assert((isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst)) && + "Invalid/unknown instruction"); } - + + // Mix in the opcode. return (Res << 1) ^ Inst->getOpcode(); } Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122720&r1=122719&r2=122720&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 19:10:08 2011 @@ -32,7 +32,7 @@ // for (i) { __real__(*P) = 0; __imag__(*P) = 0; } // this is also "Example 2" from http://blog.regehr.org/archives/320 // -// This could regognize common matrix multiplies and dot product idioms and +// This could recognize common matrix multiplies and dot product idioms and // replace them with calls to BLAS (if linked in??). // //===----------------------------------------------------------------------===// From nicholas at mxc.ca Sun Jan 2 19:21:03 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 02 Jan 2011 17:21:03 -0800 Subject: [llvm-commits] [llvm] r122720 - in /llvm/trunk/lib/Transforms/Scalar: EarlyCSE.cpp LoopIdiomRecognize.cpp In-Reply-To: <20110103011008.89A5B2A6C12C@llvm.org> References: <20110103011008.89A5B2A6C12C@llvm.org> Message-ID: <4D21247F.8010107@mxc.ca> On 01/02/2011 05:10 PM, Chris Lattner wrote: > Author: lattner > Date: Sun Jan 2 19:10:08 2011 > New Revision: 122720 > > URL: http://llvm.org/viewvc/llvm-project?rev=122720&view=rev > Log: > reduce redundancy in the hashing code and other misc cleanups. > > Modified: > llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp > llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122720&r1=122719&r2=122720&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 19:10:08 2011 > @@ -18,7 +18,6 @@ > #include "llvm/Pass.h" > #include "llvm/Analysis/Dominators.h" > #include "llvm/Analysis/InstructionSimplify.h" > -#include "llvm/Analysis/InstructionSimplify.h" > #include "llvm/Target/TargetData.h" > #include "llvm/Transforms/Utils/Local.h" > #include "llvm/Support/Debug.h" > @@ -80,28 +79,33 @@ > > unsigned DenseMapInfo::getHashValue(InstValue Val) { > Instruction *Inst = Val.Inst; > + > + // Hash in all of the operands as pointers. > unsigned Res = 0; > + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) > + Res ^= getHash(Inst->getOperand(i))<< i; > + > if (CastInst *CI = dyn_cast(Inst)) > - Res = getHash(CI->getOperand(0)) ^ getHash(CI->getType()); > - else if (BinaryOperator *BO = dyn_cast(Inst)) > - Res = getHash(BO->getOperand(0)) ^ (getHash(BO->getOperand(1))<< 1); > - else if (GetElementPtrInst *GEP = dyn_cast(Inst)) { > - Res = getHash(GEP->getOperand(0)); > - for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) > - Res ^= getHash(GEP->getOperand(i))<< i; > - } else if (CmpInst *CI = dyn_cast(Inst)) { > - Res = getHash(CI->getOperand(0)) ^ (getHash(CI->getOperand(1))<< 1) ^ > - CI->getPredicate(); > + Res ^= getHash(CI->getType()); > + else if (CmpInst *CI = dyn_cast(Inst)) > + Res ^= CI->getPredicate(); > + else if (const ExtractValueInst *EVI = dyn_cast(Inst)) { > + for (ExtractValueInst::idx_iterator I = EVI->idx_begin(), > + E = EVI->idx_end(); I != E; ++I) > + Res ^= *I; > + } else if (const InsertValueInst *IVI = dyn_cast(Inst)) { > + for (InsertValueInst::idx_iterator I = IVI->idx_begin(), > + E = IVI->idx_end(); I != E; ++I) > + Res ^= *I; > } else { > - assert((isa(Inst) || isa(Inst) || > - isa(Inst) || isa(Inst) || > - isa(Inst) || isa(Inst))&& > - "Unhandled instruction kind"); > - Res = getHash(Inst->getType())<< 4; > - for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) > - Res ^= getHash(Inst->getOperand(i))<< i; > + // nothing extra to hash in. > + assert((isa(Inst) || isa(Inst) || > + isa(Inst) || isa(Inst) || > + isa(Inst) || isa(Inst))&& > + "Invalid/unknown instruction"); > } > - > + > + // Mix in the opcode. > return (Res<< 1) ^ Inst->getOpcode(); Chris, did you consider using a FoldingSetNodeID to calculate your hash? I think it would end up cleaner. Nick > } > > > Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122720&r1=122719&r2=122720&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Jan 2 19:10:08 2011 > @@ -32,7 +32,7 @@ > // for (i) { __real__(*P) = 0; __imag__(*P) = 0; } > // this is also "Example 2" from http://blog.regehr.org/archives/320 > // > -// This could regognize common matrix multiplies and dot product idioms and > +// This could recognize common matrix multiplies and dot product idioms and > // replace them with calls to BLAS (if linked in??). > // > //===----------------------------------------------------------------------===// > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sabre at nondot.org Sun Jan 2 19:29:37 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 01:29:37 -0000 Subject: [llvm-commits] [llvm] r122721 - in /llvm/trunk/include/llvm: ADT/ScopedHashTable.h ADT/StringMap.h Support/Allocator.h Message-ID: <20110103012937.7622F2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 19:29:37 2011 New Revision: 122721 URL: http://llvm.org/viewvc/llvm-project?rev=122721&view=rev Log: Enhance ScopedHashTable to allow it to take an allocator argument. Modified: llvm/trunk/include/llvm/ADT/ScopedHashTable.h llvm/trunk/include/llvm/ADT/StringMap.h llvm/trunk/include/llvm/Support/Allocator.h Modified: llvm/trunk/include/llvm/ADT/ScopedHashTable.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ScopedHashTable.h?rev=122721&r1=122720&r2=122721&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ScopedHashTable.h (original) +++ llvm/trunk/include/llvm/ADT/ScopedHashTable.h Sun Jan 2 19:29:37 2011 @@ -31,12 +31,13 @@ #ifndef LLVM_ADT_SCOPEDHASHTABLE_H #define LLVM_ADT_SCOPEDHASHTABLE_H -#include #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Allocator.h" namespace llvm { -template > +template , + typename AllocatorTy = MallocAllocator> class ScopedHashTable; template > @@ -45,11 +46,8 @@ ScopedHashTableVal *NextForKey; K Key; V Val; + ScopedHashTableVal(const K &key, const V &val) : Key(key), Val(val) {} public: - ScopedHashTableVal(ScopedHashTableVal *nextInScope, - ScopedHashTableVal *nextForKey, const K &key, const V &val) - : NextInScope(nextInScope), NextForKey(nextForKey), Key(key), Val(val) { - } const K &getKey() const { return Key; } const V &getValue() const { return Val; } @@ -57,8 +55,27 @@ ScopedHashTableVal *getNextForKey() { return NextForKey; } const ScopedHashTableVal *getNextForKey() const { return NextForKey; } -public: ScopedHashTableVal *getNextInScope() { return NextInScope; } + + template + static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope, + ScopedHashTableVal *nextForKey, + const K &key, const V &val, + AllocatorTy &Allocator) { + ScopedHashTableVal *New = Allocator.template Allocate(); + // Set up the value. + new (New) ScopedHashTableVal(key, val); + New->NextInScope = nextInScope; + New->NextForKey = nextForKey; + return New; + } + + template + void Destroy(AllocatorTy &Allocator) { + // Free memory referenced by the item. + this->~ScopedHashTableVal(); + Allocator.Deallocate(this); + } }; template > @@ -121,26 +138,35 @@ }; -template +template class ScopedHashTable { - DenseMap*, KInfo> TopLevelMap; + typedef ScopedHashTableVal ValTy; + DenseMap TopLevelMap; ScopedHashTableScope *CurScope; + + AllocatorTy Allocator; + ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED friend class ScopedHashTableScope; public: ScopedHashTable() : CurScope(0) {} + ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {} ~ScopedHashTable() { assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!"); } + + typedef typename ReferenceAdder::result AllocatorRefTy; + typedef typename ReferenceAdder::result AllocatorCRefTy; + AllocatorRefTy getAllocator() { return Allocator; } + AllocatorCRefTy getAllocator() const { return Allocator; } bool count(const K &Key) const { return TopLevelMap.count(Key); } V lookup(const K &Key) { - typename DenseMap*, KInfo>::iterator - I = TopLevelMap.find(Key); + typename DenseMap::iterator I = TopLevelMap.find(Key); if (I != TopLevelMap.end()) return I->second->getValue(); @@ -152,8 +178,8 @@ ScopedHashTableVal *&KeyEntry = TopLevelMap[Key]; - KeyEntry= new ScopedHashTableVal(CurScope->getLastValInScope(), - KeyEntry, Key, Val); + KeyEntry = ValTy::Create(CurScope->getLastValInScope(), KeyEntry, Key, Val, + Allocator); CurScope->setLastValInScope(KeyEntry); } @@ -162,7 +188,7 @@ iterator end() { return iterator(0); } iterator begin(const K &Key) { - typename DenseMap*, KInfo>::iterator I = + typename DenseMap::iterator I = TopLevelMap.find(Key); if (I == TopLevelMap.end()) return end(); return iterator(I->second); @@ -202,7 +228,7 @@ LastValInScope = ThisEntry->getNextInScope(); // Delete this entry. - delete ThisEntry; + ThisEntry->Destroy(HT.getAllocator()); } } Modified: llvm/trunk/include/llvm/ADT/StringMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=122721&r1=122720&r2=122721&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringMap.h (original) +++ llvm/trunk/include/llvm/ADT/StringMap.h Sun Jan 2 19:29:37 2011 @@ -242,9 +242,6 @@ }; -template struct ReferenceAdder { typedef T& result; }; -template struct ReferenceAdder { typedef T result; }; - /// StringMap - This is an unconventional map that is specialized for handling /// keys that are "strings", which are basically ranges of bytes. This does some /// funky memory allocation and hashing things to make it extremely efficient, Modified: llvm/trunk/include/llvm/Support/Allocator.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Allocator.h?rev=122721&r1=122720&r2=122721&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Allocator.h (original) +++ llvm/trunk/include/llvm/Support/Allocator.h Sun Jan 2 19:29:37 2011 @@ -23,6 +23,8 @@ #include namespace llvm { +template struct ReferenceAdder { typedef T& result; }; +template struct ReferenceAdder { typedef T result; }; class MallocAllocator { public: From sabre at nondot.org Sun Jan 2 19:38:30 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 01:38:30 -0000 Subject: [llvm-commits] [llvm] r122722 - /llvm/trunk/include/llvm/ADT/ScopedHashTable.h Message-ID: <20110103013830.100B52A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 19:38:29 2011 New Revision: 122722 URL: http://llvm.org/viewvc/llvm-project?rev=122722&view=rev Log: really get this working with a custom allocator. Modified: llvm/trunk/include/llvm/ADT/ScopedHashTable.h Modified: llvm/trunk/include/llvm/ADT/ScopedHashTable.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ScopedHashTable.h?rev=122722&r1=122721&r2=122722&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ScopedHashTable.h (original) +++ llvm/trunk/include/llvm/ADT/ScopedHashTable.h Sun Jan 2 19:38:29 2011 @@ -40,7 +40,7 @@ typename AllocatorTy = MallocAllocator> class ScopedHashTable; -template > +template class ScopedHashTableVal { ScopedHashTableVal *NextInScope; ScopedHashTableVal *NextForKey; @@ -78,29 +78,30 @@ } }; -template > +template , + typename AllocatorTy = MallocAllocator> class ScopedHashTableScope { /// HT - The hashtable that we are active for. - ScopedHashTable &HT; + ScopedHashTable &HT; /// PrevScope - This is the scope that we are shadowing in HT. ScopedHashTableScope *PrevScope; /// LastValInScope - This is the last value that was inserted for this scope /// or null if none have been inserted yet. - ScopedHashTableVal *LastValInScope; + ScopedHashTableVal *LastValInScope; void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT public: - ScopedHashTableScope(ScopedHashTable &HT); + ScopedHashTableScope(ScopedHashTable &HT); ~ScopedHashTableScope(); private: - friend class ScopedHashTable; - ScopedHashTableVal *getLastValInScope() { + friend class ScopedHashTable; + ScopedHashTableVal *getLastValInScope() { return LastValInScope; } - void setLastValInScope(ScopedHashTableVal *Val) { + void setLastValInScope(ScopedHashTableVal *Val) { LastValInScope = Val; } }; @@ -108,9 +109,9 @@ template > class ScopedHashTableIterator { - ScopedHashTableVal *Node; + ScopedHashTableVal *Node; public: - ScopedHashTableIterator(ScopedHashTableVal *node) : Node(node) {} + ScopedHashTableIterator(ScopedHashTableVal *node) : Node(node) {} V &operator*() const { assert(Node && "Dereference end()"); @@ -140,15 +141,15 @@ template class ScopedHashTable { - typedef ScopedHashTableVal ValTy; + typedef ScopedHashTableVal ValTy; DenseMap TopLevelMap; - ScopedHashTableScope *CurScope; + ScopedHashTableScope *CurScope; AllocatorTy Allocator; ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED - friend class ScopedHashTableScope; + friend class ScopedHashTableScope; public: ScopedHashTable() : CurScope(0) {} ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {} @@ -176,7 +177,7 @@ void insert(const K &Key, const V &Val) { assert(CurScope && "No scope active!"); - ScopedHashTableVal *&KeyEntry = TopLevelMap[Key]; + ScopedHashTableVal *&KeyEntry = TopLevelMap[Key]; KeyEntry = ValTy::Create(CurScope->getLastValInScope(), KeyEntry, Key, Val, Allocator); @@ -197,29 +198,28 @@ /// ScopedHashTableScope ctor - Install this as the current scope for the hash /// table. -template -ScopedHashTableScope:: - ScopedHashTableScope(ScopedHashTable &ht) : HT(ht) { +template +ScopedHashTableScope:: + ScopedHashTableScope(ScopedHashTable &ht) : HT(ht) { PrevScope = HT.CurScope; HT.CurScope = this; LastValInScope = 0; } -template -ScopedHashTableScope::~ScopedHashTableScope() { +template +ScopedHashTableScope::~ScopedHashTableScope() { assert(HT.CurScope == this && "Scope imbalance!"); HT.CurScope = PrevScope; // Pop and delete all values corresponding to this scope. - while (ScopedHashTableVal *ThisEntry = LastValInScope) { + while (ScopedHashTableVal *ThisEntry = LastValInScope) { // Pop this value out of the TopLevelMap. if (ThisEntry->getNextForKey() == 0) { assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry && "Scope imbalance!"); HT.TopLevelMap.erase(ThisEntry->getKey()); } else { - ScopedHashTableVal *&KeyEntry = - HT.TopLevelMap[ThisEntry->getKey()]; + ScopedHashTableVal *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()]; assert(KeyEntry == ThisEntry && "Scope imbalance!"); KeyEntry = ThisEntry->getNextForKey(); } From sabre at nondot.org Sun Jan 2 19:42:46 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 01:42:46 -0000 Subject: [llvm-commits] [llvm] r122723 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Message-ID: <20110103014246.718602A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 19:42:46 2011 New Revision: 122723 URL: http://llvm.org/viewvc/llvm-project?rev=122723&view=rev Log: Allocate nodes for the scoped hash table from a recyling bump pointer allocator. This speeds up early cse by about 20% Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122723&r1=122722&r2=122723&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 19:42:46 2011 @@ -21,6 +21,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/RecyclingAllocator.h" #include "llvm/ADT/ScopedHashTable.h" #include "llvm/ADT/Statistic.h" using namespace llvm; @@ -132,7 +133,11 @@ public: const TargetData *TD; DominatorTree *DT; - ScopedHashTable *AvailableValues; + typedef RecyclingAllocator > AllocatorTy; + typedef ScopedHashTable, + AllocatorTy> ScopedHTType; + ScopedHTType *AvailableValues; static char ID; explicit EarlyCSE() @@ -165,11 +170,10 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false) -// FIXME: Should bump pointer allocate entries in scoped hash table. - bool EarlyCSE::processNode(DomTreeNode *Node) { // Define a scope in the scoped hash table. - ScopedHashTableScope Scope(*AvailableValues); + ScopedHashTableScope, + AllocatorTy> Scope(*AvailableValues); BasicBlock *BB = Node->getBlock(); @@ -228,7 +232,7 @@ bool EarlyCSE::runOnFunction(Function &F) { TD = getAnalysisIfAvailable(); DT = &getAnalysis(); - ScopedHashTable AVTable; + ScopedHTType AVTable; AvailableValues = &AVTable; return processNode(DT->getRootNode()); } From clattner at apple.com Sun Jan 2 19:46:46 2011 From: clattner at apple.com (Chris Lattner) Date: Sun, 2 Jan 2011 17:46:46 -0800 Subject: [llvm-commits] [llvm] r122720 - in /llvm/trunk/lib/Transforms/Scalar: EarlyCSE.cpp LoopIdiomRecognize.cpp In-Reply-To: <4D21247F.8010107@mxc.ca> References: <20110103011008.89A5B2A6C12C@llvm.org> <4D21247F.8010107@mxc.ca> Message-ID: <3C7BD2E1-D486-44A2-A2B2-38E2EA53CA85@apple.com> On Jan 2, 2011, at 5:21 PM, Nick Lewycky wrote: >> + "Invalid/unknown instruction"); >> } >> - >> + >> + // Mix in the opcode. >> return (Res<< 1) ^ Inst->getOpcode(); > > Chris, did you consider using a FoldingSetNodeID to calculate your hash? > I think it would end up cleaner. How would it help? -Chris From zwarich at apple.com Sun Jan 2 19:53:25 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 2 Jan 2011 17:53:25 -0800 Subject: [llvm-commits] [llvm] r122723 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp In-Reply-To: <20110103014246.718602A6C12C@llvm.org> References: <20110103014246.718602A6C12C@llvm.org> Message-ID: <12B448C5-B19F-46AA-ADEB-62B6DFFC021D@apple.com> Should I do the same for MachineCSE? Cameron On Jan 2, 2011, at 5:42 PM, Chris Lattner wrote: > Author: lattner > Date: Sun Jan 2 19:42:46 2011 > New Revision: 122723 > > URL: http://llvm.org/viewvc/llvm-project?rev=122723&view=rev > Log: > Allocate nodes for the scoped hash table from a recyling bump pointer > allocator. This speeds up early cse by about 20% > > Modified: > llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122723&r1=122722&r2=122723&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 19:42:46 2011 > @@ -21,6 +21,7 @@ > #include "llvm/Target/TargetData.h" > #include "llvm/Transforms/Utils/Local.h" > #include "llvm/Support/Debug.h" > +#include "llvm/Support/RecyclingAllocator.h" > #include "llvm/ADT/ScopedHashTable.h" > #include "llvm/ADT/Statistic.h" > using namespace llvm; > @@ -132,7 +133,11 @@ > public: > const TargetData *TD; > DominatorTree *DT; > - ScopedHashTable *AvailableValues; > + typedef RecyclingAllocator + ScopedHashTableVal > AllocatorTy; > + typedef ScopedHashTable, > + AllocatorTy> ScopedHTType; > + ScopedHTType *AvailableValues; > > static char ID; > explicit EarlyCSE() > @@ -165,11 +170,10 @@ > INITIALIZE_PASS_DEPENDENCY(DominatorTree) > INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false) > > -// FIXME: Should bump pointer allocate entries in scoped hash table. > - > bool EarlyCSE::processNode(DomTreeNode *Node) { > // Define a scope in the scoped hash table. > - ScopedHashTableScope Scope(*AvailableValues); > + ScopedHashTableScope, > + AllocatorTy> Scope(*AvailableValues); > > BasicBlock *BB = Node->getBlock(); > > @@ -228,7 +232,7 @@ > bool EarlyCSE::runOnFunction(Function &F) { > TD = getAnalysisIfAvailable(); > DT = &getAnalysis(); > - ScopedHashTable AVTable; > + ScopedHTType AVTable; > AvailableValues = &AVTable; > return processNode(DT->getRootNode()); > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Sun Jan 2 20:03:21 2011 From: sabre at nondot.org (Chris Lattner) Date: Sun, 2 Jan 2011 18:03:21 -0800 Subject: [llvm-commits] [llvm] r122723 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp In-Reply-To: <12B448C5-B19F-46AA-ADEB-62B6DFFC021D@apple.com> References: <20110103014246.718602A6C12C@llvm.org> <12B448C5-B19F-46AA-ADEB-62B6DFFC021D@apple.com> Message-ID: On Jan 2, 2011, at 5:53 PM, Cameron Zwarich wrote: > Should I do the same for MachineCSE? Sure, if it speeds it up! -Chris From nicholas at mxc.ca Sun Jan 2 20:15:23 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 02 Jan 2011 18:15:23 -0800 Subject: [llvm-commits] [llvm] r122720 - in /llvm/trunk/lib/Transforms/Scalar: EarlyCSE.cpp LoopIdiomRecognize.cpp In-Reply-To: <3C7BD2E1-D486-44A2-A2B2-38E2EA53CA85@apple.com> References: <20110103011008.89A5B2A6C12C@llvm.org> <4D21247F.8010107@mxc.ca> <3C7BD2E1-D486-44A2-A2B2-38E2EA53CA85@apple.com> Message-ID: <4D21313B.104@mxc.ca> On 01/02/2011 05:46 PM, Chris Lattner wrote: > > On Jan 2, 2011, at 5:21 PM, Nick Lewycky wrote: > >>> + "Invalid/unknown instruction"); >>> } >>> - >>> + >>> + // Mix in the opcode. >>> return (Res<< 1) ^ Inst->getOpcode(); >> >> Chris, did you consider using a FoldingSetNodeID to calculate your hash? >> I think it would end up cleaner. > > How would it help? Mostly it just hides the hashing math. You'd end up with: unsigned DenseMapInfo::getHashValue(InstValue Val) { FoldingSetNodeID Res; for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) Res.AddPointer(Inst->getOperand(i)); if (CastInst *CI = dyn_cast(Inst)) Res.AddPointer(CI->getType()); else if (CmpInst *CI = dyn_cast(Inst)) Res.AddInteger(CI->getPredicate()); else if (const ExtractValueInst *EVI = dyn_cast(Inst)) { for (ExtractValueInst::idx_iterator I = EVI->idx_begin(), E = EVI->idx_end(); I != E; ++I) Res.AddInteger(*I); } else if (const InsertValueInst *IVI = dyn_cast(Inst)) { for (InsertValueInst::idx_iterator I = IVI->idx_begin(), E = IVI->idx_end(); I != E; ++I) Res.AddInteger(*I); [...] Res.AddInteger(I->getOpcode()); return Res.ComputeHash(); } It's nice in that you don't have to worry about how much you're shifting and whether you're going to be mixing the bits properly, etc. It doesn't do anything to reduce the number of lines. Nick From bigcheesegs at gmail.com Sun Jan 2 20:13:05 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Mon, 03 Jan 2011 02:13:05 -0000 Subject: [llvm-commits] [llvm] r122724 - /llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Message-ID: <20110103021305.D654F2A6C12C@llvm.org> Author: mspencer Date: Sun Jan 2 20:13:05 2011 New Revision: 122724 URL: http://llvm.org/viewvc/llvm-project?rev=122724&view=rev Log: CMake: Add missing source file. Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=122724&r1=122723&r2=122724&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Sun Jan 2 20:13:05 2011 @@ -6,6 +6,7 @@ CorrelatedValuePropagation.cpp DCE.cpp DeadStoreElimination.cpp + EarlyCSE.cpp GEPSplitter.cpp GVN.cpp IndVarSimplify.cpp From sabre at nondot.org Sun Jan 2 20:20:48 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 02:20:48 -0000 Subject: [llvm-commits] [llvm] r122725 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Message-ID: <20110103022048.6B9752A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 20:20:48 2011 New Revision: 122725 URL: http://llvm.org/viewvc/llvm-project?rev=122725&view=rev Log: rename InstValue to SimpleValue, add some comments. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122725&r1=122724&r2=122725&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 20:20:48 2011 @@ -29,10 +29,14 @@ STATISTIC(NumSimplify, "Number of insts simplified or DCE'd"); STATISTIC(NumCSE, "Number of insts CSE'd"); +//===----------------------------------------------------------------------===// +// SimpleValue +//===----------------------------------------------------------------------===// + namespace { - /// InstValue - Instances of this struct represent available values in the + /// SimpleValue - Instances of this struct represent available values in the /// scoped hash table. - struct InstValue { + struct SimpleValue { Instruction *Inst; bool isSentinel() const { @@ -48,8 +52,8 @@ isa(Inst) || isa(Inst); } - static InstValue get(Instruction *I) { - InstValue X; X.Inst = I; + static SimpleValue get(Instruction *I) { + SimpleValue X; X.Inst = I; assert((X.isSentinel() || canHandle(I)) && "Inst can't be handled!"); return X; } @@ -57,20 +61,20 @@ } namespace llvm { -// InstValue is POD. -template<> struct isPodLike { +// SimpleValue is POD. +template<> struct isPodLike { static const bool value = true; }; -template<> struct DenseMapInfo { - static inline InstValue getEmptyKey() { - return InstValue::get(DenseMapInfo::getEmptyKey()); +template<> struct DenseMapInfo { + static inline SimpleValue getEmptyKey() { + return SimpleValue::get(DenseMapInfo::getEmptyKey()); } - static inline InstValue getTombstoneKey() { - return InstValue::get(DenseMapInfo::getTombstoneKey()); + static inline SimpleValue getTombstoneKey() { + return SimpleValue::get(DenseMapInfo::getTombstoneKey()); } - static unsigned getHashValue(InstValue Val); - static bool isEqual(InstValue LHS, InstValue RHS); + static unsigned getHashValue(SimpleValue Val); + static bool isEqual(SimpleValue LHS, SimpleValue RHS); }; } @@ -78,7 +82,7 @@ return DenseMapInfo::getHashValue(V); } -unsigned DenseMapInfo::getHashValue(InstValue Val) { +unsigned DenseMapInfo::getHashValue(SimpleValue Val) { Instruction *Inst = Val.Inst; // Hash in all of the operands as pointers. @@ -110,7 +114,7 @@ return (Res << 1) ^ Inst->getOpcode(); } -bool DenseMapInfo::isEqual(InstValue LHS, InstValue RHS) { +bool DenseMapInfo::isEqual(SimpleValue LHS, SimpleValue RHS) { Instruction *LHSI = LHS.Inst, *RHSI = RHS.Inst; if (LHS.isSentinel() || RHS.isSentinel()) @@ -121,6 +125,10 @@ } +//===----------------------------------------------------------------------===// +// EarlyCSE pass +//===----------------------------------------------------------------------===// + namespace { /// EarlyCSE - This pass does a simple depth-first walk over the dominator @@ -134,14 +142,19 @@ const TargetData *TD; DominatorTree *DT; typedef RecyclingAllocator > AllocatorTy; - typedef ScopedHashTable, + ScopedHashTableVal > AllocatorTy; + typedef ScopedHashTable, AllocatorTy> ScopedHTType; - ScopedHTType *AvailableValues; + /// AvailableValues - This scoped hash table contains the current values of + /// all of our simple scalar expressions. As we walk down the domtree, we + /// look to see if instructions are in this: if so, we replace them with what + /// we find, otherwise we insert them so that dominated values can succeed in + /// their lookup. + ScopedHTType *AvailableValues; + static char ID; - explicit EarlyCSE() - : FunctionPass(ID) { + explicit EarlyCSE() : FunctionPass(ID) { initializeEarlyCSEPass(*PassRegistry::getPassRegistry()); } @@ -171,8 +184,10 @@ INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false) bool EarlyCSE::processNode(DomTreeNode *Node) { - // Define a scope in the scoped hash table. - ScopedHashTableScope, + // Define a scope in the scoped hash table. When we are done processing this + // domtree node and recurse back up to our parent domtree node, this will pop + // off all the values we install. + ScopedHashTableScope, AllocatorTy> Scope(*AvailableValues); BasicBlock *BB = Node->getBlock(); @@ -205,11 +220,11 @@ } // If this instruction is something that we can't value number, ignore it. - if (!InstValue::canHandle(Inst)) + if (!SimpleValue::canHandle(Inst)) continue; // See if the instruction has an available value. If so, use it. - if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) { + if (Value *V = AvailableValues->lookup(SimpleValue::get(Inst))) { DEBUG(dbgs() << "EarlyCSE CSE: " << *Inst << " to: " << *V << '\n'); Inst->replaceAllUsesWith(V); Inst->eraseFromParent(); @@ -219,7 +234,7 @@ } // Otherwise, just remember that this value is available. - AvailableValues->insert(InstValue::get(Inst), Inst); + AvailableValues->insert(SimpleValue::get(Inst), Inst); } @@ -234,6 +249,6 @@ DT = &getAnalysis(); ScopedHTType AVTable; AvailableValues = &AVTable; + return processNode(DT->getRootNode()); } - From clattner at apple.com Sun Jan 2 21:09:16 2011 From: clattner at apple.com (Chris Lattner) Date: Sun, 2 Jan 2011 19:09:16 -0800 Subject: [llvm-commits] [llvm] r122720 - in /llvm/trunk/lib/Transforms/Scalar: EarlyCSE.cpp LoopIdiomRecognize.cpp In-Reply-To: <4D21313B.104@mxc.ca> References: <20110103011008.89A5B2A6C12C@llvm.org> <4D21247F.8010107@mxc.ca> <3C7BD2E1-D486-44A2-A2B2-38E2EA53CA85@apple.com> <4D21313B.104@mxc.ca> Message-ID: <3A0A5A7C-4F62-4676-8F32-D1A96D4DB40A@apple.com> On Jan 2, 2011, at 6:15 PM, Nick Lewycky wrote: > On 01/02/2011 05:46 PM, Chris Lattner wrote: >> >> On Jan 2, 2011, at 5:21 PM, Nick Lewycky wrote: >> >>>> + "Invalid/unknown instruction"); >>>> } >>>> - >>>> + >>>> + // Mix in the opcode. >>>> return (Res<< 1) ^ Inst->getOpcode(); >>> >>> Chris, did you consider using a FoldingSetNodeID to calculate your hash? >>> I think it would end up cleaner. >> >> How would it help? > > Mostly it just hides the hashing math. You'd end up with: > > unsigned DenseMapInfo::getHashValue(InstValue Val) { > FoldingSetNodeID Res; > for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) > Res.AddPointer(Inst->getOperand(i)); > > if (CastInst *CI = dyn_cast(Inst)) > Res.AddPointer(CI->getType()); > else if (CmpInst *CI = dyn_cast(Inst)) > Res.AddInteger(CI->getPredicate()); > else if (const ExtractValueInst *EVI = dyn_cast(Inst)) { > for (ExtractValueInst::idx_iterator I = EVI->idx_begin(), > E = EVI->idx_end(); I != E; ++I) > Res.AddInteger(*I); > } else if (const InsertValueInst *IVI = dyn_cast(Inst)) { > for (InsertValueInst::idx_iterator I = IVI->idx_begin(), > E = IVI->idx_end(); I != E; ++I) > Res.AddInteger(*I); > [...] > Res.AddInteger(I->getOpcode()); > return Res.ComputeHash(); > } > > It's nice in that you don't have to worry about how much you're shifting and whether you're going to be mixing the bits properly, etc. It doesn't do anything to reduce the number of lines. I'd rather not pull in FoldingSet.h. Thanks for the idea though, -Chris From sabre at nondot.org Sun Jan 2 21:16:20 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 03:16:20 -0000 Subject: [llvm-commits] [llvm] r122726 - /llvm/trunk/include/llvm/ADT/ScopedHashTable.h Message-ID: <20110103031620.B3E262A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 21:16:20 2011 New Revision: 122726 URL: http://llvm.org/viewvc/llvm-project?rev=122726&view=rev Log: add a handy typedef. Modified: llvm/trunk/include/llvm/ADT/ScopedHashTable.h Modified: llvm/trunk/include/llvm/ADT/ScopedHashTable.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ScopedHashTable.h?rev=122726&r1=122725&r2=122726&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ScopedHashTable.h (original) +++ llvm/trunk/include/llvm/ADT/ScopedHashTable.h Sun Jan 2 21:16:20 2011 @@ -157,6 +157,11 @@ assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!"); } + /// ScopeTy - This is a helpful typedef that allows clients to get easy access + /// to the name of the scope for this hash table. + typedef ScopedHashTableScope ScopeTy; + + /// Access to the allocator. typedef typename ReferenceAdder::result AllocatorRefTy; typedef typename ReferenceAdder::result AllocatorCRefTy; AllocatorRefTy getAllocator() { return Allocator; } From sabre at nondot.org Sun Jan 2 21:18:43 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 03:18:43 -0000 Subject: [llvm-commits] [llvm] r122727 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/basic.ll Message-ID: <20110103031843.ACD052A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 21:18:43 2011 New Revision: 122727 URL: http://llvm.org/viewvc/llvm-project?rev=122727&view=rev Log: Teach EarlyCSE to do trivial CSE of loads and read-only calls. On 176.gcc, this catches 13090 loads and calls, and increases the number of simple instructions CSE'd from 29658 to 36208. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp llvm/trunk/test/Transforms/EarlyCSE/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122727&r1=122726&r2=122727&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 21:18:43 2011 @@ -27,7 +27,12 @@ using namespace llvm; STATISTIC(NumSimplify, "Number of insts simplified or DCE'd"); -STATISTIC(NumCSE, "Number of insts CSE'd"); +STATISTIC(NumCSE, "Number of insts CSE'd"); +STATISTIC(NumCSEMem, "Number of load and call insts CSE'd"); + +static unsigned getHash(const void *V) { + return DenseMapInfo::getHashValue(V); +} //===----------------------------------------------------------------------===// // SimpleValue @@ -78,10 +83,6 @@ }; } -unsigned getHash(const void *V) { - return DenseMapInfo::getHashValue(V); -} - unsigned DenseMapInfo::getHashValue(SimpleValue Val) { Instruction *Inst = Val.Inst; @@ -124,9 +125,77 @@ return LHSI->isIdenticalTo(RHSI); } +//===----------------------------------------------------------------------===// +// MemoryValue +//===----------------------------------------------------------------------===// + +namespace { + /// MemoryValue - Instances of this struct represent available load and call + /// values in the scoped hash table. + struct MemoryValue { + Instruction *Inst; + + bool isSentinel() const { + return Inst == DenseMapInfo::getEmptyKey() || + Inst == DenseMapInfo::getTombstoneKey(); + } + + static bool canHandle(Instruction *Inst) { + if (LoadInst *LI = dyn_cast(Inst)) + return !LI->isVolatile(); + if (CallInst *CI = dyn_cast(Inst)) + return CI->onlyReadsMemory(); + return false; + } + + static MemoryValue get(Instruction *I) { + MemoryValue X; X.Inst = I; + assert((X.isSentinel() || canHandle(I)) && "Inst can't be handled!"); + return X; + } + }; +} + +namespace llvm { + // MemoryValue is POD. + template<> struct isPodLike { + static const bool value = true; + }; + + template<> struct DenseMapInfo { + static inline MemoryValue getEmptyKey() { + return MemoryValue::get(DenseMapInfo::getEmptyKey()); + } + static inline MemoryValue getTombstoneKey() { + return MemoryValue::get(DenseMapInfo::getTombstoneKey()); + } + static unsigned getHashValue(MemoryValue Val); + static bool isEqual(MemoryValue LHS, MemoryValue RHS); + }; +} +unsigned DenseMapInfo::getHashValue(MemoryValue Val) { + Instruction *Inst = Val.Inst; + // Hash in all of the operands as pointers. + unsigned Res = 0; + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) + Res ^= getHash(Inst->getOperand(i)) << i; + // Mix in the opcode. + return (Res << 1) ^ Inst->getOpcode(); +} + +bool DenseMapInfo::isEqual(MemoryValue LHS, MemoryValue RHS) { + Instruction *LHSI = LHS.Inst, *RHSI = RHS.Inst; + + if (LHS.isSentinel() || RHS.isSentinel()) + return LHSI == RHSI; + + if (LHSI->getOpcode() != RHSI->getOpcode()) return false; + return LHSI->isIdenticalTo(RHSI); +} + //===----------------------------------------------------------------------===// -// EarlyCSE pass +// EarlyCSE pass. //===----------------------------------------------------------------------===// namespace { @@ -152,7 +221,21 @@ /// we find, otherwise we insert them so that dominated values can succeed in /// their lookup. ScopedHTType *AvailableValues; - + + typedef ScopedHashTable > MemHTType; + /// AvailableMemValues - This scoped hash table contains the current values of + /// loads and other read-only memory values. This allows us to get efficient + /// access to dominating loads we we find a fully redundant load. In addition + /// to the most recent load, we keep track of a generation count of the read, + /// which is compared against the current generation count. The current + /// generation count is incremented after every possibly writing memory + /// operation, which ensures that we only CSE loads with other loads that have + /// no intervening store. + MemHTType *AvailableMemValues; + + /// CurrentGeneration - This is the current generation of the memory value. + unsigned CurrentGeneration; + static char ID; explicit EarlyCSE() : FunctionPass(ID) { initializeEarlyCSEPass(*PassRegistry::getPassRegistry()); @@ -187,11 +270,23 @@ // Define a scope in the scoped hash table. When we are done processing this // domtree node and recurse back up to our parent domtree node, this will pop // off all the values we install. - ScopedHashTableScope, - AllocatorTy> Scope(*AvailableValues); + ScopedHTType::ScopeTy Scope(*AvailableValues); + + // Define a scope for the memory values so that anything we add will get + // popped when we recurse back up to our parent domtree node. + MemHTType::ScopeTy MemScope(*AvailableMemValues); BasicBlock *BB = Node->getBlock(); + // If this block has a single predecessor, then the predecessor is the parent + // of the domtree node and all of the live out memory values are still current + // in this block. If this block has multiple predecessors, then they could + // have invalidated the live-out memory values of our parent value. For now, + // just be conservative and invalidate memory if this block has multiple + // predecessors. + if (BB->getSinglePredecessor() == 0) + ++CurrentGeneration; + bool Changed = false; // See if any instructions in the block can be eliminated. If so, do it. If @@ -219,27 +314,58 @@ continue; } - // If this instruction is something that we can't value number, ignore it. - if (!SimpleValue::canHandle(Inst)) + // If this is a simple instruction that we can value number, process it. + if (SimpleValue::canHandle(Inst)) { + // See if the instruction has an available value. If so, use it. + if (Value *V = AvailableValues->lookup(SimpleValue::get(Inst))) { + DEBUG(dbgs() << "EarlyCSE CSE: " << *Inst << " to: " << *V << '\n'); + Inst->replaceAllUsesWith(V); + Inst->eraseFromParent(); + Changed = true; + ++NumCSE; + continue; + } + + // Otherwise, just remember that this value is available. + AvailableValues->insert(SimpleValue::get(Inst), Inst); continue; + } - // See if the instruction has an available value. If so, use it. - if (Value *V = AvailableValues->lookup(SimpleValue::get(Inst))) { - DEBUG(dbgs() << "EarlyCSE CSE: " << *Inst << " to: " << *V << '\n'); - Inst->replaceAllUsesWith(V); - Inst->eraseFromParent(); - Changed = true; - ++NumCSE; + // If this is a read-only memory value, process it. + if (MemoryValue::canHandle(Inst)) { + // If we have an available version of this value, and if it is the right + // generation, replace this instruction. + std::pair InVal = + AvailableMemValues->lookup(MemoryValue::get(Inst)); + if (InVal.first != 0 && InVal.second == CurrentGeneration) { + DEBUG(dbgs() << "EarlyCSE CSE MEM: " << *Inst << " to: " + << *InVal.first << '\n'); + if (!Inst->use_empty()) Inst->replaceAllUsesWith(InVal.first); + Inst->eraseFromParent(); + Changed = true; + ++NumCSEMem; + continue; + } + + // Otherwise, remember that we have this instruction. + AvailableMemValues->insert(MemoryValue::get(Inst), + std::pair(Inst, CurrentGeneration)); continue; } - // Otherwise, just remember that this value is available. - AvailableValues->insert(SimpleValue::get(Inst), Inst); + // Okay, this isn't something we can CSE at all. Check to see if it is + // something that could modify memory. If so, our available memory values + // cannot be used so bump the generation count. + if (Inst->mayWriteToMemory()) + ++CurrentGeneration; } - - for (DomTreeNode::iterator I = Node->begin(), E = Node->end(); I != E; ++I) + unsigned LiveOutGeneration = CurrentGeneration; + for (DomTreeNode::iterator I = Node->begin(), E = Node->end(); I != E; ++I) { Changed |= processNode(*I); + // Pop any generation changes off the stack from the recursive walk. + CurrentGeneration = LiveOutGeneration; + } return Changed; } @@ -250,5 +376,9 @@ ScopedHTType AVTable; AvailableValues = &AVTable; + MemHTType MemTable; + AvailableMemValues = &MemTable; + + CurrentGeneration = 0; return processNode(DT->getRootNode()); } Modified: llvm/trunk/test/Transforms/EarlyCSE/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/basic.ll?rev=122727&r1=122726&r2=122727&view=diff ============================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/basic.ll (original) +++ llvm/trunk/test/Transforms/EarlyCSE/basic.ll Sun Jan 2 21:18:43 2011 @@ -30,3 +30,48 @@ ; CHECK-NEXT: volatile store i32 %G ret void } + + +;; Simple load value numbering. +; CHECK: @test2 +define i32 @test2(i32 *%P) { + %V1 = load i32* %P + %V2 = load i32* %P + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK: ret i32 0 +} + +;; Cross block load value numbering. +; CHECK: @test3 +define i32 @test3(i32 *%P, i1 %Cond) { + %V1 = load i32* %P + br i1 %Cond, label %T, label %F +T: + store i32 4, i32* %P + ret i32 42 +F: + %V2 = load i32* %P + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK: F: + ; CHECK: ret i32 0 +} + +;; Cross block load value numbering stops when stores happen. +; CHECK: @test4 +define i32 @test4(i32 *%P, i1 %Cond) { + %V1 = load i32* %P + br i1 %Cond, label %T, label %F +T: + ret i32 42 +F: + ; Clobbers V1 + store i32 42, i32* %P + + %V2 = load i32* %P + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK: F: + ; CHECK: ret i32 %Diff +} From nicholas at mxc.ca Sun Jan 2 21:19:35 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 03 Jan 2011 03:19:35 -0000 Subject: [llvm-commits] [llvm] r122728 - in /llvm/trunk: include/llvm/Analysis/CallGraph.h lib/Analysis/IPA/CallGraph.cpp Message-ID: <20110103031935.EF68A2A6C12C@llvm.org> Author: nicholas Date: Sun Jan 2 21:19:35 2011 New Revision: 122728 URL: http://llvm.org/viewvc/llvm-project?rev=122728&view=rev Log: Add spliceFunction to the CallGraph interface. This allows users to efficiently update a callGraph when performing the common operation of splicing the body to a new function and updating all callers (such as via RAUW). No users yet, though this is intended for DeadArgumentElimination as part of PR8887. Modified: llvm/trunk/include/llvm/Analysis/CallGraph.h llvm/trunk/lib/Analysis/IPA/CallGraph.cpp Modified: llvm/trunk/include/llvm/Analysis/CallGraph.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CallGraph.h?rev=122728&r1=122727&r2=122728&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/CallGraph.h (original) +++ llvm/trunk/include/llvm/Analysis/CallGraph.h Sun Jan 2 21:19:35 2011 @@ -138,6 +138,13 @@ /// not already exist. CallGraphNode *getOrInsertFunction(const Function *F); + /// spliceFunction - Replace the function represented by this node by another. + /// This does not rescan the body of the function, so it is suitable when + /// splicing the body of one function to another while also updating all + /// callers from the old function to the new. + /// + void spliceFunction(const Function *From, const Function *To); + //===--------------------------------------------------------------------- // Pass infrastructure interface glue code. // @@ -163,8 +170,10 @@ // CallGraphNode class definition. // class CallGraphNode { - AssertingVH F; + friend class CallGraph; + AssertingVH F; + // CallRecord - This is a pair of the calling instruction (a call or invoke) // and the callgraph node being called. public: Modified: llvm/trunk/lib/Analysis/IPA/CallGraph.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/CallGraph.cpp?rev=122728&r1=122727&r2=122728&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/CallGraph.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/CallGraph.cpp Sun Jan 2 21:19:35 2011 @@ -230,6 +230,21 @@ return F; } +/// spliceFunction - Replace the function represented by this node by another. +/// This does not rescan the body of the function, so it is suitable when +/// splicing the body of the old function to the new while also updating all +/// callers from old to new. +/// +void CallGraph::spliceFunction(const Function *From, const Function *To) { + assert(FunctionMap.count(From) && "No CallGraphNode for function!"); + assert(!FunctionMap.count(To) && + "Pointing CallGraphNode at a function that already exists"); + FunctionMapTy::iterator I = FunctionMap.find(From); + I->second->F = const_cast(To); + FunctionMap[To] = I->second; + FunctionMap.erase(I); +} + // getOrInsertFunction - This method is identical to calling operator[], but // it will insert a new CallGraphNode for the specified function if one does // not already exist. @@ -276,7 +291,6 @@ } } - // removeAnyCallEdgeTo - This method removes any call edges from this node to // the specified callee function. This takes more time to execute than // removeCallEdgeTo, so it should not be used unless necessary. From sabre at nondot.org Sun Jan 2 21:28:23 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 03:28:23 -0000 Subject: [llvm-commits] [llvm] r122729 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Message-ID: <20110103032823.6B2242A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 21:28:23 2011 New Revision: 122729 URL: http://llvm.org/viewvc/llvm-project?rev=122729&view=rev Log: various cleanups, no functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122729&r1=122728&r2=122729&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 21:28:23 2011 @@ -26,9 +26,9 @@ #include "llvm/ADT/Statistic.h" using namespace llvm; -STATISTIC(NumSimplify, "Number of insts simplified or DCE'd"); -STATISTIC(NumCSE, "Number of insts CSE'd"); -STATISTIC(NumCSEMem, "Number of load and call insts CSE'd"); +STATISTIC(NumSimplify, "Number of instructions simplified or DCE'd"); +STATISTIC(NumCSE, "Number of instructions CSE'd"); +STATISTIC(NumCSEMem, "Number of load and call instructions CSE'd"); static unsigned getHash(const void *V) { return DenseMapInfo::getHashValue(V); @@ -44,6 +44,10 @@ struct SimpleValue { Instruction *Inst; + SimpleValue(Instruction *I) : Inst(I) { + assert((isSentinel() || canHandle(I)) && "Inst can't be handled!"); + } + bool isSentinel() const { return Inst == DenseMapInfo::getEmptyKey() || Inst == DenseMapInfo::getTombstoneKey(); @@ -56,12 +60,6 @@ isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst); } - - static SimpleValue get(Instruction *I) { - SimpleValue X; X.Inst = I; - assert((X.isSentinel() || canHandle(I)) && "Inst can't be handled!"); - return X; - } }; } @@ -73,10 +71,10 @@ template<> struct DenseMapInfo { static inline SimpleValue getEmptyKey() { - return SimpleValue::get(DenseMapInfo::getEmptyKey()); + return DenseMapInfo::getEmptyKey(); } static inline SimpleValue getTombstoneKey() { - return SimpleValue::get(DenseMapInfo::getTombstoneKey()); + return DenseMapInfo::getTombstoneKey(); } static unsigned getHashValue(SimpleValue Val); static bool isEqual(SimpleValue LHS, SimpleValue RHS); @@ -135,6 +133,10 @@ struct MemoryValue { Instruction *Inst; + MemoryValue(Instruction *I) : Inst(I) { + assert((isSentinel() || canHandle(I)) && "Inst can't be handled!"); + } + bool isSentinel() const { return Inst == DenseMapInfo::getEmptyKey() || Inst == DenseMapInfo::getTombstoneKey(); @@ -147,12 +149,6 @@ return CI->onlyReadsMemory(); return false; } - - static MemoryValue get(Instruction *I) { - MemoryValue X; X.Inst = I; - assert((X.isSentinel() || canHandle(I)) && "Inst can't be handled!"); - return X; - } }; } @@ -164,10 +160,10 @@ template<> struct DenseMapInfo { static inline MemoryValue getEmptyKey() { - return MemoryValue::get(DenseMapInfo::getEmptyKey()); + return DenseMapInfo::getEmptyKey(); } static inline MemoryValue getTombstoneKey() { - return MemoryValue::get(DenseMapInfo::getTombstoneKey()); + return DenseMapInfo::getTombstoneKey(); } static unsigned getHashValue(MemoryValue Val); static bool isEqual(MemoryValue LHS, MemoryValue RHS); @@ -317,7 +313,7 @@ // If this is a simple instruction that we can value number, process it. if (SimpleValue::canHandle(Inst)) { // See if the instruction has an available value. If so, use it. - if (Value *V = AvailableValues->lookup(SimpleValue::get(Inst))) { + if (Value *V = AvailableValues->lookup(Inst)) { DEBUG(dbgs() << "EarlyCSE CSE: " << *Inst << " to: " << *V << '\n'); Inst->replaceAllUsesWith(V); Inst->eraseFromParent(); @@ -327,7 +323,7 @@ } // Otherwise, just remember that this value is available. - AvailableValues->insert(SimpleValue::get(Inst), Inst); + AvailableValues->insert(Inst, Inst); continue; } @@ -335,8 +331,7 @@ if (MemoryValue::canHandle(Inst)) { // If we have an available version of this value, and if it is the right // generation, replace this instruction. - std::pair InVal = - AvailableMemValues->lookup(MemoryValue::get(Inst)); + std::pair InVal = AvailableMemValues->lookup(Inst); if (InVal.first != 0 && InVal.second == CurrentGeneration) { DEBUG(dbgs() << "EarlyCSE CSE MEM: " << *Inst << " to: " << *InVal.first << '\n'); @@ -348,7 +343,7 @@ } // Otherwise, remember that we have this instruction. - AvailableMemValues->insert(MemoryValue::get(Inst), + AvailableMemValues->insert(Inst, std::pair(Inst, CurrentGeneration)); continue; } From sabre at nondot.org Sun Jan 2 21:33:47 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 03:33:47 -0000 Subject: [llvm-commits] [llvm] r122730 - /llvm/trunk/test/Transforms/EarlyCSE/basic.ll Message-ID: <20110103033347.BFDEB2A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 21:33:47 2011 New Revision: 122730 URL: http://llvm.org/viewvc/llvm-project?rev=122730&view=rev Log: add a testcase for readonly call CSE Modified: llvm/trunk/test/Transforms/EarlyCSE/basic.ll Modified: llvm/trunk/test/Transforms/EarlyCSE/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/basic.ll?rev=122730&r1=122729&r2=122730&view=diff ============================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/basic.ll (original) +++ llvm/trunk/test/Transforms/EarlyCSE/basic.ll Sun Jan 2 21:33:47 2011 @@ -75,3 +75,15 @@ ; CHECK: F: ; CHECK: ret i32 %Diff } + +declare i32 @func(i32 *%P) readonly + +;; Simple call CSE'ing. +; CHECK: @test5 +define i32 @test5(i32 *%P) { + %V1 = call i32 @func(i32* %P) + %V2 = call i32 @func(i32* %P) + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK: ret i32 0 +} From sabre at nondot.org Sun Jan 2 21:41:27 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 03:41:27 -0000 Subject: [llvm-commits] [llvm] r122731 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Message-ID: <20110103034128.092322A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 21:41:27 2011 New Revision: 122731 URL: http://llvm.org/viewvc/llvm-project?rev=122731&view=rev Log: split loads and calls into separate tables. Loads are now just indexed by their pointer instead of using MemoryValue to wrap it. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122731&r1=122730&r2=122731&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 21:41:27 2011 @@ -28,7 +28,8 @@ STATISTIC(NumSimplify, "Number of instructions simplified or DCE'd"); STATISTIC(NumCSE, "Number of instructions CSE'd"); -STATISTIC(NumCSEMem, "Number of load and call instructions CSE'd"); +STATISTIC(NumCSELoad, "Number of load instructions CSE'd"); +STATISTIC(NumCSECall, "Number of call instructions CSE'd"); static unsigned getHash(const void *V) { return DenseMapInfo::getHashValue(V); @@ -124,16 +125,16 @@ } //===----------------------------------------------------------------------===// -// MemoryValue +// CallValue //===----------------------------------------------------------------------===// namespace { - /// MemoryValue - Instances of this struct represent available load and call - /// values in the scoped hash table. - struct MemoryValue { + /// CallValue - Instances of this struct represent available call values in + /// the scoped hash table. + struct CallValue { Instruction *Inst; - MemoryValue(Instruction *I) : Inst(I) { + CallValue(Instruction *I) : Inst(I) { assert((isSentinel() || canHandle(I)) && "Inst can't be handled!"); } @@ -143,8 +144,6 @@ } static bool canHandle(Instruction *Inst) { - if (LoadInst *LI = dyn_cast(Inst)) - return !LI->isVolatile(); if (CallInst *CI = dyn_cast(Inst)) return CI->onlyReadsMemory(); return false; @@ -153,23 +152,23 @@ } namespace llvm { - // MemoryValue is POD. - template<> struct isPodLike { + // CallValue is POD. + template<> struct isPodLike { static const bool value = true; }; - template<> struct DenseMapInfo { - static inline MemoryValue getEmptyKey() { + template<> struct DenseMapInfo { + static inline CallValue getEmptyKey() { return DenseMapInfo::getEmptyKey(); } - static inline MemoryValue getTombstoneKey() { + static inline CallValue getTombstoneKey() { return DenseMapInfo::getTombstoneKey(); } - static unsigned getHashValue(MemoryValue Val); - static bool isEqual(MemoryValue LHS, MemoryValue RHS); + static unsigned getHashValue(CallValue Val); + static bool isEqual(CallValue LHS, CallValue RHS); }; } -unsigned DenseMapInfo::getHashValue(MemoryValue Val) { +unsigned DenseMapInfo::getHashValue(CallValue Val) { Instruction *Inst = Val.Inst; // Hash in all of the operands as pointers. unsigned Res = 0; @@ -179,13 +178,10 @@ return (Res << 1) ^ Inst->getOpcode(); } -bool DenseMapInfo::isEqual(MemoryValue LHS, MemoryValue RHS) { +bool DenseMapInfo::isEqual(CallValue LHS, CallValue RHS) { Instruction *LHSI = LHS.Inst, *RHSI = RHS.Inst; - if (LHS.isSentinel() || RHS.isSentinel()) return LHSI == RHSI; - - if (LHSI->getOpcode() != RHSI->getOpcode()) return false; return LHSI->isIdenticalTo(RHSI); } @@ -218,16 +214,20 @@ /// their lookup. ScopedHTType *AvailableValues; - typedef ScopedHashTable > MemHTType; - /// AvailableMemValues - This scoped hash table contains the current values of - /// loads and other read-only memory values. This allows us to get efficient - /// access to dominating loads we we find a fully redundant load. In addition - /// to the most recent load, we keep track of a generation count of the read, - /// which is compared against the current generation count. The current - /// generation count is incremented after every possibly writing memory - /// operation, which ensures that we only CSE loads with other loads that have - /// no intervening store. - MemHTType *AvailableMemValues; + /// AvailableLoads - This scoped hash table contains the current values + /// of loads. This allows us to get efficient access to dominating loads when + /// we have a fully redundant load. In addition to the most recent load, we + /// keep track of a generation count of the read, which is compared against + /// the current generation count. The current generation count is + /// incremented after every possibly writing memory operation, which ensures + /// that we only CSE loads with other loads that have no intervening store. + typedef ScopedHashTable > LoadHTType; + LoadHTType *AvailableLoads; + + /// AvailableCalls - This scoped hash table contains the current values + /// of read-only call values. It uses the same generation count as loads. + typedef ScopedHashTable > CallHTType; + CallHTType *AvailableCalls; /// CurrentGeneration - This is the current generation of the memory value. unsigned CurrentGeneration; @@ -268,9 +268,13 @@ // off all the values we install. ScopedHTType::ScopeTy Scope(*AvailableValues); - // Define a scope for the memory values so that anything we add will get + // Define a scope for the load values so that anything we add will get + // popped when we recurse back up to our parent domtree node. + LoadHTType::ScopeTy LoadScope(*AvailableLoads); + + // Define a scope for the call values so that anything we add will get // popped when we recurse back up to our parent domtree node. - MemHTType::ScopeTy MemScope(*AvailableMemValues); + CallHTType::ScopeTy CallScope(*AvailableCalls); BasicBlock *BB = Node->getBlock(); @@ -327,23 +331,48 @@ continue; } - // If this is a read-only memory value, process it. - if (MemoryValue::canHandle(Inst)) { - // If we have an available version of this value, and if it is the right + // If this is a non-volatile load, process it. + if (LoadInst *LI = dyn_cast(Inst)) { + // Ignore volatile loads. + if (LI->isVolatile()) continue; + + // If we have an available version of this load, and if it is the right + // generation, replace this instruction. + std::pair InVal = + AvailableLoads->lookup(Inst->getOperand(0)); + if (InVal.first != 0 && InVal.second == CurrentGeneration) { + DEBUG(dbgs() << "EarlyCSE CSE LOAD: " << *Inst << " to: " + << *InVal.first << '\n'); + if (!Inst->use_empty()) Inst->replaceAllUsesWith(InVal.first); + Inst->eraseFromParent(); + Changed = true; + ++NumCSELoad; + continue; + } + + // Otherwise, remember that we have this instruction. + AvailableLoads->insert(Inst->getOperand(0), + std::pair(Inst, CurrentGeneration)); + continue; + } + + // If this is a read-only call, process it. + if (CallValue::canHandle(Inst)) { + // If we have an available version of this call, and if it is the right // generation, replace this instruction. - std::pair InVal = AvailableMemValues->lookup(Inst); + std::pair InVal = AvailableCalls->lookup(Inst); if (InVal.first != 0 && InVal.second == CurrentGeneration) { - DEBUG(dbgs() << "EarlyCSE CSE MEM: " << *Inst << " to: " + DEBUG(dbgs() << "EarlyCSE CSE CALL: " << *Inst << " to: " << *InVal.first << '\n'); if (!Inst->use_empty()) Inst->replaceAllUsesWith(InVal.first); Inst->eraseFromParent(); Changed = true; - ++NumCSEMem; + ++NumCSECall; continue; } // Otherwise, remember that we have this instruction. - AvailableMemValues->insert(Inst, + AvailableCalls->insert(Inst, std::pair(Inst, CurrentGeneration)); continue; } @@ -368,11 +397,14 @@ bool EarlyCSE::runOnFunction(Function &F) { TD = getAnalysisIfAvailable(); DT = &getAnalysis(); + + // Tables that the pass uses when walking the domtree. ScopedHTType AVTable; AvailableValues = &AVTable; - - MemHTType MemTable; - AvailableMemValues = &MemTable; + LoadHTType LoadTable; + AvailableLoads = &LoadTable; + CallHTType CallTable; + AvailableCalls = &CallTable; CurrentGeneration = 0; return processNode(DT->getRootNode()); From sabre at nondot.org Sun Jan 2 21:46:34 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 03:46:34 -0000 Subject: [llvm-commits] [llvm] r122732 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/basic.ll Message-ID: <20110103034634.9D5C82A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 21:46:34 2011 New Revision: 122732 URL: http://llvm.org/viewvc/llvm-project?rev=122732&view=rev Log: now that loads are in their own table, we can implement store->load forwarding. This allows EarlyCSE to zap 600 more loads from 176.gcc. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp llvm/trunk/test/Transforms/EarlyCSE/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122732&r1=122731&r2=122732&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 21:46:34 2011 @@ -380,8 +380,19 @@ // Okay, this isn't something we can CSE at all. Check to see if it is // something that could modify memory. If so, our available memory values // cannot be used so bump the generation count. - if (Inst->mayWriteToMemory()) + if (Inst->mayWriteToMemory()) { ++CurrentGeneration; + + // Okay, we just invalidated anything we knew about loaded values. Try to + // salvage *something* by remembering that the stored value is a live + // version of the pointer. It is safe to forward from volatile stores to + // non-volatile loads, so we don't have to check for volatility of the + // store. + if (StoreInst *SI = dyn_cast(Inst)) { + AvailableLoads->insert(SI->getPointerOperand(), + std::pair(SI->getValueOperand(), CurrentGeneration)); + } + } } unsigned LiveOutGeneration = CurrentGeneration; Modified: llvm/trunk/test/Transforms/EarlyCSE/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/basic.ll?rev=122732&r1=122731&r2=122732&view=diff ============================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/basic.ll (original) +++ llvm/trunk/test/Transforms/EarlyCSE/basic.ll Sun Jan 2 21:46:34 2011 @@ -87,3 +87,12 @@ ret i32 %Diff ; CHECK: ret i32 0 } + +;; Trivial Store->load forwarding +; CHECK: @test6 +define i32 @test6(i32 *%P) { + store i32 42, i32* %P + %V1 = load i32* %P + ret i32 %V1 + ; CHECK: ret i32 42 +} From sabre at nondot.org Sun Jan 2 21:53:50 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 03:53:50 -0000 Subject: [llvm-commits] [llvm] r122733 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Message-ID: <20110103035350.2E1462A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 21:53:50 2011 New Revision: 122733 URL: http://llvm.org/viewvc/llvm-project?rev=122733&view=rev Log: switch the load table to use a recycling bump pointer allocator, speeding earlycse up by 6%. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122733&r1=122732&r2=122733&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 21:53:50 2011 @@ -221,7 +221,10 @@ /// the current generation count. The current generation count is /// incremented after every possibly writing memory operation, which ensures /// that we only CSE loads with other loads that have no intervening store. - typedef ScopedHashTable > LoadHTType; + typedef RecyclingAllocator > > LoadMapAllocator; + typedef ScopedHashTable, + DenseMapInfo, LoadMapAllocator> LoadHTType; LoadHTType *AvailableLoads; /// AvailableCalls - This scoped hash table contains the current values From nicholas at mxc.ca Sun Jan 2 22:01:44 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 03 Jan 2011 04:01:44 -0000 Subject: [llvm-commits] [llvm] r122734 - /llvm/trunk/docs/WritingAnLLVMPass.html Message-ID: <20110103040145.13BB92A6C12C@llvm.org> Author: nicholas Date: Sun Jan 2 22:01:44 2011 New Revision: 122734 URL: http://llvm.org/viewvc/llvm-project?rev=122734&view=rev Log: Permit CallGraphSCCPasses readonly access to the direct callers of the functions in their SCC as they already have with the direct callees. Modified: llvm/trunk/docs/WritingAnLLVMPass.html Modified: llvm/trunk/docs/WritingAnLLVMPass.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/WritingAnLLVMPass.html?rev=122734&r1=122733&r2=122734&view=diff ============================================================================== --- llvm/trunk/docs/WritingAnLLVMPass.html (original) +++ llvm/trunk/docs/WritingAnLLVMPass.html Sun Jan 2 22:01:44 2011 @@ -562,8 +562,8 @@
    1. ... not allowed to modify any Functions that are not in the current SCC.
    2. -
    3. ... not allowed to inspect any Function's other than those in the -current SCC and the direct callees of the SCC.
    4. +
    5. ... not allowed to inspect any Functions other than those +in the current SCC and the direct callers and direct callees of the SCC.
    6. ... required to preserve the current CallGraph object, updating it to reflect any changes made to the program.
    7. From zwarich at apple.com Sun Jan 2 22:07:46 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 03 Jan 2011 04:07:46 -0000 Subject: [llvm-commits] [llvm] r122735 - /llvm/trunk/lib/CodeGen/MachineCSE.cpp Message-ID: <20110103040746.D17DB2A6C12C@llvm.org> Author: zwarich Date: Sun Jan 2 22:07:46 2011 New Revision: 122735 URL: http://llvm.org/viewvc/llvm-project?rev=122735&view=rev Log: Use a RecyclingAllocator to allocate values for MachineCSE's ScopedHashTable for a 28% speedup of MachineCSE time on 403.gcc. Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=122735&r1=122734&r2=122735&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Sun Jan 2 22:07:46 2011 @@ -25,6 +25,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/RecyclingAllocator.h" using namespace llvm; @@ -65,10 +66,13 @@ private: const unsigned LookAheadLimit; - typedef ScopedHashTableScope ScopeType; + typedef RecyclingAllocator > AllocatorTy; + typedef ScopedHashTable ScopedHTType; + typedef ScopedHTType::ScopeTy ScopeType; DenseMap ScopeMap; - ScopedHashTable VNT; + ScopedHTType VNT; SmallVector Exps; unsigned CurrVN; From sabre at nondot.org Sun Jan 2 22:17:24 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 04:17:24 -0000 Subject: [llvm-commits] [llvm] r122736 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/basic.ll Message-ID: <20110103041724.3C9C52A6C12C@llvm.org> Author: lattner Date: Sun Jan 2 22:17:24 2011 New Revision: 122736 URL: http://llvm.org/viewvc/llvm-project?rev=122736&view=rev Log: earlycse can do trivial with-a-block dead store elimination as well. This deletes 60 stores in 176.gcc that largely come from bitfield code. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp llvm/trunk/test/Transforms/EarlyCSE/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122736&r1=122735&r2=122736&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Sun Jan 2 22:17:24 2011 @@ -30,6 +30,7 @@ STATISTIC(NumCSE, "Number of instructions CSE'd"); STATISTIC(NumCSELoad, "Number of load instructions CSE'd"); STATISTIC(NumCSECall, "Number of call instructions CSE'd"); +STATISTIC(NumDSE, "Number of trivial dead stores removed"); static unsigned getHash(const void *V) { return DenseMapInfo::getHashValue(V); @@ -290,6 +291,12 @@ if (BB->getSinglePredecessor() == 0) ++CurrentGeneration; + /// LastStore - Keep track of the last non-volatile store that we saw... for + /// as long as there in no instruction that reads memory. If we see a store + /// to the same location, we delete the dead store. This zaps trivial dead + /// stores which can occur in bitfield code among other things. + StoreInst *LastStore = 0; + bool Changed = false; // See if any instructions in the block can be eliminated. If so, do it. If @@ -337,7 +344,10 @@ // If this is a non-volatile load, process it. if (LoadInst *LI = dyn_cast(Inst)) { // Ignore volatile loads. - if (LI->isVolatile()) continue; + if (LI->isVolatile()) { + LastStore = 0; + continue; + } // If we have an available version of this load, and if it is the right // generation, replace this instruction. @@ -356,9 +366,14 @@ // Otherwise, remember that we have this instruction. AvailableLoads->insert(Inst->getOperand(0), std::pair(Inst, CurrentGeneration)); + LastStore = 0; continue; } + // If this instruction may read from memory, forget LastStore. + if (Inst->mayReadFromMemory()) + LastStore = 0; + // If this is a read-only call, process it. if (CallValue::canHandle(Inst)) { // If we have an available version of this call, and if it is the right @@ -386,14 +401,31 @@ if (Inst->mayWriteToMemory()) { ++CurrentGeneration; - // Okay, we just invalidated anything we knew about loaded values. Try to - // salvage *something* by remembering that the stored value is a live - // version of the pointer. It is safe to forward from volatile stores to - // non-volatile loads, so we don't have to check for volatility of the - // store. if (StoreInst *SI = dyn_cast(Inst)) { + // We do a trivial form of DSE if there are two stores to the same + // location with no intervening loads. Delete the earlier store. + if (LastStore && + LastStore->getPointerOperand() == SI->getPointerOperand()) { + DEBUG(dbgs() << "EarlyCSE DEAD STORE: " << *LastStore << " due to: " + << *Inst << '\n'); + LastStore->eraseFromParent(); + Changed = true; + ++NumDSE; + LastStore = 0; + continue; + } + + // Okay, we just invalidated anything we knew about loaded values. Try + // to salvage *something* by remembering that the stored value is a live + // version of the pointer. It is safe to forward from volatile stores + // to non-volatile loads, so we don't have to check for volatility of + // the store. AvailableLoads->insert(SI->getPointerOperand(), std::pair(SI->getValueOperand(), CurrentGeneration)); + + // Remember that this was the last store we saw for DSE. + if (!SI->isVolatile()) + LastStore = SI; } } } Modified: llvm/trunk/test/Transforms/EarlyCSE/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/basic.ll?rev=122736&r1=122735&r2=122736&view=diff ============================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/basic.ll (original) +++ llvm/trunk/test/Transforms/EarlyCSE/basic.ll Sun Jan 2 22:17:24 2011 @@ -96,3 +96,13 @@ ret i32 %V1 ; CHECK: ret i32 42 } + +;; Trivial dead store elimination. +; CHECK: @test7 +define void @test7(i32 *%P) { + store i32 42, i32* %P + store i32 45, i32* %P + ret void + ; CHECK-NEXT: store i32 45 + ; CHECK-NEXT: ret void +} From aggarwa4 at illinois.edu Sun Jan 2 22:26:43 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 03 Jan 2011 04:26:43 -0000 Subject: [llvm-commits] [poolalloc] r122737 - /poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Message-ID: <20110103042643.8EC582A6C12C@llvm.org> Author: aggarwa4 Date: Sun Jan 2 22:26:43 2011 New Revision: 122737 URL: http://llvm.org/viewvc/llvm-project?rev=122737&view=rev Log: Formatting changes. Remove dead code. No functionality change. Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=122737&r1=122736&r2=122737&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Sun Jan 2 22:26:43 2011 @@ -58,13 +58,12 @@ template void AddPoolUse(InstType &I, Value *PoolHandle, SetType &Set) { - if (AllocaInst *AI=dyn_cast(PoolHandle->stripPointerCasts())) + if (AllocaInst *AI = dyn_cast(PoolHandle->stripPointerCasts())) Set.insert(std::make_pair(AI, &I)); } // FIXME: Factor out assumptions about c stdlib function names void visitInstruction(Instruction &I); - //void visitMallocInst(MallocInst &MI); void visitAllocaInst(AllocaInst &MI); void visitMallocCall(CallSite & CS); void visitCallocCall(CallSite CS); @@ -72,7 +71,6 @@ void visitMemAlignCall(CallSite CS); void visitStrdupCall(CallSite CS); void visitRuntimeCheck(CallSite CS); - //void visitFreeInst(FreeInst &FI); void visitFreeCall(CallSite &CS); void visitCallSite(CallSite &CS); void visitCallInst(CallInst &CI) {