From sabre at nondot.org Mon Nov 2 00:06:14 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 06:06:14 -0000 Subject: [llvm-commits] [llvm] r85789 - in /llvm/trunk: lib/Transforms/Scalar/SCCP.cpp test/Transforms/SCCP/loadtest.ll Message-ID: <200911020606.nA266EZ5001541@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 00:06:14 2009 New Revision: 85789 URL: http://llvm.org/viewvc/llvm-project?rev=85789&view=rev Log: Use the libanalysis 'ConstantFoldLoadFromConstPtr' function instead of reinventing SCCP-specific logic. This gives us new powers. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp llvm/trunk/test/Transforms/SCCP/loadtest.ll Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85789&r1=85788&r2=85789&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 00:06:14 2009 @@ -28,6 +28,7 @@ #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Target/TargetData.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -154,6 +155,7 @@ /// Constant Propagation. /// class SCCPSolver : public InstVisitor { + const TargetData *TD; DenseSet BBExecutable;// The basic blocks that are executable DenseMap ValueState; // The state each value is in. @@ -194,6 +196,7 @@ typedef std::pair Edge; DenseSet KnownFeasibleEdges; public: + SCCPSolver(const TargetData *td) : TD(td) {} /// MarkBlockExecutable - This method can be used by clients to mark all of /// the blocks that are known to be intrinsically live in the processed unit. @@ -1109,16 +1112,15 @@ // global, we can replace the load with the loaded constant value! void SCCPSolver::visitLoadInst(LoadInst &I) { LatticeVal PtrVal = getValueState(I.getOperand(0)); + if (PtrVal.isUndefined()) return; // The pointer is not resolved yet! LatticeVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; - if (PtrVal.isUndefined()) return; // The pointer is not resolved yet! - if (!PtrVal.isConstant() || I.isVolatile()) return markOverdefined(IV, &I); - Value *Ptr = PtrVal.getConstant(); + Constant *Ptr = PtrVal.getConstant(); // load null -> null if (isa(Ptr) && I.getPointerAddressSpace() == 0) @@ -1126,11 +1128,7 @@ // Transform load (constant global) into the value loaded. if (GlobalVariable *GV = dyn_cast(Ptr)) { - if (GV->isConstant()) { - if (GV->hasDefinitiveInitializer()) - return markConstant(IV, &I, GV->getInitializer()); - - } else if (!TrackedGlobals.empty()) { + if (!TrackedGlobals.empty()) { // If we are tracking this global, merge in the known value for it. DenseMap::iterator It = TrackedGlobals.find(GV); @@ -1141,14 +1139,9 @@ } } - // Transform load (constantexpr_GEP global, 0, ...) into the value loaded. - if (ConstantExpr *CE = dyn_cast(Ptr)) - if (CE->getOpcode() == Instruction::GetElementPtr) - if (GlobalVariable *GV = dyn_cast(CE->getOperand(0))) - if (GV->isConstant() && GV->hasDefinitiveInitializer()) - if (Constant *V = - ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE)) - return markConstant(IV, &I, V); + // Transform load from a constant into a constant if possible. + if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, TD)) + return markConstant(IV, &I, C); // Otherwise we cannot say for certain what value this load will produce. // Bail out. @@ -1530,7 +1523,7 @@ // bool SCCP::runOnFunction(Function &F) { DEBUG(errs() << "SCCP on function '" << F.getName() << "'\n"); - SCCPSolver Solver; + SCCPSolver Solver(getAnalysisIfAvailable()); // Mark the first block of the function as being executable. Solver.MarkBlockExecutable(F.begin()); @@ -1640,7 +1633,7 @@ } bool IPSCCP::runOnModule(Module &M) { - SCCPSolver Solver; + SCCPSolver Solver(getAnalysisIfAvailable()); // Loop over all functions, marking arguments to those with their addresses // taken or that are external as overdefined. Modified: llvm/trunk/test/Transforms/SCCP/loadtest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/loadtest.ll?rev=85789&r1=85788&r2=85789&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/loadtest.ll (original) +++ llvm/trunk/test/Transforms/SCCP/loadtest.ll Mon Nov 2 00:06:14 2009 @@ -1,5 +1,6 @@ ; This test makes sure that these instructions are properly constant propagated. -; + +target datalayout = "e-p:32:32" ; RUN: opt < %s -sccp -S | not grep load @@ -20,7 +21,13 @@ define i32 @test3() { %A = getelementptr [2 x { i32, float }]* @Y, i64 0, i64 0, i32 0 ; [#uses=1] - %B = load i32* %A ; [#uses=1] + %B = load i32* %A ret i32 %B } +define i8 @test4() { + %A = bitcast i32* @X to i8* + %B = load i8* %A + ret i8 %B +} + From sabre at nondot.org Mon Nov 2 00:11:24 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 06:11:24 -0000 Subject: [llvm-commits] [llvm] r85790 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911020611.nA26BOrk001896@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 00:11:23 2009 New Revision: 85790 URL: http://llvm.org/viewvc/llvm-project?rev=85790&view=rev Log: avoid redundant lookups in BBExecutable, and make it a SmallPtrSet. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85790&r1=85789&r2=85790&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 00:11:23 2009 @@ -37,6 +37,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" @@ -156,7 +157,7 @@ /// class SCCPSolver : public InstVisitor { const TargetData *TD; - DenseSet BBExecutable;// The basic blocks that are executable + SmallPtrSet BBExecutable;// The BBs that are executable. DenseMap ValueState; // The state each value is in. /// GlobalValue - If we are tracking any values for the contents of a global @@ -200,10 +201,13 @@ /// MarkBlockExecutable - This method can be used by clients to mark all of /// the blocks that are known to be intrinsically live in the processed unit. - void MarkBlockExecutable(BasicBlock *BB) { + /// + /// This returns true if the block was not considered live before. + bool MarkBlockExecutable(BasicBlock *BB) { + if (!BBExecutable.insert(BB)) return false; DEBUG(errs() << "Marking Block Executable: " << BB->getName() << "\n"); - BBExecutable.insert(BB); // Basic block is executable! BBWorkList.push_back(BB); // Add the block to the work list! + return true; } /// TrackValueOfGlobalVariable - Clients can use this method to @@ -348,18 +352,17 @@ if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second) return; // This edge is already known to be executable! - if (BBExecutable.count(Dest)) { - DEBUG(errs() << "Marking Edge Executable: " << Source->getName() - << " -> " << Dest->getName() << "\n"); - - // The destination is already executable, but we just made an edge + if (!MarkBlockExecutable(Dest)) { + // If the destination is already executable, we just made an *edge* // feasible that wasn't before. Revisit the PHI nodes in the block // because they have potentially new operands. - for (BasicBlock::iterator I = Dest->begin(); isa(I); ++I) - visitPHINode(*cast(I)); + DEBUG(errs() << "Marking Edge Executable: " << Source->getName() + << " -> " << Dest->getName() << "\n"); - } else { - MarkBlockExecutable(Dest); + PHINode *PN; + for (BasicBlock::iterator I = Dest->begin(); + (PN = dyn_cast(I)); ++I) + visitPHINode(*PN); } } @@ -1229,8 +1232,7 @@ // Finally, if this is the first call to the function hit, mark its entry // block executable. - if (!BBExecutable.count(F->begin())) - MarkBlockExecutable(F->begin()); + MarkBlockExecutable(F->begin()); // Propagate information from this call site into the callee. CallSite::arg_iterator CAI = CS.arg_begin(); From sabre at nondot.org Mon Nov 2 00:17:08 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 06:17:08 -0000 Subject: [llvm-commits] [llvm] r85791 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911020617.nA26H8MD002290@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 00:17:06 2009 New Revision: 85791 URL: http://llvm.org/viewvc/llvm-project?rev=85791&view=rev Log: remove some confused code that dates from when we had "multiple return values" but not "first class aggregates" Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85791&r1=85790&r2=85791&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 00:17:06 2009 @@ -661,16 +661,8 @@ } // Handle functions that return multiple values. - if (0 && !TrackedMultipleRetVals.empty() && I.getNumOperands() > 1) { - for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { - DenseMap, LatticeVal>::iterator - It = TrackedMultipleRetVals.find(std::make_pair(F, i)); - if (It == TrackedMultipleRetVals.end()) break; - mergeInValue(It->second, F, getValueState(I.getOperand(i))); - } - } else if (!TrackedMultipleRetVals.empty() && - /*I.getNumOperands() == 1 &&*/ - isa(I.getOperand(0)->getType())) { + if (!TrackedMultipleRetVals.empty() && + isa(I.getOperand(0)->getType())) { for (unsigned i = 0, e = I.getOperand(0)->getType()->getNumContainedTypes(); i != e; ++i) { DenseMap, LatticeVal>::iterator From sabre at nondot.org Mon Nov 2 00:28:16 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 06:28:16 -0000 Subject: [llvm-commits] [llvm] r85792 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911020628.nA26SGpw002768@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 00:28:16 2009 New Revision: 85792 URL: http://llvm.org/viewvc/llvm-project?rev=85792&view=rev Log: restore some code I removed in r85788, refactor it into a shared place instead of duplicating it 4 times. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85792&r1=85791&r2=85792&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 00:28:16 2009 @@ -386,6 +386,20 @@ if (BBExecutable.count(I.getParent())) // Inst is executable? visit(I); } + + /// RemoveFromOverdefinedPHIs - If I has any entries in the + /// UsersOfOverdefinedPHIs map for PN, remove them now. + void RemoveFromOverdefinedPHIs(Instruction *I, PHINode *PN) { + if (UsersOfOverdefinedPHIs.empty()) return; + std::multimap::iterator It, E; + tie(It, E) = UsersOfOverdefinedPHIs.equal_range(PN); + while (It != E) { + if (It->second == I) + UsersOfOverdefinedPHIs.erase(It++); + else + ++It; + } + } private: friend class InstVisitor; @@ -904,8 +918,8 @@ // added ourselves to the UsersOfOverdefinedPHIs list for the PHIs, // make sure to clean out any entries that we put there, for // efficiency. - UsersOfOverdefinedPHIs.erase(PN1); - UsersOfOverdefinedPHIs.erase(PN2); + RemoveFromOverdefinedPHIs(&I, PN1); + RemoveFromOverdefinedPHIs(&I, PN2); } markOverdefined(&I); @@ -986,8 +1000,8 @@ // added ourselves to the UsersOfOverdefinedPHIs list for the PHIs, // make sure to clean out any entries that we put there, for // efficiency. - UsersOfOverdefinedPHIs.erase(PN1); - UsersOfOverdefinedPHIs.erase(PN2); + RemoveFromOverdefinedPHIs(&I, PN1); + RemoveFromOverdefinedPHIs(&I, PN2); } markOverdefined(&I); From sabre at nondot.org Mon Nov 2 00:34:04 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 06:34:04 -0000 Subject: [llvm-commits] [llvm] r85793 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911020634.nA26Y5G1003017@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 00:34:04 2009 New Revision: 85793 URL: http://llvm.org/viewvc/llvm-project?rev=85793&view=rev Log: don't mark the arguments of prototype overdefined, they will never be queried. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85793&r1=85792&r2=85793&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 00:34:04 2009 @@ -1646,16 +1646,19 @@ // Loop over all functions, marking arguments to those with their addresses // taken or that are external as overdefined. // - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { + if (F->isDeclaration()) + continue; + if (!F->hasLocalLinkage() || AddressIsTaken(F)) { - if (!F->isDeclaration()) - Solver.MarkBlockExecutable(F->begin()); + Solver.MarkBlockExecutable(F->begin()); for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI) Solver.markOverdefined(AI); } else { Solver.AddTrackedFunction(F); } + } // Loop over global variables. We inform the solver about any internal global // variables that do not have their 'addresses taken'. If they don't have From asl at math.spbu.ru Mon Nov 2 01:01:14 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 2 Nov 2009 10:01:14 +0300 Subject: [llvm-commits] [llvm] r85764 - in /llvm/trunk/lib/Target/ARM: ARM.td ARMBaseInstrInfo.cpp ARMBaseInstrInfo.h ARMInstrFormats.td ARMInstrInfo.cpp ARMInstrInfo.h Thumb1InstrInfo.cpp Thumb2InstrInfo.cpp In-Reply-To: <2DB4E637-9985-4FC7-8D08-2DB1B17BD341@apple.com> References: <200911020010.nA20Ade4021334@zion.cs.uiuc.edu> <2DB4E637-9985-4FC7-8D08-2DB1B17BD341@apple.com> Message-ID: Hello, Evan > What is "canXformTo16Bit" for? It seems that this flag is currently unused, I added it for the sake of completeness. I don't know - maybe the flag should be removed at all. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From asl at math.spbu.ru Mon Nov 2 01:04:41 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 2 Nov 2009 10:04:41 +0300 Subject: [llvm-commits] [llvm] r85764 - in /llvm/trunk/lib/Target/ARM: ARM.td ARMBaseInstrInfo.cpp ARMBaseInstrInfo.h ARMInstrFormats.td ARMInstrInfo.cpp ARMInstrInfo.h Thumb1InstrInfo.cpp Thumb2InstrInfo.cpp In-Reply-To: References: <200911020010.nA20Ade4021334@zion.cs.uiuc.edu> <7703A6BF-6F9F-4636-961C-23B5080B78A2@apple.com> Message-ID: Hello, Evan > 1. When the register is virtual, it could have used > machineregisterinfo to find the def. It would have been much faster. Yes, however, I never saw such case in (rather huge) real codes. I will add it. > 2. When the register is physical it can scan all the way to the top of > the MBB, that's extremely expensive. Do we have any better way? It seems - no. We need to find the def of the register which is closest to the insertion point. Even if some instruction numbering would be saved after RA, then iterating of instructions seems to be cheaper than iterating over defs of the phys reg. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From evan.cheng at apple.com Mon Nov 2 01:08:49 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 1 Nov 2009 23:08:49 -0800 Subject: [llvm-commits] [llvm] r85764 - in /llvm/trunk/lib/Target/ARM: ARM.td ARMBaseInstrInfo.cpp ARMBaseInstrInfo.h ARMInstrFormats.td ARMInstrInfo.cpp ARMInstrInfo.h Thumb1InstrInfo.cpp Thumb2InstrInfo.cpp In-Reply-To: References: <200911020010.nA20Ade4021334@zion.cs.uiuc.edu> <7703A6BF-6F9F-4636-961C-23B5080B78A2@apple.com> Message-ID: On Nov 1, 2009, at 11:04 PM, Anton Korobeynikov wrote: > Hello, Evan > >> 1. When the register is virtual, it could have used >> machineregisterinfo to find the def. It would have been much faster. > Yes, however, I never saw such case in (rather huge) real codes. I > will add it. > >> 2. When the register is physical it can scan all the way to the top >> of >> the MBB, that's extremely expensive. > Do we have any better way? It seems - no. We need to find the def of > the > register which is closest to the insertion point. Even if some > instruction > numbering would be saved after RA, then iterating of instructions > seems to > be cheaper than iterating over defs of the phys reg. This has to be done in a late pass which can walk basic blocks from top down and tracking the domain of every register. When it sees a fcpyd, it knows the domain of source register and can change it. The current implementation really is a non-starter, especially for JIT. Can you disable it for now? Evan > > -- > With best regards, Anton Korobeynikov > Faculty of Mathematics and Mechanics, Saint Petersburg State > University From evan.cheng at apple.com Mon Nov 2 01:11:55 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 02 Nov 2009 07:11:55 -0000 Subject: [llvm-commits] [llvm] r85794 - /llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll Message-ID: <200911020711.nA27Bt3h004523@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 2 01:11:54 2009 New Revision: 85794 URL: http://llvm.org/viewvc/llvm-project?rev=85794&view=rev Log: Remove an irrelevant and poorly reduced test case. Removed: llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll Removed: llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll?rev=85793&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll (removed) @@ -1,414 +0,0 @@ -; RUN: llc < %s -mtriple=arm-apple-darwin9 -stats |& grep asm-printer | grep 154 - - %"struct.Adv5::Ekin<3>" = type <{ i8 }> - %"struct.Adv5::X::Energyflux<3>" = type { double } - %"struct.BinaryNode >, double, MultiPatchView, 3> >,Field >, double, MultiPatchView, 3> > >" = type { %"struct.Field >,double,MultiPatchView, 3> >", %"struct.Field >,double,MultiPatchView, 3> >" } - %"struct.BinaryNode >, double, Remote >,Field >, double, Remote > >" = type { %"struct.Field >,double,Remote >", %"struct.Field >,double,Remote >" } - %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >" = type { %"struct.Adv5::X::Energyflux<3>", %"struct.BinaryNode >, double, MultiPatchView, 3> >,Field >, double, MultiPatchView, 3> > >" } - %"struct.BinaryNode,BinaryNode >, double, Remote >, Field >, double, Remote > > >" = type { %"struct.Adv5::X::Energyflux<3>", %"struct.BinaryNode >, double, Remote >,Field >, double, Remote > >" } - %"struct.Centering<3>" = type { i32, i32, %"struct.std::vector,std::allocator > >", %"struct.std::vector,std::allocator > >" } - %"struct.ContextMapper<1>" = type { i32 (...)** } - %"struct.DataBlockController" = type { %"struct.RefBlockController", %"struct.Adv5::Ekin<3>"*, i8, %"struct.SingleObservable", i32 } - %"struct.DataBlockPtr" = type { %"struct.RefCountedBlockPtr >" } - %"struct.Domain<1,DomainTraits > >" = type { %"struct.DomainBase > >" } - %"struct.Domain<1,DomainTraits > >" = type { %"struct.DomainBase > >" } - %"struct.Domain<1,DomainTraits > >" = type { %"struct.DomainBase > >" } - %"struct.Domain<3,DomainTraits > >" = type { %"struct.DomainBase > >" } - %"struct.Domain<3,DomainTraits > >" = type { %"struct.DomainBase > >" } - %"struct.Domain<3,DomainTraits > >" = type { %"struct.DomainBase > >" } - %"struct.DomainBase > >" = type { [2 x i32] } - %"struct.DomainBase > >" = type { [3 x %"struct.WrapNoInit >"] } - %"struct.DomainBase > >" = type { i32 } - %"struct.DomainBase > >" = type { [3 x %"struct.WrapNoInit >"] } - %"struct.DomainBase > >" = type { [3 x i32] } - %"struct.DomainBase > >" = type { [3 x %"struct.WrapNoInit >"] } - %"struct.DomainLayout<3>" = type { %"struct.Node,Interval<3> >" } - %"struct.DomainMap,int>" = type { i32, %"struct.DomainMapNode,int>"*, %"struct.DomainMapIterator,int>" } - %"struct.DomainMapIterator,int>" = type { %"struct.DomainMapNode,int>"*, %"struct.std::_List_const_iterator >" } - %"struct.DomainMapNode,int>" = type { %"struct.Interval<1>", %"struct.DomainMapNode,int>"*, %"struct.DomainMapNode,int>"*, %"struct.DomainMapNode,int>"*, %"struct.std::list,std::allocator > >" } - %"struct.Engine<3,Zero,ConstantFunction>" = type { %"struct.Adv5::Ekin<3>", %"struct.Interval<3>", [3 x i32] } - %"struct.Engine<3,double,Brick>" = type { %"struct.Pooma::BrickBase<3>", %"struct.DataBlockPtr", double* } - %"struct.Engine<3,double,BrickView>" = type { %"struct.Pooma::BrickViewBase<3>", %"struct.DataBlockPtr", double* } - %"struct.Engine<3,double,ConstantFunction>" = type { double, %"struct.Interval<3>", [3 x i32] } - %"struct.Engine<3,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >" = type { %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >", %"struct.Interval<3>" } - %"struct.Engine<3,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" = type { %"struct.BinaryNode,BinaryNode >, double, Remote >, Field >, double, Remote > > >", %"struct.Interval<3>" } - %"struct.Engine<3,double,MultiPatch > >" = type { %"struct.ContextMapper<1>", %"struct.GridLayout<3>", %"struct.RefCountedBlockPtr >,false,RefBlockController > > >", i32* } - %"struct.Engine<3,double,MultiPatchView, 3> >" = type { %"struct.GridLayoutView<3,3>", %"struct.Engine<3,double,MultiPatch > >" } - %"struct.Engine<3,double,Remote >" = type { %"struct.Interval<3>", i32, %"struct.RefCountedPtr > >" } - %"struct.Engine<3,double,Remote >" = type { %"struct.Interval<3>", i32, %"struct.RefCountedPtr > >" } - %"struct.Field >,Zero,ConstantFunction>" = type { %"struct.FieldEngine >,Zero,ConstantFunction>" } - %"struct.Field >,double,ConstantFunction>" = type { %"struct.FieldEngine >,double,ConstantFunction>" } - %"struct.Field >,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >" = type { %"struct.FieldEngine >,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >" } - %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" = type { %"struct.FieldEngine >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" } - %"struct.Field >,double,MultiPatch > >" = type { %"struct.FieldEngine >,double,MultiPatch > >" } - %"struct.Field >,double,MultiPatchView, 3> >" = type { %"struct.FieldEngine >,double,MultiPatchView, 3> >" } - %"struct.Field >,double,Remote >" = type { %"struct.FieldEngine >,double,Remote >" } - %"struct.FieldEngine >,Zero,ConstantFunction>" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr, ConstantFunction>,false,RefBlockController, ConstantFunction> > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } - %"struct.FieldEngine >,double,ConstantFunction>" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr,false,RefBlockController > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } - %"struct.FieldEngine >,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >" = type { %"struct.Engine<3,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >", %"struct.Field >,double,MultiPatchView, 3> >"* } - %"struct.FieldEngine >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" = type { %"struct.Engine<3,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >", %"struct.Field >,double,Remote >"* } - %"struct.FieldEngine >,double,MultiPatch > >" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr > >,false,RefBlockController > > > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } - %"struct.FieldEngine >,double,MultiPatchView, 3> >" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr, 3> >,false,RefBlockController, 3> > > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } - %"struct.FieldEngine >,double,Remote >" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr >,false,RefBlockController > > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } - %"struct.FieldEngineBaseData<3,Zero,ConstantFunction>" = type { %"struct.Engine<3,Zero,ConstantFunction>", %struct.RelationList } - %"struct.FieldEngineBaseData<3,double,ConstantFunction>" = type { %"struct.Engine<3,double,ConstantFunction>", %struct.RelationList } - %"struct.FieldEngineBaseData<3,double,MultiPatch > >" = type { %"struct.Engine<3,double,MultiPatch > >", %struct.RelationList } - %"struct.FieldEngineBaseData<3,double,MultiPatchView, 3> >" = type { %"struct.Engine<3,double,MultiPatchView, 3> >", %struct.RelationList } - %"struct.FieldEngineBaseData<3,double,Remote >" = type { %"struct.Engine<3,double,Remote >", %struct.RelationList } - %struct.GlobalIDDataBase = type { %"struct.std::vector >", %"struct.std::map,std::allocator > >" } - %"struct.GlobalIDDataBase::Pack" = type { i32, i32, i32, i32 } - %"struct.GridLayout<3>" = type { %"struct.ContextMapper<1>", %"struct.LayoutBase<3,GridLayoutData<3> >", %"struct.Observable >" } - %"struct.GridLayoutData<3>" = type { %"struct.LayoutBaseData<3>", %struct.RefCounted, [21 x i8], i8, [3 x i32], [3 x %"struct.DomainMap,int>"], [3 x %"struct.DomainMap,int>"] } - %"struct.GridLayoutView<3,3>" = type { %"struct.LayoutBaseView<3,3,GridLayoutViewData<3, 3> >" } - %"struct.GridLayoutViewData<3,3>" = type { %"struct.LayoutBaseViewData<3,3,GridLayout<3> >", %struct.RefCounted } - %"struct.GuardLayers<3>" = type { [3 x i32], [3 x i32] } - %"struct.INode<3>" = type { %"struct.Interval<3>", %struct.GlobalIDDataBase*, i32 } - %"struct.Interval<1>" = type { %"struct.Domain<1,DomainTraits > >" } - %"struct.Interval<3>" = type { %"struct.Domain<3,DomainTraits > >" } - %"struct.LayoutBase<3,GridLayoutData<3> >" = type { %"struct.RefCountedPtr >" } - %"struct.LayoutBaseData<3>" = type { i32, %"struct.Interval<3>", %"struct.Interval<3>", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", i8, i8, %"struct.GuardLayers<3>", %"struct.GuardLayers<3>", %"struct.std::vector::GCFillInfo,std::allocator::GCFillInfo> >", [3 x i32], [3 x i32], %"struct.Loc<3>" } - %"struct.LayoutBaseData<3>::GCFillInfo" = type { %"struct.Interval<3>", i32, i32, i32 } - %"struct.LayoutBaseView<3,3,GridLayoutViewData<3, 3> >" = type { %"struct.RefCountedPtr >" } - %"struct.LayoutBaseViewData<3,3,GridLayout<3> >" = type { i32, %"struct.GridLayout<3>", %"struct.GuardLayers<3>", %"struct.GuardLayers<3>", %"struct.ViewIndexer<3,3>", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", i8 } - %"struct.Loc<1>" = type { %"struct.Domain<1,DomainTraits > >" } - %"struct.Loc<3>" = type { %"struct.Domain<3,DomainTraits > >" } - %"struct.MultiArg6 >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, ConstantFunction>,Field >, Zero, ConstantFunction> >" = type { %"struct.Field >,double,MultiPatch > >", %! "struct.Field >,double,MultiPatch > >", %"struct.Field >,double,MultiPatch > >", %"struct.Field >,double,MultiPatch > >", %"struct.Field >,double,ConstantFunction>", %"struct.Field >,Zero,ConstantFunction>" } - %"struct.NoMeshData<3>" = type { %struct.RefCounted, %"struct.Interval<3>", %"struct.Interval<3>", %"struct.Interval<3>", %"struct.Interval<3>" } - %"struct.Node,Interval<3> >" = type { %"struct.Interval<3>", %"struct.Interval<3>", i32, i32, i32, i32 } - %"struct.Observable >" = type { %"struct.GridLayout<3>"*, %"struct.std::vector >*,std::allocator >*> >", i32, %"struct.Adv5::Ekin<3>" } - %"struct.Pooma::BrickBase<3>" = type { %"struct.DomainLayout<3>", [3 x i32], [3 x i32], i32, i8 } - %"struct.Pooma::BrickViewBase<3>" = type { %"struct.Interval<3>", [3 x i32], [3 x i32], i32, i8 } - %"struct.Range<1>" = type { %"struct.Domain<1,DomainTraits > >" } - %"struct.Range<3>" = type { %"struct.Domain<3,DomainTraits > >" } - %"struct.RefBlockController > >" = type { %struct.RefCounted, %"struct.Engine<3,double,Remote >"*, %"struct.Engine<3,double,Remote >"*, %"struct.Engine<3,double,Remote >"*, i8 } - %"struct.RefBlockController, ConstantFunction> >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,Zero,ConstantFunction>"*, %"struct.FieldEngineBaseData<3,Zero,ConstantFunction>"*, %"struct.FieldEngineBaseData<3,Zero,ConstantFunction>"*, i8 } - %"struct.RefBlockController >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,double,ConstantFunction>"*, %"struct.FieldEngineBaseData<3,double,ConstantFunction>"*, %"struct.FieldEngineBaseData<3,double,ConstantFunction>"*, i8 } - %"struct.RefBlockController > > >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,double,MultiPatch > >"*, %"struct.FieldEngineBaseData<3,double,MultiPatch > >"*, %"struct.FieldEngineBaseData<3,double,MultiPatch > >"*, i8 } - %"struct.RefBlockController, 3> > >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,double,MultiPatchView, 3> >"*, %"struct.FieldEngineBaseData<3,double,MultiPatchView, 3> >"*, %"struct.FieldEngineBaseData<3,double,MultiPatchView, 3> >"*, i8 } - %"struct.RefBlockController > >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,double,Remote >"*, %"struct.FieldEngineBaseData<3,double,Remote >"*, %"struct.FieldEngineBaseData<3,double,Remote >"*, i8 } - %"struct.RefBlockController" = type { %struct.RefCounted, double*, double*, double*, i8 } - %struct.RefCounted = type { i32, %"struct.Adv5::Ekin<3>" } - %"struct.RefCountedBlockPtr >,false,RefBlockController > > >" = type { i32, %"struct.RefCountedPtr > > >" } - %"struct.RefCountedBlockPtr, ConstantFunction>,false,RefBlockController, ConstantFunction> > >" = type { i32, %"struct.RefCountedPtr, ConstantFunction> > >" } - %"struct.RefCountedBlockPtr,false,RefBlockController > >" = type { i32, %"struct.RefCountedPtr > >" } - %"struct.RefCountedBlockPtr > >,false,RefBlockController > > > >" = type { i32, %"struct.RefCountedPtr > > > >" } - %"struct.RefCountedBlockPtr, 3> >,false,RefBlockController, 3> > > >" = type { i32, %"struct.RefCountedPtr, 3> > > >" } - %"struct.RefCountedBlockPtr >,false,RefBlockController > > >" = type { i32, %"struct.RefCountedPtr > > >" } - %"struct.RefCountedBlockPtr >" = type { i32, %"struct.RefCountedPtr >" } - %"struct.RefCountedPtr >" = type { %"struct.DataBlockController"* } - %"struct.RefCountedPtr >" = type { %"struct.GridLayoutData<3>"* } - %"struct.RefCountedPtr >" = type { %"struct.GridLayoutViewData<3,3>"* } - %"struct.RefCountedPtr > > >" = type { %"struct.RefBlockController > >"* } - %"struct.RefCountedPtr, ConstantFunction> > >" = type { %"struct.RefBlockController, ConstantFunction> >"* } - %"struct.RefCountedPtr > >" = type { %"struct.RefBlockController >"* } - %"struct.RefCountedPtr > > > >" = type { %"struct.RefBlockController > > >"* } - %"struct.RefCountedPtr, 3> > > >" = type { %"struct.RefBlockController, 3> > >"* } - %"struct.RefCountedPtr > > >" = type { %"struct.RefBlockController > >"* } - %"struct.RefCountedPtr" = type { %struct.RelationListData* } - %"struct.RefCountedPtr > >" = type { %"struct.Shared >"* } - %"struct.RefCountedPtr > >" = type { %"struct.Shared >"* } - %"struct.RefCountedPtr > >" = type { %"struct.UniformRectilinearMeshData >"* } - %struct.RelationList = type { %"struct.RefCountedPtr" } - %struct.RelationListData = type { %struct.RefCounted, %"struct.std::vector >" } - %struct.RelationListItem = type { i32 (...)**, i32, i32, i8 } - %"struct.Shared >" = type { %struct.RefCounted, %"struct.Engine<3,double,Brick>" } - %"struct.Shared >" = type { %struct.RefCounted, %"struct.Engine<3,double,BrickView>" } - %"struct.SingleObservable" = type { %"struct.ContextMapper<1>"* } - %"struct.UniformRectilinearMesh >" = type { %"struct.RefCountedPtr > >" } - %"struct.UniformRectilinearMeshData >" = type { %"struct.NoMeshData<3>", %"struct.Vector<3,double,Full>", %"struct.Vector<3,double,Full>" } - %"struct.Vector<3,double,Full>" = type { %"struct.VectorEngine<3,double,Full>" } - %"struct.VectorEngine<3,double,Full>" = type { [3 x double] } - %"struct.ViewIndexer<3,3>" = type { %"struct.Interval<3>", %"struct.Range<3>", [3 x i32], [3 x i32], %"struct.Loc<3>" } - %"struct.WrapNoInit >" = type { %"struct.Interval<1>" } - %"struct.WrapNoInit >" = type { %"struct.Loc<1>" } - %"struct.WrapNoInit >" = type { %"struct.Range<1>" } - %"struct.std::_List_base,std::allocator > >" = type { %"struct.std::_List_base,std::allocator > >::_List_impl" } - %"struct.std::_List_base,std::allocator > >::_List_impl" = type { %"struct.std::_List_node_base" } - %"struct.std::_List_const_iterator >" = type { %"struct.std::_List_node_base"* } - %"struct.std::_List_node_base" = type { %"struct.std::_List_node_base"*, %"struct.std::_List_node_base"* } - %"struct.std::_Rb_tree,std::_Select1st >,std::less,std::allocator > >" = type { %"struct.std::_Rb_tree,std::_Select1st >,std::less,std::allocator > >::_Rb_tree_impl,false>" } - %"struct.std::_Rb_tree,std::_Select1st >,std::less,std::allocator > >::_Rb_tree_impl,false>" = type { %"struct.Adv5::Ekin<3>", %"struct.std::_Rb_tree_node_base", i32 } - %"struct.std::_Rb_tree_node_base" = type { i32, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"* } - %"struct.std::_Vector_base >" = type { %"struct.std::_Vector_base >::_Vector_impl" } - %"struct.std::_Vector_base >::_Vector_impl" = type { %"struct.GlobalIDDataBase::Pack"*, %"struct.GlobalIDDataBase::Pack"*, %"struct.GlobalIDDataBase::Pack"* } - %"struct.std::_Vector_base::GCFillInfo,std::allocator::GCFillInfo> >" = type { %"struct.std::_Vector_base::GCFillInfo,std::allocator::GCFillInfo> >::_Vector_impl" } - %"struct.std::_Vector_base::GCFillInfo,std::allocator::GCFillInfo> >::_Vector_impl" = type { %"struct.LayoutBaseData<3>::GCFillInfo"*, %"struct.LayoutBaseData<3>::GCFillInfo"*, %"struct.LayoutBaseData<3>::GCFillInfo"* } - %"struct.std::_Vector_base,std::allocator > >" = type { %"struct.std::_Vector_base,std::allocator > >::_Vector_impl" } - %"struct.std::_Vector_base,std::allocator > >::_Vector_impl" = type { %"struct.Loc<3>"*, %"struct.Loc<3>"*, %"struct.Loc<3>"* } - %"struct.std::_Vector_base, Interval<3> >*,std::allocator, Interval<3> >*> >" = type { %"struct.std::_Vector_base, Interval<3> >*,std::allocator, Interval<3> >*> >::_Vector_impl" } - %"struct.std::_Vector_base, Interval<3> >*,std::allocator, Interval<3> >*> >::_Vector_impl" = type { %"struct.Node,Interval<3> >"**, %"struct.Node,Interval<3> >"**, %"struct.Node,Interval<3> >"** } - %"struct.std::_Vector_base >*,std::allocator >*> >" = type { %"struct.std::_Vector_base >*,std::allocator >*> >::_Vector_impl" } - %"struct.std::_Vector_base >*,std::allocator >*> >::_Vector_impl" = type { %"struct.ContextMapper<1>"**, %"struct.ContextMapper<1>"**, %"struct.ContextMapper<1>"** } - %"struct.std::_Vector_base >" = type { %"struct.std::_Vector_base >::_Vector_impl" } - %"struct.std::_Vector_base >::_Vector_impl" = type { %struct.RelationListItem**, %struct.RelationListItem**, %struct.RelationListItem** } - %"struct.std::_Vector_base,std::allocator > >" = type { %"struct.std::_Vector_base,std::allocator > >::_Vector_impl" } - %"struct.std::_Vector_base,std::allocator > >::_Vector_impl" = type { %"struct.Vector<3,double,Full>"*, %"struct.Vector<3,double,Full>"*, %"struct.Vector<3,double,Full>"* } - %"struct.std::list,std::allocator > >" = type { %"struct.std::_List_base,std::allocator > >" } - %"struct.std::map,std::allocator > >" = type { %"struct.std::_Rb_tree,std::_Select1st >,std::less,std::allocator > >" } - %"struct.std::vector >" = type { %"struct.std::_Vector_base >" } - %"struct.std::vector::GCFillInfo,std::allocator::GCFillInfo> >" = type { %"struct.std::_Vector_base::GCFillInfo,std::allocator::GCFillInfo> >" } - %"struct.std::vector,std::allocator > >" = type { %"struct.std::_Vector_base,std::allocator > >" } - %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >" = type { %"struct.std::_Vector_base, Interval<3> >*,std::allocator, Interval<3> >*> >" } - %"struct.std::vector >*,std::allocator >*> >" = type { %"struct.std::_Vector_base >*,std::allocator >*> >" } - %"struct.std::vector >" = type { %"struct.std::_Vector_base >" } - %"struct.std::vector,std::allocator > >" = type { %"struct.std::_Vector_base,std::allocator > >" } - -declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind - -declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEEC1ERKSC_(%"struct.FieldEngine >,double,MultiPatch > >"*, %"struct.FieldEngine >,double,MultiPatch > >"*) nounwind - -declare fastcc void @_ZN9CenteringILi3EEC1ERKS0_i(%"struct.Centering<3>"*, %"struct.Centering<3>"*, i32) nounwind - -declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEED1Ev(%"struct.FieldEngine >,double,Remote >"*) nounwind - -declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEEC1Id14MultiPatchViewI7GridTagS6_I5BrickELi3EEEERKS_IS5_T_T0_ERK5INodeILi3EE(%"struct.FieldEngine >,double,Remote >"*, %"struct.FieldEngine >,double,MultiPatchView, 3> >"*, %"struct.INode<3>"*) nounwind - -declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEED1Ev(%"struct.FieldEngine >,double,MultiPatchView, 3> >"*) nounwind - -declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEEC1Id10MultiPatchIS7_SA_EEERKS_IS5_T_T0_ERK8IntervalILi3EE(%"struct.FieldEngine >,double,MultiPatchView, 3> >"*, %"struct.FieldEngine >,double,MultiPatch > >"*, %"struct.Interval<3>"*) nounwind - -define fastcc void @t(double %dt, %"struct.Field >,double,MultiPatch > >"* %rh, %"struct.Field >,double,MultiPatch > >"* %T, %"struct.Field >,double,MultiPatch > >"* %v, %"struct.Field >,double,MultiPatch > >"* %pg, %"struct.Field >,double,MultiPatch > >"* %ph, %"struct.Field >,double,MultiPatch > >"* %cs, %"struct.Field >,double,ConstantFunction>"* %cv, %"struct.Field >,Zero,ConstantFunction>"* %dlmdlt, %"struct.Field >,double,ConstantFunction>"* %xmue, %"struct.Field >,double,MultiPatch > >"* %vint, %"struct.Field >,double,MultiPatch > >"* %cent, %"struct.Field >,double,MultiPatch > >"* %fvis, double %c_nr, double %c_av, i8 zeroext %cartvis_f) nounwind { -entry: - %0 = alloca %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" ; <%"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"*> [#uses=4] - %s.i.i.i.i.i = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] - %1 = alloca %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >" ; <%"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >"*> [#uses=2] - %multiArg.i = alloca %"struct.MultiArg6 >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, ConstantFunction>,Field >, Zero, ConstantFunction> >" ; <%"struct.MultiArg6 >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, ConstantFunction>,Field >, Zero, ConstantFunction> >"*> [#uses=0] - %2 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=6] - %3 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=2] - %4 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] - %5 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=2] - %6 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] - %7 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %8 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %9 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %10 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %11 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %12 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %13 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %14 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %15 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %16 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %17 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] - %18 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %19 = alloca double ; [#uses=0] - %20 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] - %21 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] - %22 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] - %23 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] - %24 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] - %25 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %26 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %27 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %28 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %29 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] - %30 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %31 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %32 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %33 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %34 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %35 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] - %36 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] - %37 = getelementptr %"struct.Field >,double,MultiPatch > >"* %v, i32 0, i32 0, i32 5 ; <%"struct.GuardLayers<3>"*> [#uses=1] - %38 = bitcast %"struct.GuardLayers<3>"* %37 to i8* ; [#uses=1] - br label %bb.i.i.i.i.i - -bb.i.i.i.i.i: ; preds = %bb.i.i.i.i.i, %entry - %39 = icmp eq i32* null, null ; [#uses=1] - br i1 %39, label %_ZN14ScalarCodeInfoILi3ELi4EEC1Ev.exit.i, label %bb.i.i.i.i.i - -_ZN14ScalarCodeInfoILi3ELi4EEC1Ev.exit.i: ; preds = %bb.i.i.i.i.i - br label %bb.i.i.i35.i.i34 - -bb.i.i.i35.i.i34: ; preds = %bb.i.i.i35.i.i34, %_ZN14ScalarCodeInfoILi3ELi4EEC1Ev.exit.i - %40 = icmp eq i32* null, null ; [#uses=1] - br i1 %40, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i37, label %bb.i.i.i35.i.i34 - -_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i37: ; preds = %bb.i.i.i35.i.i34 - br label %bb.i.i.i19.i.i47 - -bb.i.i.i19.i.i47: ; preds = %bb.i.i.i19.i.i47, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i37 - %41 = icmp eq i32* null, null ; [#uses=1] - br i1 %41, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i50, label %bb.i.i.i19.i.i47 - -_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i50: ; preds = %bb.i.i.i19.i.i47 - %42 = getelementptr %"struct.Field >,double,MultiPatch > >"* %rh, i32 0, i32 0 ; <%"struct.FieldEngine >,double,MultiPatch > >"*> [#uses=1] - br label %bb.i.i.i19.i.i.i - -bb.i.i.i19.i.i.i: ; preds = %bb.i.i.i19.i.i.i, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i50 - %43 = icmp eq i32* null, null ; [#uses=1] - br i1 %43, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i.i, label %bb.i.i.i19.i.i.i - -_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i.i: ; preds = %bb.i.i.i19.i.i.i - br label %bb.i.i.i35.i.i433 - -bb.i.i.i35.i.i433: ; preds = %bb.i.i.i35.i.i433, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i.i - %44 = icmp eq i32* null, null ; [#uses=1] - br i1 %44, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i436, label %bb.i.i.i35.i.i433 - -_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i436: ; preds = %bb.i.i.i35.i.i433 - br label %bb.i.i.i19.i.i446 - -bb.i.i.i19.i.i446: ; preds = %bb.i.i.i19.i.i446, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i436 - %45 = icmp eq i32* null, null ; [#uses=1] - br i1 %45, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i449, label %bb.i.i.i19.i.i446 - -_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i449: ; preds = %bb.i.i.i19.i.i446 - br label %bb.i.i.i.i.i459 - -bb.i.i.i.i.i459: ; preds = %bb.i.i.i.i.i459, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i449 - %46 = icmp eq i32* null, null ; [#uses=1] - br i1 %46, label %_ZN14ScalarCodeInfoILi3ELi6EEC1Ev.exit.i460, label %bb.i.i.i.i.i459 - -_ZN14ScalarCodeInfoILi3ELi6EEC1Ev.exit.i460: ; preds = %bb.i.i.i.i.i459 - %47 = getelementptr %"struct.Field >,double,MultiPatch > >"* %5, i32 0, i32 0, i32 1 ; <%"struct.Centering<3>"*> [#uses=1] - %48 = getelementptr %"struct.Field >,double,MultiPatch > >"* %vint, i32 0, i32 0, i32 1 ; <%"struct.Centering<3>"*> [#uses=2] - %49 = getelementptr %"struct.Field >,double,MultiPatch > >"* %5, i32 0, i32 0, i32 5 ; <%"struct.GuardLayers<3>"*> [#uses=1] - %50 = bitcast %"struct.GuardLayers<3>"* %49 to i8* ; [#uses=1] - %51 = bitcast %"struct.GuardLayers<3>"* null to i8* ; [#uses=2] - %52 = getelementptr %"struct.Field >,double,MultiPatch > >"* %3, i32 0, i32 0, i32 1 ; <%"struct.Centering<3>"*> [#uses=1] - %53 = getelementptr %"struct.Field >,double,MultiPatch > >"* %3, i32 0, i32 0, i32 5 ; <%"struct.GuardLayers<3>"*> [#uses=1] - %54 = bitcast %"struct.GuardLayers<3>"* %53 to i8* ; [#uses=1] - %55 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 1 ; <%"struct.Centering<3>"*> [#uses=1] - %56 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] - %57 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] - %58 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0 ; [#uses=1] - %59 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] - %60 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 5 ; <%"struct.GuardLayers<3>"*> [#uses=1] - %61 = bitcast %"struct.GuardLayers<3>"* %60 to i8* ; [#uses=1] - %62 = getelementptr %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >"* %1, i32 0, i32 1, i32 0, i32 0 ; <%"struct.FieldEngine >,double,MultiPatchView, 3> >"*> [#uses=1] - %63 = getelementptr %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >"* %1, i32 0, i32 1, i32 1, i32 0 ; <%"struct.FieldEngine >,double,MultiPatchView, 3> >"*> [#uses=1] - %64 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >"* null, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 ; [#uses=1] - %65 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"* %0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 1, i32 0 ; <%"struct.FieldEngine >,double,Remote >"*> [#uses=2] - %66 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"* %0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0 ; [#uses=1] - %67 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"* %0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] - %68 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"* %0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] - br label %bb15 - -bb15: ; preds = %_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit, %_ZN14ScalarCodeInfoILi3ELi6EEC1Ev.exit.i460 - %i.0.reg2mem.0 = phi i32 [ 0, %_ZN14ScalarCodeInfoILi3ELi6EEC1Ev.exit.i460 ], [ %indvar.next, %_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit ] ; [#uses=4] - call fastcc void @_ZN9CenteringILi3EEC1ERKS0_i(%"struct.Centering<3>"* %47, %"struct.Centering<3>"* %48, i32 %i.0.reg2mem.0) nounwind - call void @llvm.memcpy.i32(i8* %50, i8* %51, i32 24, i32 4) nounwind - call fastcc void @_ZN9CenteringILi3EEC1ERKS0_i(%"struct.Centering<3>"* %52, %"struct.Centering<3>"* %48, i32 %i.0.reg2mem.0) nounwind - call void @llvm.memcpy.i32(i8* %54, i8* %51, i32 24, i32 4) nounwind - br i1 false, label %bb.i940, label %bb4.i943 - -bb.i940: ; preds = %bb15 - br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944 - -bb4.i943: ; preds = %bb15 - br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944 - -_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944: ; preds = %bb4.i943, %bb.i940 - call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEEC1Id10MultiPatchIS7_SA_EEERKS_IS5_T_T0_ERK8IntervalILi3EE(%"struct.FieldEngine >,double,MultiPatchView, 3> >"* null, %"struct.FieldEngine >,double,MultiPatch > >"* null, %"struct.Interval<3>"* null) nounwind - call fastcc void @_ZN9CenteringILi3EEC1ERKS0_i(%"struct.Centering<3>"* %55, %"struct.Centering<3>"* null, i32 %i.0.reg2mem.0) nounwind - call void @llvm.memcpy.i32(i8* %61, i8* %38, i32 24, i32 4) nounwind - %69 = load %"struct.Loc<3>"** null, align 4 ; <%"struct.Loc<3>"*> [#uses=1] - %70 = ptrtoint %"struct.Loc<3>"* %69 to i32 ; [#uses=1] - %.off.i911 = sub i32 0, %70 ; [#uses=1] - %71 = icmp ult i32 %.off.i911, 12 ; [#uses=1] - %72 = sub i32 0, 0 ; [#uses=2] - %73 = load i32* %56, align 4 ; [#uses=1] - %74 = add i32 %73, 0 ; [#uses=1] - %75 = sub i32 %74, %72 ; [#uses=1] - %76 = add i32 %75, 0 ; [#uses=1] - %77 = load i32* null, align 8 ; [#uses=2] - %78 = load i32* null, align 4 ; [#uses=1] - %79 = sub i32 %77, %78 ; [#uses=1] - %80 = load i32* %57, align 4 ; [#uses=1] - %81 = load i32* null, align 4 ; [#uses=1] - br i1 %71, label %bb.i912, label %bb4.i915 - -bb.i912: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944 - br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916 - -bb4.i915: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944 - %82 = sub i32 %77, %79 ; [#uses=1] - %83 = add i32 %82, %80 ; [#uses=1] - %84 = add i32 %83, %81 ; [#uses=1] - %85 = load i32* %58, align 8 ; [#uses=2] - %86 = load i32* null, align 8 ; [#uses=1] - %87 = sub i32 %85, %86 ; [#uses=2] - %88 = load i32* %59, align 4 ; [#uses=1] - %89 = load i32* null, align 4 ; [#uses=1] - %90 = sub i32 %85, %87 ; [#uses=1] - %91 = add i32 %90, %88 ; [#uses=1] - %92 = add i32 %91, %89 ; [#uses=1] - br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916 - -_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916: ; preds = %bb4.i915, %bb.i912 - %.0978.0.0.1.0.0.0.0.1.0 = phi i32 [ %84, %bb4.i915 ], [ 0, %bb.i912 ] ; [#uses=0] - %.0978.0.0.2.0.0.0.0.0.0 = phi i32 [ %87, %bb4.i915 ], [ 0, %bb.i912 ] ; [#uses=1] - %.0978.0.0.2.0.0.0.0.1.0 = phi i32 [ %92, %bb4.i915 ], [ 0, %bb.i912 ] ; [#uses=0] - store i32 %72, i32* null, align 8 - store i32 %76, i32* null, align 4 - store i32 %.0978.0.0.2.0.0.0.0.0.0, i32* null, align 8 - call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEEC1Id10MultiPatchIS7_SA_EEERKS_IS5_T_T0_ERK8IntervalILi3EE(%"struct.FieldEngine >,double,MultiPatchView, 3> >"* null, %"struct.FieldEngine >,double,MultiPatch > >"* null, %"struct.Interval<3>"* null) nounwind - %93 = load i32* null, align 8 ; [#uses=1] - %94 = icmp sgt i32 %93, 0 ; [#uses=1] - br i1 %94, label %bb1.i, label %_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit - -bb1.i: ; preds = %bb3.i23.i.i, %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916 - call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEED1Ev(%"struct.FieldEngine >,double,MultiPatchView, 3> >"* %63) nounwind - call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEED1Ev(%"struct.FieldEngine >,double,MultiPatchView, 3> >"* %62) nounwind - br label %bb.i17.i14.i - -bb.i17.i14.i: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i, %bb1.i - %i.0.02.rec.i.i.i = phi i32 [ %.rec.i.i.i641, %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i ], [ 0, %bb1.i ] ; [#uses=1] - %95 = load double* %64, align 8 ; [#uses=1] - store double %95, double* null, align 8 - call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEEC1Id14MultiPatchViewI7GridTagS6_I5BrickELi3EEEERKS_IS5_T_T0_ERK5INodeILi3EE(%"struct.FieldEngine >,double,Remote >"* %65, %"struct.FieldEngine >,double,MultiPatchView, 3> >"* null, %"struct.INode<3>"* null) nounwind - %96 = load %"struct.Loc<3>"** null, align 4 ; <%"struct.Loc<3>"*> [#uses=1] - %97 = ptrtoint %"struct.Loc<3>"* %96 to i32 ; [#uses=1] - %.off.i21.i.i.i.i = sub i32 0, %97 ; [#uses=1] - %98 = icmp ult i32 %.off.i21.i.i.i.i, 12 ; [#uses=1] - br i1 %98, label %bb.i22.i.i.i.i, label %bb3.i25.i.i.i.i - -bb.i22.i.i.i.i: ; preds = %bb.i17.i14.i - %99 = load i32* null, align 4 ; [#uses=1] - %100 = icmp eq i32 %99, 1 ; [#uses=1] - %101 = load i32* null, align 4 ; [#uses=1] - br i1 %100, label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i, label %bb6.i.i24.i.i.i.i - -bb6.i.i24.i.i.i.i: ; preds = %bb.i22.i.i.i.i - br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i - -bb3.i25.i.i.i.i: ; preds = %bb.i17.i14.i - %102 = load i32* %66, align 8 ; [#uses=2] - %103 = load i32* %67, align 4 ; [#uses=1] - %104 = load i32* %68, align 4 ; [#uses=1] - br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i - -_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i: ; preds = %bb3.i25.i.i.i.i, %bb6.i.i24.i.i.i.i, %bb.i22.i.i.i.i - %.rle1279 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] - %.rle1277 = phi i32 [ %102, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] - %.rle1275 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] - %.01034.0.0.2.0.0.0.0.1.0 = phi i32 [ %104, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] - %.01034.0.0.2.0.0.0.0.0.0 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] - %.01034.0.0.1.0.0.0.0.1.0 = phi i32 [ %103, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] - %.01034.0.0.1.0.0.0.0.0.0 = phi i32 [ %102, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] - %.01034.0.0.0.0.0.0.0.1.0 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ %101, %bb.i22.i.i.i.i ] ; [#uses=1] - %.01034.0.0.0.0.0.0.0.0.0 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] - %105 = sub i32 %.01034.0.0.0.0.0.0.0.0.0, %.rle1275 ; [#uses=0] - %106 = sub i32 %.01034.0.0.1.0.0.0.0.0.0, %.rle1277 ; [#uses=0] - %107 = sub i32 %.01034.0.0.2.0.0.0.0.0.0, %.rle1279 ; [#uses=0] - store i32 %.01034.0.0.0.0.0.0.0.1.0, i32* null, align 4 - store i32 %.01034.0.0.1.0.0.0.0.1.0, i32* null, align 4 - store i32 %.01034.0.0.2.0.0.0.0.1.0, i32* null, align 4 - call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEED1Ev(%"struct.FieldEngine >,double,Remote >"* %65) nounwind - %.rec.i.i.i641 = add i32 %i.0.02.rec.i.i.i, 1 ; [#uses=1] - %108 = load %"struct.INode<3>"** null, align 4 ; <%"struct.INode<3>"*> [#uses=1] - %109 = icmp eq %"struct.INode<3>"* null, %108 ; [#uses=1] - br i1 %109, label %bb3.i23.i.i, label %bb.i17.i14.i - -bb3.i23.i.i: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i - br label %bb1.i - -_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916 - %indvar.next = add i32 %i.0.reg2mem.0, 1 ; [#uses=2] - %exitcond = icmp eq i32 %indvar.next, 3 ; [#uses=1] - br i1 %exitcond, label %bb18, label %bb15 - -bb18: ; preds = %_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit - call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEEC1ERKSC_(%"struct.FieldEngine >,double,MultiPatch > >"* null, %"struct.FieldEngine >,double,MultiPatch > >"* %42) nounwind - unreachable -} From clattner at apple.com Mon Nov 2 01:30:52 2009 From: clattner at apple.com (Chris Lattner) Date: Sun, 1 Nov 2009 23:30:52 -0800 Subject: [llvm-commits] [llvm] r85764 - in /llvm/trunk/lib/Target/ARM: ARM.td ARMBaseInstrInfo.cpp ARMBaseInstrInfo.h ARMInstrFormats.td ARMInstrInfo.cpp ARMInstrInfo.h Thumb1InstrInfo.cpp Thumb2InstrInfo.cpp In-Reply-To: References: <200911020010.nA20Ade4021334@zion.cs.uiuc.edu> <7703A6BF-6F9F-4636-961C-23B5080B78A2@apple.com> Message-ID: <9C2785E9-143B-4F5C-8E8C-E5727F372468@apple.com> On Nov 1, 2009, at 11:08 PM, Evan Cheng wrote: >> Do we have any better way? It seems - no. We need to find the def of >> the >> register which is closest to the insertion point. Even if some >> instruction >> numbering would be saved after RA, then iterating of instructions >> seems to >> be cheaper than iterating over defs of the phys reg. > > This has to be done in a late pass which can walk basic blocks from > top down and tracking the domain of every register. When it sees a > fcpyd, it knows the domain of source register and can change it. The > current implementation really is a non-starter, especially for JIT. FWIW, I agree with Evan's approach. This would also allow you to disable the pass in -fast mode etc. -Chris From sabre at nondot.org Mon Nov 2 01:33:59 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 07:33:59 -0000 Subject: [llvm-commits] [llvm] r85795 - in /llvm/trunk: lib/Transforms/Scalar/SCCP.cpp test/Transforms/SCCP/ipsccp-basic.ll Message-ID: <200911020733.nA27XxI6005372@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 01:33:59 2009 New Revision: 85795 URL: http://llvm.org/viewvc/llvm-project?rev=85795&view=rev Log: improve IPSCCP to be able to propagate the result of "!mayBeOverridden" function to calls of that function, regardless of whether it has local linkage or has its address taken. Not escaping should only affect whether we make an aggressive assumption about the arguments to a function, not whether we can track the result of it. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85795&r1=85794&r2=85795&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 01:33:59 2009 @@ -25,7 +25,6 @@ #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Target/TargetData.h" @@ -227,7 +226,6 @@ /// and out of the specified function (which cannot have its address taken), /// this method must be called. void AddTrackedFunction(Function *F) { - assert(F->hasLocalLinkage() && "Can only track internal functions!"); // Add an entry, F -> undef. if (const StructType *STy = dyn_cast(F->getReturnType())) { for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) @@ -380,11 +378,9 @@ // instruction that was just changed state somehow. Based on this // information, we need to update the specified user of this instruction. // - void OperandChangedState(User *U) { - // Only instructions use other variable values! - Instruction &I = cast(*U); - if (BBExecutable.count(I.getParent())) // Inst is executable? - visit(I); + void OperandChangedState(Instruction *I) { + if (BBExecutable.count(I->getParent())) // Inst is executable? + visit(*I); } /// RemoveFromOverdefinedPHIs - If I has any entries in the @@ -428,8 +424,6 @@ void visitLoadInst (LoadInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); void visitCallInst (CallInst &I) { - if (isFreeCall(&I)) - return; visitCallSite(CallSite::get(&I)); } void visitInvokeInst (InvokeInst &II) { @@ -656,19 +650,19 @@ markConstant(&PN, OperandVal); // Acquire operand value } + + + void SCCPSolver::visitReturnInst(ReturnInst &I) { if (I.getNumOperands() == 0) return; // ret void Function *F = I.getParent()->getParent(); + // If we are tracking the return value of this function, merge it in. - if (!F->hasLocalLinkage()) - return; - if (!TrackedRetVals.empty()) { DenseMap::iterator TFRVI = TrackedRetVals.find(F); - if (TFRVI != TrackedRetVals.end() && - !TFRVI->second.isOverdefined()) { + if (TFRVI != TrackedRetVals.end()) { mergeInValue(TFRVI->second, F, getValueState(I.getOperand(0))); return; } @@ -1164,14 +1158,14 @@ // The common case is that we aren't tracking the callee, either because we // are not doing interprocedural analysis or the callee is indirect, or is // external. Handle these cases first. - if (F == 0 || !F->hasLocalLinkage()) { + if (F == 0 || F->isDeclaration()) { CallOverdefined: // Void return and not tracking callee, just bail. if (I->getType()->isVoidTy()) return; // Otherwise, if we have a single return value case, and if the function is // a declaration, maybe we can constant fold it. - if (!isa(I->getType()) && F && F->isDeclaration() && + if (F && F->isDeclaration() && !isa(I->getType()) && canConstantFoldCallTo(F)) { SmallVector Operands; @@ -1235,7 +1229,7 @@ // common path above. goto CallOverdefined; } - + // Finally, if this is the first call to the function hit, mark its entry // block executable. MarkBlockExecutable(F->begin()); @@ -1244,6 +1238,8 @@ CallSite::arg_iterator CAI = CS.arg_begin(); for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI, ++CAI) { + // If this argument is byval, and if the function is not readonly, there + // will be an implicit copy formed of the input aggregate. if (AI->hasByValAttr() && !F->onlyReadsMemory()) { markOverdefined(AI); continue; @@ -1273,7 +1269,8 @@ // for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) - OperandChangedState(*UI); + if (Instruction *I = dyn_cast(*UI)) + OperandChangedState(I); } // Process the instruction work list. @@ -1292,7 +1289,8 @@ if (!getValueState(I).isOverdefined()) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) - OperandChangedState(*UI); + if (Instruction *I = dyn_cast(*UI)) + OperandChangedState(I); } // Process the basic block work list. @@ -1650,14 +1648,24 @@ if (F->isDeclaration()) continue; - if (!F->hasLocalLinkage() || AddressIsTaken(F)) { - Solver.MarkBlockExecutable(F->begin()); - for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); - AI != E; ++AI) - Solver.markOverdefined(AI); - } else { + // If this is a strong or ODR definition of this function, then we can + // propagate information about its result into callsites of it. + if (!F->mayBeOverridden()) Solver.AddTrackedFunction(F); - } + + // If this function only has direct calls that we can see, we can track its + // arguments and return value aggressively, and can assume it is not called + // unless we see evidence to the contrary. + if (F->hasLocalLinkage() && !AddressIsTaken(F)) + continue; + + // Assume the function is called. + Solver.MarkBlockExecutable(F->begin()); + + // Assume nothing about the incoming arguments. + for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); + AI != E; ++AI) + Solver.markOverdefined(AI); } // Loop over global variables. We inform the solver about any internal global @@ -1805,16 +1813,21 @@ // TODO: Process multiple value ret instructions also. const DenseMap &RV = Solver.getTrackedRetVals(); for (DenseMap::const_iterator I = RV.begin(), - E = RV.end(); I != E; ++I) - if (!I->second.isOverdefined() && - !I->first->getReturnType()->isVoidTy()) { - Function *F = I->first; - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) - if (ReturnInst *RI = dyn_cast(BB->getTerminator())) - if (!isa(RI->getOperand(0))) - RI->setOperand(0, UndefValue::get(F->getReturnType())); - } - + E = RV.end(); I != E; ++I) { + Function *F = I->first; + if (I->second.isOverdefined() || F->getReturnType()->isVoidTy()) + continue; + + // We can only do this if we know that nothing else can call the function. + if (!F->hasLocalLinkage() || AddressIsTaken(F)) + continue; + + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) + if (!isa(RI->getOperand(0))) + RI->setOperand(0, UndefValue::get(F->getReturnType())); + } + // If we infered constant or undef values for globals variables, we can delete // the global and any stores that remain to it. const DenseMap &TG = Solver.getTrackedGlobals(); Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll?rev=85795&r1=85794&r2=85795&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll (original) +++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Mon Nov 2 01:33:59 2009 @@ -134,3 +134,17 @@ ret i64 %b } + +;;======================== test6 + +define i64 @test6a() { + ret i64 0 +} + +define i64 @test6b() { + %a = call i64 @test6a() + ret i64 %a +} +; CHECK: define i64 @test6b +; CHECK: ret i64 0 + From sabre at nondot.org Mon Nov 2 01:34:29 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 07:34:29 -0000 Subject: [llvm-commits] [llvm] r85796 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <200911020734.nA27YTg2005396@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 01:34:29 2009 New Revision: 85796 URL: http://llvm.org/viewvc/llvm-project?rev=85796&view=rev Log: now that ip sccp *really* subsumes ipcp, remove ipcp again. 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=85796&r1=85795&r2=85796&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Nov 2 01:34:29 2009 @@ -99,7 +99,6 @@ if (UnitAtATime) { PM->add(createGlobalOptimizerPass()); // Optimize out global vars - PM->add(createIPConstantPropagationPass()); // IP CP PM->add(createIPSCCPPass()); // IP SCCP PM->add(createDeadArgEliminationPass()); // Dead argument elimination } From evan.cheng at apple.com Mon Nov 2 01:51:19 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 02 Nov 2009 07:51:19 -0000 Subject: [llvm-commits] [llvm] r85797 - /llvm/trunk/lib/Target/ARM/README.txt Message-ID: <200911020751.nA27pJdG005964@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 2 01:51:19 2009 New Revision: 85797 URL: http://llvm.org/viewvc/llvm-project?rev=85797&view=rev Log: Add an entry. Modified: llvm/trunk/lib/Target/ARM/README.txt Modified: llvm/trunk/lib/Target/ARM/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/README.txt?rev=85797&r1=85796&r2=85797&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/README.txt (original) +++ llvm/trunk/lib/Target/ARM/README.txt Mon Nov 2 01:51:19 2009 @@ -609,3 +609,6 @@ revisions of patches are on the mailing list, beginning at: http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/022763.html +//===---------------------------------------------------------------------===// + +Make use of the "rbit" instruction. From evan.cheng at apple.com Mon Nov 2 01:58:25 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 02 Nov 2009 07:58:25 -0000 Subject: [llvm-commits] [llvm] r85798 - /llvm/trunk/lib/Target/ARM/README.txt Message-ID: <200911020758.nA27wPWW006220@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 2 01:58:25 2009 New Revision: 85798 URL: http://llvm.org/viewvc/llvm-project?rev=85798&view=rev Log: These are done / no longer care. Modified: llvm/trunk/lib/Target/ARM/README.txt Modified: llvm/trunk/lib/Target/ARM/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/README.txt?rev=85798&r1=85797&r2=85798&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/README.txt (original) +++ llvm/trunk/lib/Target/ARM/README.txt Mon Nov 2 01:58:25 2009 @@ -8,12 +8,8 @@ add doesn't need to overflow between the two 16-bit chunks. * Implement pre/post increment support. (e.g. PR935) -* Coalesce stack slots! * Implement smarter constant generation for binops with large immediates. -* Consider materializing FP constants like 0.0f and 1.0f using integer - immediate instructions then copy to FPU. Slower than load into FPU? - //===---------------------------------------------------------------------===// Crazy idea: Consider code that uses lots of 8-bit or 16-bit values. By the @@ -422,14 +418,6 @@ //===---------------------------------------------------------------------===// -More register scavenging work: - -1. Use the register scavenger to track frame index materialized into registers - (those that do not fit in addressing modes) to allow reuse in the same BB. -2. Finish scavenging for Thumb. - -//===---------------------------------------------------------------------===// - More LSR enhancements possible: 1. Teach LSR about pre- and post- indexed ops to allow iv increment be merged @@ -540,10 +528,6 @@ //===---------------------------------------------------------------------===// -We need to fix constant isel for ARMv6t2 to use MOVT. - -//===---------------------------------------------------------------------===// - Constant island pass should make use of full range SoImm values for LEApcrel. Be careful though as the last attempt caused infinite looping on lencod. @@ -593,11 +577,6 @@ //===---------------------------------------------------------------------===// -add/sub/and/or + i32 imm can be simplified by folding part of the immediate -into the operation. - -//===---------------------------------------------------------------------===// - It might be profitable to cse MOVi16 if there are lots of 32-bit immediates with the same bottom half. From evan.cheng at apple.com Mon Nov 2 02:09:50 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 02 Nov 2009 08:09:50 -0000 Subject: [llvm-commits] [llvm] r85799 - in /llvm/trunk: lib/CodeGen/MachineLICM.cpp test/CodeGen/ARM/remat.ll test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Message-ID: <200911020809.nA289opg006565@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 2 02:09:49 2009 New Revision: 85799 URL: http://llvm.org/viewvc/llvm-project?rev=85799&view=rev Log: Initilize the machine LICM CSE map upon the first time an instruction is hoisted to the loop preheader. Add instructions which are already in the preheader block that may be common expressions of those that are hoisted out. These does get a few more instructions CSE'ed. Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/test/CodeGen/ARM/remat.ll llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=85799&r1=85798&r2=85799&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Mon Nov 2 02:09:49 2009 @@ -56,12 +56,12 @@ // State that is updated as we process loops bool Changed; // True if a loop is changed. + bool FirstInLoop; // True if it's the first LICM in the loop. MachineLoop *CurLoop; // The current loop we are working on. MachineBasicBlock *CurPreheader; // The preheader for CurLoop. - // For each BB and opcode pair, keep a list of hoisted instructions. - DenseMap, - std::vector > CSEMap; + // For each opcode, keep a list of potentail CSE instructions. + DenseMap > CSEMap; public: static char ID; // Pass identification, replacement for typeid MachineLICM() : MachineFunctionPass(&ID) {} @@ -115,6 +115,11 @@ /// that is safe to hoist, this instruction is called to do the dirty work. /// void Hoist(MachineInstr *MI); + + /// InitCSEMap - Initialize the CSE map with instructions that are in the + /// current loop preheader that may become duplicates of instructions that + /// are hoisted out of the loop. + void InitCSEMap(MachineBasicBlock *BB); }; } // end anonymous namespace @@ -140,7 +145,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { DEBUG(errs() << "******** Machine LICM ********\n"); - Changed = false; + Changed = FirstInLoop = false; TM = &MF.getTarget(); TII = TM->getInstrInfo(); TRI = TM->getRegisterInfo(); @@ -152,8 +157,7 @@ DT = &getAnalysis(); AA = &getAnalysis(); - for (MachineLoopInfo::iterator - I = LI->begin(), E = LI->end(); I != E; ++I) { + for (MachineLoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) { CurLoop = *I; // Only visit outer-most preheader-sporting loops. @@ -170,7 +174,11 @@ if (!CurPreheader) continue; + // CSEMap is initialized for loop header when the first instruction is + // being hoisted. + FirstInLoop = true; HoistRegion(DT->getNode(CurLoop->getHeader())); + CSEMap.clear(); } return Changed; @@ -191,10 +199,7 @@ for (MachineBasicBlock::iterator MII = BB->begin(), E = BB->end(); MII != E; ) { MachineBasicBlock::iterator NextMII = MII; ++NextMII; - MachineInstr &MI = *MII; - - Hoist(&MI); - + Hoist(&*MII); MII = NextMII; } @@ -430,6 +435,27 @@ return NewMIs[0]; } +void MachineLICM::InitCSEMap(MachineBasicBlock *BB) { + for (MachineBasicBlock::iterator I = BB->begin(),E = BB->end(); I != E; ++I) { + const MachineInstr *MI = &*I; + // FIXME: For now, only hoist re-materilizable instructions. LICM will + // increase register pressure. We want to make sure it doesn't increase + // spilling. + if (TII->isTriviallyReMaterializable(MI, AA)) { + unsigned Opcode = MI->getOpcode(); + DenseMap >::iterator + CI = CSEMap.find(Opcode); + if (CI != CSEMap.end()) + CI->second.push_back(MI); + else { + std::vector CSEMIs; + CSEMIs.push_back(MI); + CSEMap.insert(std::make_pair(Opcode, CSEMIs)); + } + } + } +} + /// Hoist - When an instruction is found to use only loop invariant operands /// that are safe to hoist, this instruction is called to do the dirty work. /// @@ -454,11 +480,14 @@ errs() << "\n"; }); + // If this is the first instruction being hoisted to the preheader, + // initialize the CSE map with potential common expressions. + InitCSEMap(CurPreheader); + // Look for opportunity to CSE the hoisted instruction. - std::pair BBOpcPair = - std::make_pair(CurPreheader->getNumber(), MI->getOpcode()); - DenseMap, - std::vector >::iterator CI = CSEMap.find(BBOpcPair); + unsigned Opcode = MI->getOpcode(); + DenseMap >::iterator + CI = CSEMap.find(Opcode); bool DoneCSE = false; if (CI != CSEMap.end()) { const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo); @@ -477,15 +506,15 @@ // Otherwise, splice the instruction to the preheader. if (!DoneCSE) { - CurPreheader->splice(CurPreheader->getFirstTerminator(), - MI->getParent(), MI); + CurPreheader->splice(CurPreheader->getFirstTerminator(),MI->getParent(),MI); + // Add to the CSE map. if (CI != CSEMap.end()) CI->second.push_back(MI); else { std::vector CSEMIs; CSEMIs.push_back(MI); - CSEMap.insert(std::make_pair(BBOpcPair, CSEMIs)); + CSEMap.insert(std::make_pair(Opcode, CSEMIs)); } } Modified: llvm/trunk/test/CodeGen/ARM/remat.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/remat.ll?rev=85799&r1=85798&r2=85799&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/remat.ll (original) +++ llvm/trunk/test/CodeGen/ARM/remat.ll Mon Nov 2 02:09:49 2009 @@ -1,5 +1,5 @@ ; RUN: llc < %s -mtriple=arm-apple-darwin -; RUN: llc < %s -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 4 +; RUN: llc < %s -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 5 %struct.CONTENTBOX = type { i32, i32, i32, i32, i32 } %struct.LOCBOX = type { i32, i32, i32, i32 } Modified: llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll?rev=85799&r1=85798&r2=85799&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Mon Nov 2 02:09:49 2009 @@ -1,6 +1,5 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 -stats |& \ -; RUN: grep {1 .*folded into instructions} -; Increment in loop bb.128.i adjusted to 2, to prevent loop reversal from +; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s +; Increment in loop bb.i28.i adjusted to 2, to prevent loop reversal from ; kicking in. declare fastcc void @rdft(i32, i32, double*, i32*, double*) @@ -34,6 +33,9 @@ br label %bb.i28.i bb.i28.i: ; preds = %bb.i28.i, %cond_next36.i +; CHECK: %bb.i28.i +; CHECK: addl $2 +; CHECK: addl $2 %j.0.reg2mem.0.i16.i = phi i32 [ 0, %cond_next36.i ], [ %indvar.next39.i, %bb.i28.i ] ; [#uses=2] %din_addr.1.reg2mem.0.i17.i = phi double [ 0.000000e+00, %cond_next36.i ], [ %tmp16.i25.i, %bb.i28.i ] ; [#uses=1] %tmp1.i18.i = fptosi double %din_addr.1.reg2mem.0.i17.i to i32 ; [#uses=2] From baldrick at free.fr Mon Nov 2 08:23:47 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 02 Nov 2009 15:23:47 +0100 Subject: [llvm-commits] [llvm] r85738 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/phi.ll In-Reply-To: <200911012007.nA1K78eB012267@zion.cs.uiuc.edu> References: <200911012007.nA1K78eB012267@zion.cs.uiuc.edu> Message-ID: <4AEEEB73.9070101@free.fr> Hi Chris, > - LoadAlignment = std::max(LoadAlignment, LI->getAlignment()); > + LoadAlignment = std::min(LoadAlignment, LI->getAlignment()); if one alignment is zero and the other is not, then zero (the minimum) may be the wrong result. On the other hand, if one is zero and the other is over aligned (bigger than the ABI alignment), then zero is the right thing, not the bigger alignment. You need target data to get this right. Ciao, Duncan. From baldrick at free.fr Mon Nov 2 09:48:33 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 02 Nov 2009 15:48:33 -0000 Subject: [llvm-commits] [dragonegg] r85802 - /dragonegg/trunk/www/index.html Message-ID: <200911021548.nA2FmX5a007104@zion.cs.uiuc.edu> Author: baldrick Date: Mon Nov 2 09:48:31 2009 New Revision: 85802 URL: http://llvm.org/viewvc/llvm-project?rev=85802&view=rev Log: I hereby decree that indirect gotos work properly with dragonegg. Since they use the new indirect branch and block address stuff, this is not entirely true, but will be soon. Modified: dragonegg/trunk/www/index.html Modified: dragonegg/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/www/index.html?rev=85802&r1=85801&r2=85802&view=diff ============================================================================== --- dragonegg/trunk/www/index.html (original) +++ dragonegg/trunk/www/index.html Mon Nov 2 09:48:31 2009 @@ -40,7 +40,6 @@
  • Ada and C++ work somewhat
  • Java, Obj-C and Obj-C++ are untested
  • Exception handling does not work
  • -
  • Indirect gotos do not always work
  • Limited debug info
  • Requires one gcc patch
  • Only supports x86-32 and x86-64
  • From baldrick at free.fr Mon Nov 2 09:56:37 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 02 Nov 2009 15:56:37 -0000 Subject: [llvm-commits] [dragonegg] r85803 - in /dragonegg/trunk: TODO x86/llvm-target.cpp Message-ID: <200911021556.nA2Fuco5007559@zion.cs.uiuc.edu> Author: baldrick Date: Mon Nov 2 09:56:37 2009 New Revision: 85803 URL: http://llvm.org/viewvc/llvm-project?rev=85803&view=rev Log: Add the list of all x86 builtins supported by gcc-4.5, with ones we don't support commented out. This way it is easy to see what needs doing. Add a note about how we could easily add support for several gcc builtins. Comment out the IX86_BUILTIN_LOADQ expansion code from llvm-gcc, because I couldn't work out which gcc intrinsic (if any) it corresponds to. Modified: dragonegg/trunk/TODO dragonegg/trunk/x86/llvm-target.cpp Modified: dragonegg/trunk/TODO URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/TODO?rev=85803&r1=85802&r2=85803&view=diff ============================================================================== --- dragonegg/trunk/TODO (original) +++ dragonegg/trunk/TODO Mon Nov 2 09:56:37 2009 @@ -62,3 +62,7 @@ Output proper debug info rather than throwing most of it away. Add support for exception handling. + +Many x86 specific builtins are not supported, even though it would be easy to +add support for some of them, for example the 256 bit versions of builtins we +do support. Improve this. Modified: dragonegg/trunk/x86/llvm-target.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/x86/llvm-target.cpp?rev=85803&r1=85802&r2=85803&view=diff ============================================================================== --- dragonegg/trunk/x86/llvm-target.cpp (original) +++ dragonegg/trunk/x86/llvm-target.cpp Mon Nov 2 09:56:37 2009 @@ -82,18 +82,42 @@ const Type *ResultType, std::vector &Ops) { const HandlerEntry Handlers[] = { + // Unsupported builtins are commented out. {"__builtin_ia32_addpd", &&IX86_BUILTIN_ADDPD}, - {"__builtin_ia32_addpd256", &&IX86_BUILTIN_ADDPD}, + //{"__builtin_ia32_addpd256", &&IX86_BUILTIN_ADDPD256}, {"__builtin_ia32_addps", &&IX86_BUILTIN_ADDPS}, - {"__builtin_ia32_addps256", &&IX86_BUILTIN_ADDPS}, + //{"__builtin_ia32_addps256", &&IX86_BUILTIN_ADDPS256}, + //{"__builtin_ia32_addsd", &&IX86_BUILTIN_ADDSD}, + //{"__builtin_ia32_addss", &&IX86_BUILTIN_ADDSS}, + //{"__builtin_ia32_addsubpd", &&IX86_BUILTIN_ADDSUBPD}, + //{"__builtin_ia32_addsubpd256", &&IX86_BUILTIN_ADDSUBPD256}, + //{"__builtin_ia32_addsubps", &&IX86_BUILTIN_ADDSUBPS}, + //{"__builtin_ia32_addsubps256", &&IX86_BUILTIN_ADDSUBPS256}, + //{"__builtin_ia32_aesdec128", &&IX86_BUILTIN_AESDEC128}, + //{"__builtin_ia32_aesdeclast128", &&IX86_BUILTIN_AESDECLAST128}, + //{"__builtin_ia32_aesenc128", &&IX86_BUILTIN_AESENC128}, + //{"__builtin_ia32_aesenclast128", &&IX86_BUILTIN_AESENCLAST128}, + //{"__builtin_ia32_aesimc128", &&IX86_BUILTIN_AESIMC128}, + //{"__builtin_ia32_aeskeygenassist128", &&IX86_BUILTIN_AESKEYGENASSIST128}, {"__builtin_ia32_andnpd", &&IX86_BUILTIN_ANDNPD}, - {"__builtin_ia32_andnpd256", &&IX86_BUILTIN_ANDNPD}, + //{"__builtin_ia32_andnpd256", &&IX86_BUILTIN_ANDNPD256}, {"__builtin_ia32_andnps", &&IX86_BUILTIN_ANDNPS}, - {"__builtin_ia32_andnps256", &&IX86_BUILTIN_ANDNPS}, + //{"__builtin_ia32_andnps256", &&IX86_BUILTIN_ANDNPS256}, {"__builtin_ia32_andpd", &&IX86_BUILTIN_ANDPD}, - {"__builtin_ia32_andpd256", &&IX86_BUILTIN_ANDPD}, + //{"__builtin_ia32_andpd256", &&IX86_BUILTIN_ANDPD256}, {"__builtin_ia32_andps", &&IX86_BUILTIN_ANDPS}, - {"__builtin_ia32_andps256", &&IX86_BUILTIN_ANDPS}, + //{"__builtin_ia32_andps256", &&IX86_BUILTIN_ANDPS256}, + //{"__builtin_ia32_blendpd", &&IX86_BUILTIN_BLENDPD}, + //{"__builtin_ia32_blendpd256", &&IX86_BUILTIN_BLENDPD256}, + //{"__builtin_ia32_blendps", &&IX86_BUILTIN_BLENDPS}, + //{"__builtin_ia32_blendps256", &&IX86_BUILTIN_BLENDPS256}, + //{"__builtin_ia32_blendvpd", &&IX86_BUILTIN_BLENDVPD}, + //{"__builtin_ia32_blendvpd256", &&IX86_BUILTIN_BLENDVPD256}, + //{"__builtin_ia32_blendvps", &&IX86_BUILTIN_BLENDVPS}, + //{"__builtin_ia32_blendvps256", &&IX86_BUILTIN_BLENDVPS256}, + //{"__builtin_ia32_bsrdi", &&IX86_BUILTIN_BSRDI}, + //{"__builtin_ia32_bsrsi", &&IX86_BUILTIN_BSRSI}, + //{"__builtin_ia32_clflush", &&IX86_BUILTIN_CLFLUSH}, {"__builtin_ia32_cmpeqpd", &&IX86_BUILTIN_CMPEQPD}, {"__builtin_ia32_cmpeqps", &&IX86_BUILTIN_CMPEQPS}, {"__builtin_ia32_cmpeqsd", &&IX86_BUILTIN_CMPEQSD}, @@ -116,8 +140,10 @@ {"__builtin_ia32_cmpneqss", &&IX86_BUILTIN_CMPNEQSS}, {"__builtin_ia32_cmpngepd", &&IX86_BUILTIN_CMPNGEPD}, {"__builtin_ia32_cmpngeps", &&IX86_BUILTIN_CMPNGEPS}, + //{"__builtin_ia32_cmpngess", &&IX86_BUILTIN_CMPNGESS}, {"__builtin_ia32_cmpngtpd", &&IX86_BUILTIN_CMPNGTPD}, {"__builtin_ia32_cmpngtps", &&IX86_BUILTIN_CMPNGTPS}, + //{"__builtin_ia32_cmpngtss", &&IX86_BUILTIN_CMPNGTSS}, {"__builtin_ia32_cmpnlepd", &&IX86_BUILTIN_CMPNLEPD}, {"__builtin_ia32_cmpnleps", &&IX86_BUILTIN_CMPNLEPS}, {"__builtin_ia32_cmpnlesd", &&IX86_BUILTIN_CMPNLESD}, @@ -130,71 +156,400 @@ {"__builtin_ia32_cmpordps", &&IX86_BUILTIN_CMPORDPS}, {"__builtin_ia32_cmpordsd", &&IX86_BUILTIN_CMPORDSD}, {"__builtin_ia32_cmpordss", &&IX86_BUILTIN_CMPORDSS}, + //{"__builtin_ia32_cmppd", &&IX86_BUILTIN_CMPPD}, + //{"__builtin_ia32_cmppd256", &&IX86_BUILTIN_CMPPD256}, + //{"__builtin_ia32_cmpps", &&IX86_BUILTIN_CMPPS}, + //{"__builtin_ia32_cmpps256", &&IX86_BUILTIN_CMPPS256}, + //{"__builtin_ia32_cmpsd", &&IX86_BUILTIN_CMPSD}, + //{"__builtin_ia32_cmpss", &&IX86_BUILTIN_CMPSS}, {"__builtin_ia32_cmpunordpd", &&IX86_BUILTIN_CMPUNORDPD}, {"__builtin_ia32_cmpunordps", &&IX86_BUILTIN_CMPUNORDPS}, {"__builtin_ia32_cmpunordsd", &&IX86_BUILTIN_CMPUNORDSD}, {"__builtin_ia32_cmpunordss", &&IX86_BUILTIN_CMPUNORDSS}, + //{"__builtin_ia32_comieq", &&IX86_BUILTIN_COMIEQSS}, + //{"__builtin_ia32_comige", &&IX86_BUILTIN_COMIGESS}, + //{"__builtin_ia32_comigt", &&IX86_BUILTIN_COMIGTSS}, + //{"__builtin_ia32_comile", &&IX86_BUILTIN_COMILESS}, + //{"__builtin_ia32_comilt", &&IX86_BUILTIN_COMILTSS}, + //{"__builtin_ia32_comineq", &&IX86_BUILTIN_COMINEQSS}, + //{"__builtin_ia32_comisdeq", &&IX86_BUILTIN_COMIEQSD}, + //{"__builtin_ia32_comisdge", &&IX86_BUILTIN_COMIGESD}, + //{"__builtin_ia32_comisdgt", &&IX86_BUILTIN_COMIGTSD}, + //{"__builtin_ia32_comisdle", &&IX86_BUILTIN_COMILESD}, + //{"__builtin_ia32_comisdlt", &&IX86_BUILTIN_COMILTSD}, + //{"__builtin_ia32_comisdneq", &&IX86_BUILTIN_COMINEQSD}, + //{"__builtin_ia32_copysignpd", &&IX86_BUILTIN_CPYSGNPD}, + //{"__builtin_ia32_copysignps", &&IX86_BUILTIN_CPYSGNPS}, + //{"__builtin_ia32_crc32di", &&IX86_BUILTIN_CRC32DI}, + //{"__builtin_ia32_crc32hi", &&IX86_BUILTIN_CRC32HI}, + //{"__builtin_ia32_crc32qi", &&IX86_BUILTIN_CRC32QI}, + //{"__builtin_ia32_crc32si", &&IX86_BUILTIN_CRC32SI}, + //{"__builtin_ia32_cvtdq2pd", &&IX86_BUILTIN_CVTDQ2PD}, + //{"__builtin_ia32_cvtdq2pd256", &&IX86_BUILTIN_CVTDQ2PD256}, + //{"__builtin_ia32_cvtdq2ps", &&IX86_BUILTIN_CVTDQ2PS}, + //{"__builtin_ia32_cvtdq2ps256", &&IX86_BUILTIN_CVTDQ2PS256}, + //{"__builtin_ia32_cvtpd2dq", &&IX86_BUILTIN_CVTPD2DQ}, + //{"__builtin_ia32_cvtpd2dq256", &&IX86_BUILTIN_CVTPD2DQ256}, + //{"__builtin_ia32_cvtpd2pi", &&IX86_BUILTIN_CVTPD2PI}, + //{"__builtin_ia32_cvtpd2ps", &&IX86_BUILTIN_CVTPD2PS}, + //{"__builtin_ia32_cvtpd2ps256", &&IX86_BUILTIN_CVTPD2PS256}, + //{"__builtin_ia32_cvtpi2pd", &&IX86_BUILTIN_CVTPI2PD}, + //{"__builtin_ia32_cvtpi2ps", &&IX86_BUILTIN_CVTPI2PS}, + //{"__builtin_ia32_cvtps2dq", &&IX86_BUILTIN_CVTPS2DQ}, + //{"__builtin_ia32_cvtps2dq256", &&IX86_BUILTIN_CVTPS2DQ256}, + //{"__builtin_ia32_cvtps2pd", &&IX86_BUILTIN_CVTPS2PD}, + //{"__builtin_ia32_cvtps2pd256", &&IX86_BUILTIN_CVTPS2PD256}, + //{"__builtin_ia32_cvtps2pi", &&IX86_BUILTIN_CVTPS2PI}, + //{"__builtin_ia32_cvtsd2si", &&IX86_BUILTIN_CVTSD2SI}, + //{"__builtin_ia32_cvtsd2si64", &&IX86_BUILTIN_CVTSD2SI64}, + //{"__builtin_ia32_cvtsd2ss", &&IX86_BUILTIN_CVTSD2SS}, + //{"__builtin_ia32_cvtsi2sd", &&IX86_BUILTIN_CVTSI2SD}, + //{"__builtin_ia32_cvtsi2ss", &&IX86_BUILTIN_CVTSI2SS}, + //{"__builtin_ia32_cvtsi642sd", &&IX86_BUILTIN_CVTSI642SD}, + //{"__builtin_ia32_cvtsi642ss", &&IX86_BUILTIN_CVTSI642SS}, + //{"__builtin_ia32_cvtss2sd", &&IX86_BUILTIN_CVTSS2SD}, + //{"__builtin_ia32_cvtss2si", &&IX86_BUILTIN_CVTSS2SI}, + //{"__builtin_ia32_cvtss2si64", &&IX86_BUILTIN_CVTSS2SI64}, + //{"__builtin_ia32_cvttpd2dq", &&IX86_BUILTIN_CVTTPD2DQ}, + //{"__builtin_ia32_cvttpd2dq256", &&IX86_BUILTIN_CVTTPD2DQ256}, + //{"__builtin_ia32_cvttpd2pi", &&IX86_BUILTIN_CVTTPD2PI}, + //{"__builtin_ia32_cvttps2dq", &&IX86_BUILTIN_CVTTPS2DQ}, + //{"__builtin_ia32_cvttps2dq256", &&IX86_BUILTIN_CVTTPS2DQ256}, + //{"__builtin_ia32_cvttps2pi", &&IX86_BUILTIN_CVTTPS2PI}, + //{"__builtin_ia32_cvttsd2si", &&IX86_BUILTIN_CVTTSD2SI}, + //{"__builtin_ia32_cvttsd2si64", &&IX86_BUILTIN_CVTTSD2SI64}, + //{"__builtin_ia32_cvttss2si", &&IX86_BUILTIN_CVTTSS2SI}, + //{"__builtin_ia32_cvttss2si64", &&IX86_BUILTIN_CVTTSS2SI64}, + //{"__builtin_ia32_cvtudq2ps", &&IX86_BUILTIN_CVTUDQ2PS}, {"__builtin_ia32_divpd", &&IX86_BUILTIN_DIVPD}, - {"__builtin_ia32_divpd256", &&IX86_BUILTIN_DIVPD}, + //{"__builtin_ia32_divpd256", &&IX86_BUILTIN_DIVPD256}, {"__builtin_ia32_divps", &&IX86_BUILTIN_DIVPS}, - {"__builtin_ia32_divps256", &&IX86_BUILTIN_DIVPS}, + //{"__builtin_ia32_divps256", &&IX86_BUILTIN_DIVPS256}, + //{"__builtin_ia32_divsd", &&IX86_BUILTIN_DIVSD}, + //{"__builtin_ia32_divss", &&IX86_BUILTIN_DIVSS}, + //{"__builtin_ia32_dppd", &&IX86_BUILTIN_DPPD}, + //{"__builtin_ia32_dpps", &&IX86_BUILTIN_DPPS}, + //{"__builtin_ia32_dpps256", &&IX86_BUILTIN_DPPS256}, + //{"__builtin_ia32_emms", &&IX86_BUILTIN_EMMS}, + //{"__builtin_ia32_extrq", &&IX86_BUILTIN_EXTRQ}, + //{"__builtin_ia32_extrqi", &&IX86_BUILTIN_EXTRQI}, + //{"__builtin_ia32_femms", &&IX86_BUILTIN_FEMMS}, + //{"__builtin_ia32_haddpd", &&IX86_BUILTIN_HADDPD}, + //{"__builtin_ia32_haddpd256", &&IX86_BUILTIN_HADDPD256}, + //{"__builtin_ia32_haddps", &&IX86_BUILTIN_HADDPS}, + //{"__builtin_ia32_haddps256", &&IX86_BUILTIN_HADDPS256}, + //{"__builtin_ia32_hsubpd", &&IX86_BUILTIN_HSUBPD}, + //{"__builtin_ia32_hsubpd256", &&IX86_BUILTIN_HSUBPD256}, + //{"__builtin_ia32_hsubps", &&IX86_BUILTIN_HSUBPS}, + //{"__builtin_ia32_hsubps256", &&IX86_BUILTIN_HSUBPS256}, + //{"__builtin_ia32_insertps128", &&IX86_BUILTIN_INSERTPS128}, + //{"__builtin_ia32_insertq", &&IX86_BUILTIN_INSERTQ}, + //{"__builtin_ia32_insertqi", &&IX86_BUILTIN_INSERTQI}, + //{"__builtin_ia32_lddqu", &&IX86_BUILTIN_LDDQU}, + //{"__builtin_ia32_lddqu256", &&IX86_BUILTIN_LDDQU256}, {"__builtin_ia32_ldmxcsr", &&IX86_BUILTIN_LDMXCSR}, + //{"__builtin_ia32_lfence", &&IX86_BUILTIN_LFENCE}, {"__builtin_ia32_loaddqu", &&IX86_BUILTIN_LOADDQU}, - {"__builtin_ia32_loaddqu256", &&IX86_BUILTIN_LOADDQU}, + //{"__builtin_ia32_loaddqu256", &&IX86_BUILTIN_LOADDQU256}, {"__builtin_ia32_loadhpd", &&IX86_BUILTIN_LOADHPD}, {"__builtin_ia32_loadhps", &&IX86_BUILTIN_LOADHPS}, {"__builtin_ia32_loadlpd", &&IX86_BUILTIN_LOADLPD}, {"__builtin_ia32_loadlps", &&IX86_BUILTIN_LOADLPS}, - {"__builtin_ia32_loadlv4si", &&IX86_BUILTIN_LOADQ}, {"__builtin_ia32_loadupd", &&IX86_BUILTIN_LOADUPD}, - {"__builtin_ia32_loadupd256", &&IX86_BUILTIN_LOADUPD}, + //{"__builtin_ia32_loadupd256", &&IX86_BUILTIN_LOADUPD256}, {"__builtin_ia32_loadups", &&IX86_BUILTIN_LOADUPS}, - {"__builtin_ia32_loadups256", &&IX86_BUILTIN_LOADUPS}, + //{"__builtin_ia32_loadups256", &&IX86_BUILTIN_LOADUPS256}, + //{"__builtin_ia32_maskloadpd", &&IX86_BUILTIN_MASKLOADPD}, + //{"__builtin_ia32_maskloadpd256", &&IX86_BUILTIN_MASKLOADPD256}, + //{"__builtin_ia32_maskloadps", &&IX86_BUILTIN_MASKLOADPS}, + //{"__builtin_ia32_maskloadps256", &&IX86_BUILTIN_MASKLOADPS256}, + //{"__builtin_ia32_maskmovdqu", &&IX86_BUILTIN_MASKMOVDQU}, + //{"__builtin_ia32_maskmovq", &&IX86_BUILTIN_MASKMOVQ}, + //{"__builtin_ia32_maskstorepd", &&IX86_BUILTIN_MASKSTOREPD}, + //{"__builtin_ia32_maskstorepd256", &&IX86_BUILTIN_MASKSTOREPD256}, + //{"__builtin_ia32_maskstoreps", &&IX86_BUILTIN_MASKSTOREPS}, + //{"__builtin_ia32_maskstoreps256", &&IX86_BUILTIN_MASKSTOREPS256}, + //{"__builtin_ia32_maxpd", &&IX86_BUILTIN_MAXPD}, + //{"__builtin_ia32_maxpd256", &&IX86_BUILTIN_MAXPD256}, + //{"__builtin_ia32_maxps", &&IX86_BUILTIN_MAXPS}, + //{"__builtin_ia32_maxps256", &&IX86_BUILTIN_MAXPS256}, + //{"__builtin_ia32_maxsd", &&IX86_BUILTIN_MAXSD}, + //{"__builtin_ia32_maxss", &&IX86_BUILTIN_MAXSS}, + //{"__builtin_ia32_mfence", &&IX86_BUILTIN_MFENCE}, + //{"__builtin_ia32_minpd", &&IX86_BUILTIN_MINPD}, + //{"__builtin_ia32_minpd256", &&IX86_BUILTIN_MINPD256}, + //{"__builtin_ia32_minps", &&IX86_BUILTIN_MINPS}, + //{"__builtin_ia32_minps256", &&IX86_BUILTIN_MINPS256}, + //{"__builtin_ia32_minsd", &&IX86_BUILTIN_MINSD}, + //{"__builtin_ia32_minss", &&IX86_BUILTIN_MINSS}, + //{"__builtin_ia32_monitor", &&IX86_BUILTIN_MONITOR}, + //{"__builtin_ia32_movddup256", &&IX86_BUILTIN_MOVDDUP256}, {"__builtin_ia32_movhlps", &&IX86_BUILTIN_MOVHLPS}, {"__builtin_ia32_movlhps", &&IX86_BUILTIN_MOVLHPS}, + //{"__builtin_ia32_movmskpd", &&IX86_BUILTIN_MOVMSKPD}, + //{"__builtin_ia32_movmskpd256", &&IX86_BUILTIN_MOVMSKPD256}, + //{"__builtin_ia32_movmskps", &&IX86_BUILTIN_MOVMSKPS}, + //{"__builtin_ia32_movmskps256", &&IX86_BUILTIN_MOVMSKPS256}, + //{"__builtin_ia32_movntdq", &&IX86_BUILTIN_MOVNTDQ}, + //{"__builtin_ia32_movntdq256", &&IX86_BUILTIN_MOVNTDQ256}, + //{"__builtin_ia32_movntdqa", &&IX86_BUILTIN_MOVNTDQA}, + //{"__builtin_ia32_movnti", &&IX86_BUILTIN_MOVNTI}, + //{"__builtin_ia32_movntpd", &&IX86_BUILTIN_MOVNTPD}, + //{"__builtin_ia32_movntpd256", &&IX86_BUILTIN_MOVNTPD256}, + //{"__builtin_ia32_movntps", &&IX86_BUILTIN_MOVNTPS}, + //{"__builtin_ia32_movntps256", &&IX86_BUILTIN_MOVNTPS256}, + //{"__builtin_ia32_movntq", &&IX86_BUILTIN_MOVNTQ}, + //{"__builtin_ia32_movntsd", &&IX86_BUILTIN_MOVNTSD}, + //{"__builtin_ia32_movntss", &&IX86_BUILTIN_MOVNTSS}, {"__builtin_ia32_movq128", &&IX86_BUILTIN_MOVQ128}, {"__builtin_ia32_movsd", &&IX86_BUILTIN_MOVSD}, {"__builtin_ia32_movshdup", &&IX86_BUILTIN_MOVSHDUP}, - {"__builtin_ia32_movshdup256", &&IX86_BUILTIN_MOVSHDUP}, + //{"__builtin_ia32_movshdup256", &&IX86_BUILTIN_MOVSHDUP256}, {"__builtin_ia32_movsldup", &&IX86_BUILTIN_MOVSLDUP}, - {"__builtin_ia32_movsldup256", &&IX86_BUILTIN_MOVSLDUP}, + //{"__builtin_ia32_movsldup256", &&IX86_BUILTIN_MOVSLDUP256}, {"__builtin_ia32_movss", &&IX86_BUILTIN_MOVSS}, + //{"__builtin_ia32_mpsadbw128", &&IX86_BUILTIN_MPSADBW128}, {"__builtin_ia32_mulpd", &&IX86_BUILTIN_MULPD}, - {"__builtin_ia32_mulpd256", &&IX86_BUILTIN_MULPD}, + //{"__builtin_ia32_mulpd256", &&IX86_BUILTIN_MULPD256}, {"__builtin_ia32_mulps", &&IX86_BUILTIN_MULPS}, - {"__builtin_ia32_mulps256", &&IX86_BUILTIN_MULPS}, + //{"__builtin_ia32_mulps256", &&IX86_BUILTIN_MULPS256}, + //{"__builtin_ia32_mulsd", &&IX86_BUILTIN_MULSD}, + //{"__builtin_ia32_mulss", &&IX86_BUILTIN_MULSS}, + //{"__builtin_ia32_mwait", &&IX86_BUILTIN_MWAIT}, {"__builtin_ia32_orpd", &&IX86_BUILTIN_ORPD}, - {"__builtin_ia32_orpd256", &&IX86_BUILTIN_ORPD}, + //{"__builtin_ia32_orpd256", &&IX86_BUILTIN_ORPD256}, {"__builtin_ia32_orps", &&IX86_BUILTIN_ORPS}, - {"__builtin_ia32_orps256", &&IX86_BUILTIN_ORPS}, + //{"__builtin_ia32_orps256", &&IX86_BUILTIN_ORPS256}, + //{"__builtin_ia32_pabsb", &&IX86_BUILTIN_PABSB}, + //{"__builtin_ia32_pabsb128", &&IX86_BUILTIN_PABSB128}, + //{"__builtin_ia32_pabsd", &&IX86_BUILTIN_PABSD}, + //{"__builtin_ia32_pabsd128", &&IX86_BUILTIN_PABSD128}, + //{"__builtin_ia32_pabsw", &&IX86_BUILTIN_PABSW}, + //{"__builtin_ia32_pabsw128", &&IX86_BUILTIN_PABSW128}, + //{"__builtin_ia32_packssdw", &&IX86_BUILTIN_PACKSSDW}, + //{"__builtin_ia32_packssdw128", &&IX86_BUILTIN_PACKSSDW128}, + //{"__builtin_ia32_packsswb", &&IX86_BUILTIN_PACKSSWB}, + //{"__builtin_ia32_packsswb128", &&IX86_BUILTIN_PACKSSWB128}, + //{"__builtin_ia32_packusdw128", &&IX86_BUILTIN_PACKUSDW128}, + //{"__builtin_ia32_packuswb", &&IX86_BUILTIN_PACKUSWB}, + //{"__builtin_ia32_packuswb128", &&IX86_BUILTIN_PACKUSWB128}, {"__builtin_ia32_paddb", &&IX86_BUILTIN_PADDB}, {"__builtin_ia32_paddb128", &&IX86_BUILTIN_PADDB128}, {"__builtin_ia32_paddd", &&IX86_BUILTIN_PADDD}, {"__builtin_ia32_paddd128", &&IX86_BUILTIN_PADDD128}, {"__builtin_ia32_paddq", &&IX86_BUILTIN_PADDQ}, {"__builtin_ia32_paddq128", &&IX86_BUILTIN_PADDQ128}, + //{"__builtin_ia32_paddsb", &&IX86_BUILTIN_PADDSB}, + //{"__builtin_ia32_paddsb128", &&IX86_BUILTIN_PADDSB128}, + //{"__builtin_ia32_paddsw", &&IX86_BUILTIN_PADDSW}, + //{"__builtin_ia32_paddsw128", &&IX86_BUILTIN_PADDSW128}, + //{"__builtin_ia32_paddusb", &&IX86_BUILTIN_PADDUSB}, + //{"__builtin_ia32_paddusb128", &&IX86_BUILTIN_PADDUSB128}, + //{"__builtin_ia32_paddusw", &&IX86_BUILTIN_PADDUSW}, + //{"__builtin_ia32_paddusw128", &&IX86_BUILTIN_PADDUSW128}, {"__builtin_ia32_paddw", &&IX86_BUILTIN_PADDW}, {"__builtin_ia32_paddw128", &&IX86_BUILTIN_PADDW128}, + //{"__builtin_ia32_palignr", &&IX86_BUILTIN_PALIGNR}, + //{"__builtin_ia32_palignr128", &&IX86_BUILTIN_PALIGNR128}, {"__builtin_ia32_pand", &&IX86_BUILTIN_PAND}, {"__builtin_ia32_pand128", &&IX86_BUILTIN_PAND128}, {"__builtin_ia32_pandn", &&IX86_BUILTIN_PANDN}, {"__builtin_ia32_pandn128", &&IX86_BUILTIN_PANDN128}, + //{"__builtin_ia32_pavgb", &&IX86_BUILTIN_PAVGB}, + //{"__builtin_ia32_pavgb128", &&IX86_BUILTIN_PAVGB128}, + //{"__builtin_ia32_pavgusb", &&IX86_BUILTIN_PAVGUSB}, + //{"__builtin_ia32_pavgw", &&IX86_BUILTIN_PAVGW}, + //{"__builtin_ia32_pavgw128", &&IX86_BUILTIN_PAVGW128}, + //{"__builtin_ia32_pblendvb128", &&IX86_BUILTIN_PBLENDVB128}, + //{"__builtin_ia32_pblendw128", &&IX86_BUILTIN_PBLENDW128}, + //{"__builtin_ia32_pclmulqdq128", &&IX86_BUILTIN_PCLMULQDQ128}, + //{"__builtin_ia32_pcmpeqb", &&IX86_BUILTIN_PCMPEQB}, + //{"__builtin_ia32_pcmpeqb128", &&IX86_BUILTIN_PCMPEQB128}, + //{"__builtin_ia32_pcmpeqd", &&IX86_BUILTIN_PCMPEQD}, + //{"__builtin_ia32_pcmpeqd128", &&IX86_BUILTIN_PCMPEQD128}, + //{"__builtin_ia32_pcmpeqq", &&IX86_BUILTIN_PCMPEQQ}, + //{"__builtin_ia32_pcmpeqw", &&IX86_BUILTIN_PCMPEQW}, + //{"__builtin_ia32_pcmpeqw128", &&IX86_BUILTIN_PCMPEQW128}, + //{"__builtin_ia32_pcmpestri128", &&IX86_BUILTIN_PCMPESTRI128}, + //{"__builtin_ia32_pcmpestria128", &&IX86_BUILTIN_PCMPESTRA128}, + //{"__builtin_ia32_pcmpestric128", &&IX86_BUILTIN_PCMPESTRC128}, + //{"__builtin_ia32_pcmpestrio128", &&IX86_BUILTIN_PCMPESTRO128}, + //{"__builtin_ia32_pcmpestris128", &&IX86_BUILTIN_PCMPESTRS128}, + //{"__builtin_ia32_pcmpestriz128", &&IX86_BUILTIN_PCMPESTRZ128}, + //{"__builtin_ia32_pcmpestrm128", &&IX86_BUILTIN_PCMPESTRM128}, + //{"__builtin_ia32_pcmpgtb", &&IX86_BUILTIN_PCMPGTB}, + //{"__builtin_ia32_pcmpgtb128", &&IX86_BUILTIN_PCMPGTB128}, + //{"__builtin_ia32_pcmpgtd", &&IX86_BUILTIN_PCMPGTD}, + //{"__builtin_ia32_pcmpgtd128", &&IX86_BUILTIN_PCMPGTD128}, + //{"__builtin_ia32_pcmpgtq", &&IX86_BUILTIN_PCMPGTQ}, + //{"__builtin_ia32_pcmpgtw", &&IX86_BUILTIN_PCMPGTW}, + //{"__builtin_ia32_pcmpgtw128", &&IX86_BUILTIN_PCMPGTW128}, + //{"__builtin_ia32_pcmpistri128", &&IX86_BUILTIN_PCMPISTRI128}, + //{"__builtin_ia32_pcmpistria128", &&IX86_BUILTIN_PCMPISTRA128}, + //{"__builtin_ia32_pcmpistric128", &&IX86_BUILTIN_PCMPISTRC128}, + //{"__builtin_ia32_pcmpistrio128", &&IX86_BUILTIN_PCMPISTRO128}, + //{"__builtin_ia32_pcmpistris128", &&IX86_BUILTIN_PCMPISTRS128}, + //{"__builtin_ia32_pcmpistriz128", &&IX86_BUILTIN_PCMPISTRZ128}, + //{"__builtin_ia32_pcmpistrm128", &&IX86_BUILTIN_PCMPISTRM128}, + //{"__builtin_ia32_pd256_pd", &&IX86_BUILTIN_PD256_PD}, + //{"__builtin_ia32_pd_pd256", &&IX86_BUILTIN_PD_PD256}, + //{"__builtin_ia32_pf2id", &&IX86_BUILTIN_PF2ID}, + //{"__builtin_ia32_pf2iw", &&IX86_BUILTIN_PF2IW}, + //{"__builtin_ia32_pfacc", &&IX86_BUILTIN_PFACC}, + //{"__builtin_ia32_pfadd", &&IX86_BUILTIN_PFADD}, + //{"__builtin_ia32_pfcmpeq", &&IX86_BUILTIN_PFCMPEQ}, + //{"__builtin_ia32_pfcmpge", &&IX86_BUILTIN_PFCMPGE}, + //{"__builtin_ia32_pfcmpgt", &&IX86_BUILTIN_PFCMPGT}, + //{"__builtin_ia32_pfmax", &&IX86_BUILTIN_PFMAX}, + //{"__builtin_ia32_pfmin", &&IX86_BUILTIN_PFMIN}, + //{"__builtin_ia32_pfmul", &&IX86_BUILTIN_PFMUL}, + //{"__builtin_ia32_pfnacc", &&IX86_BUILTIN_PFNACC}, + //{"__builtin_ia32_pfpnacc", &&IX86_BUILTIN_PFPNACC}, + //{"__builtin_ia32_pfrcp", &&IX86_BUILTIN_PFRCP}, + //{"__builtin_ia32_pfrcpit1", &&IX86_BUILTIN_PFRCPIT1}, + //{"__builtin_ia32_pfrcpit2", &&IX86_BUILTIN_PFRCPIT2}, + //{"__builtin_ia32_pfrsqit1", &&IX86_BUILTIN_PFRSQIT1}, + //{"__builtin_ia32_pfrsqrt", &&IX86_BUILTIN_PFRSQRT}, + //{"__builtin_ia32_pfsub", &&IX86_BUILTIN_PFSUB}, + //{"__builtin_ia32_pfsubr", &&IX86_BUILTIN_PFSUBR}, + //{"__builtin_ia32_phaddd", &&IX86_BUILTIN_PHADDD}, + //{"__builtin_ia32_phaddd128", &&IX86_BUILTIN_PHADDD128}, + //{"__builtin_ia32_phaddsw", &&IX86_BUILTIN_PHADDSW}, + //{"__builtin_ia32_phaddsw128", &&IX86_BUILTIN_PHADDSW128}, + //{"__builtin_ia32_phaddw", &&IX86_BUILTIN_PHADDW}, + //{"__builtin_ia32_phaddw128", &&IX86_BUILTIN_PHADDW128}, + //{"__builtin_ia32_phminposuw128", &&IX86_BUILTIN_PHMINPOSUW128}, + //{"__builtin_ia32_phsubd", &&IX86_BUILTIN_PHSUBD}, + //{"__builtin_ia32_phsubd128", &&IX86_BUILTIN_PHSUBD128}, + //{"__builtin_ia32_phsubsw", &&IX86_BUILTIN_PHSUBSW}, + //{"__builtin_ia32_phsubsw128", &&IX86_BUILTIN_PHSUBSW128}, + //{"__builtin_ia32_phsubw", &&IX86_BUILTIN_PHSUBW}, + //{"__builtin_ia32_phsubw128", &&IX86_BUILTIN_PHSUBW128}, + //{"__builtin_ia32_pi2fd", &&IX86_BUILTIN_PI2FD}, + //{"__builtin_ia32_pi2fw", &&IX86_BUILTIN_PI2FW}, + //{"__builtin_ia32_pmaddubsw", &&IX86_BUILTIN_PMADDUBSW}, + //{"__builtin_ia32_pmaddubsw128", &&IX86_BUILTIN_PMADDUBSW128}, + //{"__builtin_ia32_pmaddwd", &&IX86_BUILTIN_PMADDWD}, + //{"__builtin_ia32_pmaddwd128", &&IX86_BUILTIN_PMADDWD128}, + //{"__builtin_ia32_pmaxsb128", &&IX86_BUILTIN_PMAXSB128}, + //{"__builtin_ia32_pmaxsd128", &&IX86_BUILTIN_PMAXSD128}, + //{"__builtin_ia32_pmaxsw", &&IX86_BUILTIN_PMAXSW}, + //{"__builtin_ia32_pmaxsw128", &&IX86_BUILTIN_PMAXSW128}, + //{"__builtin_ia32_pmaxub", &&IX86_BUILTIN_PMAXUB}, + //{"__builtin_ia32_pmaxub128", &&IX86_BUILTIN_PMAXUB128}, + //{"__builtin_ia32_pmaxud128", &&IX86_BUILTIN_PMAXUD128}, + //{"__builtin_ia32_pmaxuw128", &&IX86_BUILTIN_PMAXUW128}, + //{"__builtin_ia32_pminsb128", &&IX86_BUILTIN_PMINSB128}, + //{"__builtin_ia32_pminsd128", &&IX86_BUILTIN_PMINSD128}, + //{"__builtin_ia32_pminsw", &&IX86_BUILTIN_PMINSW}, + //{"__builtin_ia32_pminsw128", &&IX86_BUILTIN_PMINSW128}, + //{"__builtin_ia32_pminub", &&IX86_BUILTIN_PMINUB}, + //{"__builtin_ia32_pminub128", &&IX86_BUILTIN_PMINUB128}, + //{"__builtin_ia32_pminud128", &&IX86_BUILTIN_PMINUD128}, + //{"__builtin_ia32_pminuw128", &&IX86_BUILTIN_PMINUW128}, + //{"__builtin_ia32_pmovmskb", &&IX86_BUILTIN_PMOVMSKB}, + //{"__builtin_ia32_pmovmskb128", &&IX86_BUILTIN_PMOVMSKB128}, + //{"__builtin_ia32_pmovsxbd128", &&IX86_BUILTIN_PMOVSXBD128}, + //{"__builtin_ia32_pmovsxbq128", &&IX86_BUILTIN_PMOVSXBQ128}, + //{"__builtin_ia32_pmovsxbw128", &&IX86_BUILTIN_PMOVSXBW128}, + //{"__builtin_ia32_pmovsxdq128", &&IX86_BUILTIN_PMOVSXDQ128}, + //{"__builtin_ia32_pmovsxwd128", &&IX86_BUILTIN_PMOVSXWD128}, + //{"__builtin_ia32_pmovsxwq128", &&IX86_BUILTIN_PMOVSXWQ128}, + //{"__builtin_ia32_pmovzxbd128", &&IX86_BUILTIN_PMOVZXBD128}, + //{"__builtin_ia32_pmovzxbq128", &&IX86_BUILTIN_PMOVZXBQ128}, + //{"__builtin_ia32_pmovzxbw128", &&IX86_BUILTIN_PMOVZXBW128}, + //{"__builtin_ia32_pmovzxdq128", &&IX86_BUILTIN_PMOVZXDQ128}, + //{"__builtin_ia32_pmovzxwd128", &&IX86_BUILTIN_PMOVZXWD128}, + //{"__builtin_ia32_pmovzxwq128", &&IX86_BUILTIN_PMOVZXWQ128}, + //{"__builtin_ia32_pmuldq128", &&IX86_BUILTIN_PMULDQ128}, + //{"__builtin_ia32_pmulhrsw", &&IX86_BUILTIN_PMULHRSW}, + //{"__builtin_ia32_pmulhrsw128", &&IX86_BUILTIN_PMULHRSW128}, + //{"__builtin_ia32_pmulhrw", &&IX86_BUILTIN_PMULHRW}, + //{"__builtin_ia32_pmulhuw", &&IX86_BUILTIN_PMULHUW}, + //{"__builtin_ia32_pmulhuw128", &&IX86_BUILTIN_PMULHUW128}, + //{"__builtin_ia32_pmulhw", &&IX86_BUILTIN_PMULHW}, + //{"__builtin_ia32_pmulhw128", &&IX86_BUILTIN_PMULHW128}, + //{"__builtin_ia32_pmulld128", &&IX86_BUILTIN_PMULLD128}, {"__builtin_ia32_pmullw", &&IX86_BUILTIN_PMULLW}, {"__builtin_ia32_pmullw128", &&IX86_BUILTIN_PMULLW128}, + //{"__builtin_ia32_pmuludq", &&IX86_BUILTIN_PMULUDQ}, + //{"__builtin_ia32_pmuludq128", &&IX86_BUILTIN_PMULUDQ128}, {"__builtin_ia32_por", &&IX86_BUILTIN_POR}, {"__builtin_ia32_por128", &&IX86_BUILTIN_POR128}, + //{"__builtin_ia32_ps256_ps", &&IX86_BUILTIN_PS256_PS}, + //{"__builtin_ia32_psadbw", &&IX86_BUILTIN_PSADBW}, + //{"__builtin_ia32_psadbw128", &&IX86_BUILTIN_PSADBW128}, + //{"__builtin_ia32_pshufb", &&IX86_BUILTIN_PSHUFB}, + //{"__builtin_ia32_pshufb128", &&IX86_BUILTIN_PSHUFB128}, {"__builtin_ia32_pshufd", &&IX86_BUILTIN_PSHUFD}, {"__builtin_ia32_pshufhw", &&IX86_BUILTIN_PSHUFHW}, {"__builtin_ia32_pshuflw", &&IX86_BUILTIN_PSHUFLW}, {"__builtin_ia32_pshufw", &&IX86_BUILTIN_PSHUFW}, + //{"__builtin_ia32_psignb", &&IX86_BUILTIN_PSIGNB}, + //{"__builtin_ia32_psignb128", &&IX86_BUILTIN_PSIGNB128}, + //{"__builtin_ia32_psignd", &&IX86_BUILTIN_PSIGND}, + //{"__builtin_ia32_psignd128", &&IX86_BUILTIN_PSIGND128}, + //{"__builtin_ia32_psignw", &&IX86_BUILTIN_PSIGNW}, + //{"__builtin_ia32_psignw128", &&IX86_BUILTIN_PSIGNW128}, + //{"__builtin_ia32_pslld", &&IX86_BUILTIN_PSLLD}, + //{"__builtin_ia32_pslld128", &&IX86_BUILTIN_PSLLD128}, + //{"__builtin_ia32_pslldi", &&IX86_BUILTIN_PSLLDI}, + //{"__builtin_ia32_pslldi128", &&IX86_BUILTIN_PSLLDI128}, + //{"__builtin_ia32_pslldqi128", &&IX86_BUILTIN_PSLLDQI128}, + //{"__builtin_ia32_psllq", &&IX86_BUILTIN_PSLLQ}, + //{"__builtin_ia32_psllq128", &&IX86_BUILTIN_PSLLQ128}, + //{"__builtin_ia32_psllqi", &&IX86_BUILTIN_PSLLQI}, + //{"__builtin_ia32_psllqi128", &&IX86_BUILTIN_PSLLQI128}, + //{"__builtin_ia32_psllw", &&IX86_BUILTIN_PSLLW}, + //{"__builtin_ia32_psllw128", &&IX86_BUILTIN_PSLLW128}, + //{"__builtin_ia32_psllwi", &&IX86_BUILTIN_PSLLWI}, + //{"__builtin_ia32_psllwi128", &&IX86_BUILTIN_PSLLWI128}, + //{"__builtin_ia32_ps_ps256", &&IX86_BUILTIN_PS_PS256}, + //{"__builtin_ia32_psrad", &&IX86_BUILTIN_PSRAD}, + //{"__builtin_ia32_psrad128", &&IX86_BUILTIN_PSRAD128}, + //{"__builtin_ia32_psradi", &&IX86_BUILTIN_PSRADI}, + //{"__builtin_ia32_psradi128", &&IX86_BUILTIN_PSRADI128}, + //{"__builtin_ia32_psraw", &&IX86_BUILTIN_PSRAW}, + //{"__builtin_ia32_psraw128", &&IX86_BUILTIN_PSRAW128}, + //{"__builtin_ia32_psrawi", &&IX86_BUILTIN_PSRAWI}, + //{"__builtin_ia32_psrawi128", &&IX86_BUILTIN_PSRAWI128}, + //{"__builtin_ia32_psrld", &&IX86_BUILTIN_PSRLD}, + //{"__builtin_ia32_psrld128", &&IX86_BUILTIN_PSRLD128}, + //{"__builtin_ia32_psrldi", &&IX86_BUILTIN_PSRLDI}, + //{"__builtin_ia32_psrldi128", &&IX86_BUILTIN_PSRLDI128}, + //{"__builtin_ia32_psrldqi128", &&IX86_BUILTIN_PSRLDQI128}, + //{"__builtin_ia32_psrlq", &&IX86_BUILTIN_PSRLQ}, + //{"__builtin_ia32_psrlq128", &&IX86_BUILTIN_PSRLQ128}, + //{"__builtin_ia32_psrlqi", &&IX86_BUILTIN_PSRLQI}, + //{"__builtin_ia32_psrlqi128", &&IX86_BUILTIN_PSRLQI128}, + //{"__builtin_ia32_psrlw", &&IX86_BUILTIN_PSRLW}, + //{"__builtin_ia32_psrlw128", &&IX86_BUILTIN_PSRLW128}, + //{"__builtin_ia32_psrlwi", &&IX86_BUILTIN_PSRLWI}, + //{"__builtin_ia32_psrlwi128", &&IX86_BUILTIN_PSRLWI128}, {"__builtin_ia32_psubb", &&IX86_BUILTIN_PSUBB}, {"__builtin_ia32_psubb128", &&IX86_BUILTIN_PSUBB128}, {"__builtin_ia32_psubd", &&IX86_BUILTIN_PSUBD}, {"__builtin_ia32_psubd128", &&IX86_BUILTIN_PSUBD128}, {"__builtin_ia32_psubq", &&IX86_BUILTIN_PSUBQ}, {"__builtin_ia32_psubq128", &&IX86_BUILTIN_PSUBQ128}, + //{"__builtin_ia32_psubsb", &&IX86_BUILTIN_PSUBSB}, + //{"__builtin_ia32_psubsb128", &&IX86_BUILTIN_PSUBSB128}, + //{"__builtin_ia32_psubsw", &&IX86_BUILTIN_PSUBSW}, + //{"__builtin_ia32_psubsw128", &&IX86_BUILTIN_PSUBSW128}, + //{"__builtin_ia32_psubusb", &&IX86_BUILTIN_PSUBUSB}, + //{"__builtin_ia32_psubusb128", &&IX86_BUILTIN_PSUBUSB128}, + //{"__builtin_ia32_psubusw", &&IX86_BUILTIN_PSUBUSW}, + //{"__builtin_ia32_psubusw128", &&IX86_BUILTIN_PSUBUSW128}, {"__builtin_ia32_psubw", &&IX86_BUILTIN_PSUBW}, {"__builtin_ia32_psubw128", &&IX86_BUILTIN_PSUBW128}, + //{"__builtin_ia32_pswapdsf", &&IX86_BUILTIN_PSWAPDSF}, + //{"__builtin_ia32_pswapdsi", &&IX86_BUILTIN_PSWAPDSI}, + //{"__builtin_ia32_ptestc128", &&IX86_BUILTIN_PTESTC}, + //{"__builtin_ia32_ptestc256", &&IX86_BUILTIN_PTESTC256}, + //{"__builtin_ia32_ptestnzc128", &&IX86_BUILTIN_PTESTNZC}, + //{"__builtin_ia32_ptestnzc256", &&IX86_BUILTIN_PTESTNZC256}, + //{"__builtin_ia32_ptestz128", &&IX86_BUILTIN_PTESTZ}, + //{"__builtin_ia32_ptestz256", &&IX86_BUILTIN_PTESTZ256}, {"__builtin_ia32_punpckhbw", &&IX86_BUILTIN_PUNPCKHBW}, {"__builtin_ia32_punpckhbw128", &&IX86_BUILTIN_PUNPCKHBW128}, {"__builtin_ia32_punpckhdq", &&IX86_BUILTIN_PUNPCKHDQ}, @@ -211,31 +566,83 @@ {"__builtin_ia32_punpcklwd128", &&IX86_BUILTIN_PUNPCKLWD128}, {"__builtin_ia32_pxor", &&IX86_BUILTIN_PXOR}, {"__builtin_ia32_pxor128", &&IX86_BUILTIN_PXOR128}, + //{"__builtin_ia32_rcpps", &&IX86_BUILTIN_RCPPS}, + //{"__builtin_ia32_rcpps256", &&IX86_BUILTIN_RCPPS256}, + //{"__builtin_ia32_rcpss", &&IX86_BUILTIN_RCPSS}, + //{"__builtin_ia32_rdpmc", &&IX86_BUILTIN_RDPMC}, + //{"__builtin_ia32_rdtsc", &&IX86_BUILTIN_RDTSC}, + //{"__builtin_ia32_rdtscp", &&IX86_BUILTIN_RDTSCP}, + //{"__builtin_ia32_rolhi", &&IX86_BUILTIN_ROLHI}, + //{"__builtin_ia32_rolqi", &&IX86_BUILTIN_ROLQI}, + //{"__builtin_ia32_rorhi", &&IX86_BUILTIN_RORHI}, + //{"__builtin_ia32_rorqi", &&IX86_BUILTIN_RORQI}, + //{"__builtin_ia32_roundpd", &&IX86_BUILTIN_ROUNDPD}, + //{"__builtin_ia32_roundpd256", &&IX86_BUILTIN_ROUNDPD256}, + //{"__builtin_ia32_roundps", &&IX86_BUILTIN_ROUNDPS}, + //{"__builtin_ia32_roundps256", &&IX86_BUILTIN_ROUNDPS256}, + //{"__builtin_ia32_roundsd", &&IX86_BUILTIN_ROUNDSD}, + //{"__builtin_ia32_roundss", &&IX86_BUILTIN_ROUNDSS}, + //{"__builtin_ia32_rsqrtf", &&IX86_BUILTIN_RSQRTF}, + //{"__builtin_ia32_rsqrtps", &&IX86_BUILTIN_RSQRTPS}, + //{"__builtin_ia32_rsqrtps256", &&IX86_BUILTIN_RSQRTPS256}, + //{"__builtin_ia32_rsqrtps_nr", &&IX86_BUILTIN_RSQRTPS_NR}, + //{"__builtin_ia32_rsqrtps_nr256", &&IX86_BUILTIN_RSQRTPS_NR256}, + //{"__builtin_ia32_rsqrtss", &&IX86_BUILTIN_RSQRTSS}, + //{"__builtin_ia32_sfence", &&IX86_BUILTIN_SFENCE}, {"__builtin_ia32_shufpd", &&IX86_BUILTIN_SHUFPD}, - {"__builtin_ia32_shufpd256", &&IX86_BUILTIN_SHUFPD}, + //{"__builtin_ia32_shufpd256", &&IX86_BUILTIN_SHUFPD256}, {"__builtin_ia32_shufps", &&IX86_BUILTIN_SHUFPS}, - {"__builtin_ia32_shufps256", &&IX86_BUILTIN_SHUFPS}, + //{"__builtin_ia32_shufps256", &&IX86_BUILTIN_SHUFPS256}, + //{"__builtin_ia32_si256_si", &&IX86_BUILTIN_SI256_SI}, + //{"__builtin_ia32_si_si256", &&IX86_BUILTIN_SI_SI256}, + //{"__builtin_ia32_sqrtpd", &&IX86_BUILTIN_SQRTPD}, + //{"__builtin_ia32_sqrtpd256", &&IX86_BUILTIN_SQRTPD256}, + //{"__builtin_ia32_sqrtps", &&IX86_BUILTIN_SQRTPS}, + //{"__builtin_ia32_sqrtps256", &&IX86_BUILTIN_SQRTPS256}, + //{"__builtin_ia32_sqrtps_nr", &&IX86_BUILTIN_SQRTPS_NR}, + //{"__builtin_ia32_sqrtps_nr256", &&IX86_BUILTIN_SQRTPS_NR256}, + //{"__builtin_ia32_sqrtsd", &&IX86_BUILTIN_SQRTSD}, + //{"__builtin_ia32_sqrtss", &&IX86_BUILTIN_SQRTSS}, {"__builtin_ia32_stmxcsr", &&IX86_BUILTIN_STMXCSR}, {"__builtin_ia32_storedqu", &&IX86_BUILTIN_STOREDQU}, - {"__builtin_ia32_storedqu256", &&IX86_BUILTIN_STOREDQU}, + //{"__builtin_ia32_storedqu256", &&IX86_BUILTIN_STOREDQU256}, {"__builtin_ia32_storehps", &&IX86_BUILTIN_STOREHPS}, {"__builtin_ia32_storelps", &&IX86_BUILTIN_STORELPS}, {"__builtin_ia32_storeupd", &&IX86_BUILTIN_STOREUPD}, - {"__builtin_ia32_storeupd256", &&IX86_BUILTIN_STOREUPD}, + //{"__builtin_ia32_storeupd256", &&IX86_BUILTIN_STOREUPD256}, {"__builtin_ia32_storeups", &&IX86_BUILTIN_STOREUPS}, - {"__builtin_ia32_storeups256", &&IX86_BUILTIN_STOREUPS}, + //{"__builtin_ia32_storeups256", &&IX86_BUILTIN_STOREUPS256}, {"__builtin_ia32_subpd", &&IX86_BUILTIN_SUBPD}, - {"__builtin_ia32_subpd256", &&IX86_BUILTIN_SUBPD}, + //{"__builtin_ia32_subpd256", &&IX86_BUILTIN_SUBPD256}, {"__builtin_ia32_subps", &&IX86_BUILTIN_SUBPS}, - {"__builtin_ia32_subps256", &&IX86_BUILTIN_SUBPS}, + //{"__builtin_ia32_subps256", &&IX86_BUILTIN_SUBPS256}, + //{"__builtin_ia32_subsd", &&IX86_BUILTIN_SUBSD}, + //{"__builtin_ia32_subss", &&IX86_BUILTIN_SUBSS}, + //{"__builtin_ia32_ucomieq", &&IX86_BUILTIN_UCOMIEQSS}, + //{"__builtin_ia32_ucomige", &&IX86_BUILTIN_UCOMIGESS}, + //{"__builtin_ia32_ucomigt", &&IX86_BUILTIN_UCOMIGTSS}, + //{"__builtin_ia32_ucomile", &&IX86_BUILTIN_UCOMILESS}, + //{"__builtin_ia32_ucomilt", &&IX86_BUILTIN_UCOMILTSS}, + //{"__builtin_ia32_ucomineq", &&IX86_BUILTIN_UCOMINEQSS}, + //{"__builtin_ia32_ucomisdeq", &&IX86_BUILTIN_UCOMIEQSD}, + //{"__builtin_ia32_ucomisdge", &&IX86_BUILTIN_UCOMIGESD}, + //{"__builtin_ia32_ucomisdgt", &&IX86_BUILTIN_UCOMIGTSD}, + //{"__builtin_ia32_ucomisdle", &&IX86_BUILTIN_UCOMILESD}, + //{"__builtin_ia32_ucomisdlt", &&IX86_BUILTIN_UCOMILTSD}, + //{"__builtin_ia32_ucomisdneq", &&IX86_BUILTIN_UCOMINEQSD}, {"__builtin_ia32_unpckhpd", &&IX86_BUILTIN_UNPCKHPD}, - {"__builtin_ia32_unpckhpd256", &&IX86_BUILTIN_UNPCKHPD}, + //{"__builtin_ia32_unpckhpd256", &&IX86_BUILTIN_UNPCKHPD256}, {"__builtin_ia32_unpckhps", &&IX86_BUILTIN_UNPCKHPS}, - {"__builtin_ia32_unpckhps256", &&IX86_BUILTIN_UNPCKHPS}, + //{"__builtin_ia32_unpckhps256", &&IX86_BUILTIN_UNPCKHPS256}, {"__builtin_ia32_unpcklpd", &&IX86_BUILTIN_UNPCKLPD}, - {"__builtin_ia32_unpcklpd256", &&IX86_BUILTIN_UNPCKLPD}, + //{"__builtin_ia32_unpcklpd256", &&IX86_BUILTIN_UNPCKLPD256}, {"__builtin_ia32_unpcklps", &&IX86_BUILTIN_UNPCKLPS}, - {"__builtin_ia32_unpcklps256", &&IX86_BUILTIN_UNPCKLPS}, + //{"__builtin_ia32_unpcklps256", &&IX86_BUILTIN_UNPCKLPS256}, + //{"__builtin_ia32_vbroadcastf128_pd256", &&IX86_BUILTIN_VBROADCASTPD256}, + //{"__builtin_ia32_vbroadcastf128_ps256", &&IX86_BUILTIN_VBROADCASTPS256}, + //{"__builtin_ia32_vbroadcastsd256", &&IX86_BUILTIN_VBROADCASTSD256}, + //{"__builtin_ia32_vbroadcastss", &&IX86_BUILTIN_VBROADCASTSS}, + //{"__builtin_ia32_vbroadcastss256", &&IX86_BUILTIN_VBROADCASTSS256}, {"__builtin_ia32_vec_ext_v16qi", &&IX86_BUILTIN_VEC_EXT_V16QI}, {"__builtin_ia32_vec_ext_v2df", &&IX86_BUILTIN_VEC_EXT_V2DF}, {"__builtin_ia32_vec_ext_v2di", &&IX86_BUILTIN_VEC_EXT_V2DI}, @@ -247,15 +654,79 @@ {"__builtin_ia32_vec_init_v2si", &&IX86_BUILTIN_VEC_INIT_V2SI}, {"__builtin_ia32_vec_init_v4hi", &&IX86_BUILTIN_VEC_INIT_V4HI}, {"__builtin_ia32_vec_init_v8qi", &&IX86_BUILTIN_VEC_INIT_V8QI}, + //{"__builtin_ia32_vec_pack_sfix", &&IX86_BUILTIN_VEC_PACK_SFIX}, {"__builtin_ia32_vec_set_v16qi", &&IX86_BUILTIN_VEC_SET_V16QI}, {"__builtin_ia32_vec_set_v2di", &&IX86_BUILTIN_VEC_SET_V2DI}, {"__builtin_ia32_vec_set_v4hi", &&IX86_BUILTIN_VEC_SET_V4HI}, + //{"__builtin_ia32_vec_set_v4sf", &&IX86_BUILTIN_VEC_SET_V4SF}, {"__builtin_ia32_vec_set_v4si", &&IX86_BUILTIN_VEC_SET_V4SI}, {"__builtin_ia32_vec_set_v8hi", &&IX86_BUILTIN_VEC_SET_V8HI}, + //{"__builtin_ia32_vextractf128_pd256", &&IX86_BUILTIN_EXTRACTF128PD256}, + //{"__builtin_ia32_vextractf128_ps256", &&IX86_BUILTIN_EXTRACTF128PS256}, + //{"__builtin_ia32_vextractf128_si256", &&IX86_BUILTIN_EXTRACTF128SI256}, + //{"__builtin_ia32_vfmaddpd", &&IX86_BUILTIN_VFMADDPD}, + //{"__builtin_ia32_vfmaddpd256", &&IX86_BUILTIN_VFMADDPD256}, + //{"__builtin_ia32_vfmaddps", &&IX86_BUILTIN_VFMADDPS}, + //{"__builtin_ia32_vfmaddps256", &&IX86_BUILTIN_VFMADDPS256}, + //{"__builtin_ia32_vfmaddsd", &&IX86_BUILTIN_VFMADDSD}, + //{"__builtin_ia32_vfmaddss", &&IX86_BUILTIN_VFMADDSS}, + //{"__builtin_ia32_vfmaddsubpd", &&IX86_BUILTIN_VFMADDSUBPD}, + //{"__builtin_ia32_vfmaddsubpd256", &&IX86_BUILTIN_VFMADDSUBPD256}, + //{"__builtin_ia32_vfmaddsubps", &&IX86_BUILTIN_VFMADDSUBPS}, + //{"__builtin_ia32_vfmaddsubps256", &&IX86_BUILTIN_VFMADDSUBPS256}, + //{"__builtin_ia32_vfmsubaddpd", &&IX86_BUILTIN_VFMSUBADDPD}, + //{"__builtin_ia32_vfmsubaddpd256", &&IX86_BUILTIN_VFMSUBADDPD256}, + //{"__builtin_ia32_vfmsubaddps", &&IX86_BUILTIN_VFMSUBADDPS}, + //{"__builtin_ia32_vfmsubaddps256", &&IX86_BUILTIN_VFMSUBADDPS256}, + //{"__builtin_ia32_vfmsubpd", &&IX86_BUILTIN_VFMSUBPD}, + //{"__builtin_ia32_vfmsubpd256", &&IX86_BUILTIN_VFMSUBPD256}, + //{"__builtin_ia32_vfmsubps", &&IX86_BUILTIN_VFMSUBPS}, + //{"__builtin_ia32_vfmsubps256", &&IX86_BUILTIN_VFMSUBPS256}, + //{"__builtin_ia32_vfmsubsd", &&IX86_BUILTIN_VFMSUBSD}, + //{"__builtin_ia32_vfmsubss", &&IX86_BUILTIN_VFMSUBSS}, + //{"__builtin_ia32_vfnmaddpd", &&IX86_BUILTIN_VFNMADDPD}, + //{"__builtin_ia32_vfnmaddpd256", &&IX86_BUILTIN_VFNMADDPD256}, + //{"__builtin_ia32_vfnmaddps", &&IX86_BUILTIN_VFNMADDPS}, + //{"__builtin_ia32_vfnmaddps256", &&IX86_BUILTIN_VFNMADDPS256}, + //{"__builtin_ia32_vfnmaddsd", &&IX86_BUILTIN_VFNMADDSD}, + //{"__builtin_ia32_vfnmaddss", &&IX86_BUILTIN_VFNMADDSS}, + //{"__builtin_ia32_vfnmsubpd", &&IX86_BUILTIN_VFNMSUBPD}, + //{"__builtin_ia32_vfnmsubpd256", &&IX86_BUILTIN_VFNMSUBPD256}, + //{"__builtin_ia32_vfnmsubps", &&IX86_BUILTIN_VFNMSUBPS}, + //{"__builtin_ia32_vfnmsubps256", &&IX86_BUILTIN_VFNMSUBPS256}, + //{"__builtin_ia32_vfnmsubsd", &&IX86_BUILTIN_VFNMSUBSD}, + //{"__builtin_ia32_vfnmsubss", &&IX86_BUILTIN_VFNMSUBSS}, + //{"__builtin_ia32_vinsertf128_pd256", &&IX86_BUILTIN_VINSERTF128PD256}, + //{"__builtin_ia32_vinsertf128_ps256", &&IX86_BUILTIN_VINSERTF128PS256}, + //{"__builtin_ia32_vinsertf128_si256", &&IX86_BUILTIN_VINSERTF128SI256}, + //{"__builtin_ia32_vperm2f128_pd256", &&IX86_BUILTIN_VPERM2F128PD256}, + //{"__builtin_ia32_vperm2f128_ps256", &&IX86_BUILTIN_VPERM2F128PS256}, + //{"__builtin_ia32_vperm2f128_si256", &&IX86_BUILTIN_VPERM2F128SI256}, + //{"__builtin_ia32_vpermilpd", &&IX86_BUILTIN_VPERMILPD}, + //{"__builtin_ia32_vpermilpd256", &&IX86_BUILTIN_VPERMILPD256}, + //{"__builtin_ia32_vpermilps", &&IX86_BUILTIN_VPERMILPS}, + //{"__builtin_ia32_vpermilps256", &&IX86_BUILTIN_VPERMILPS256}, + //{"__builtin_ia32_vpermilvarpd", &&IX86_BUILTIN_VPERMILVARPD}, + //{"__builtin_ia32_vpermilvarpd256", &&IX86_BUILTIN_VPERMILVARPD256}, + //{"__builtin_ia32_vpermilvarps", &&IX86_BUILTIN_VPERMILVARPS}, + //{"__builtin_ia32_vpermilvarps256", &&IX86_BUILTIN_VPERMILVARPS256}, + //{"__builtin_ia32_vtestcpd", &&IX86_BUILTIN_VTESTCPD}, + //{"__builtin_ia32_vtestcpd256", &&IX86_BUILTIN_VTESTCPD256}, + //{"__builtin_ia32_vtestcps", &&IX86_BUILTIN_VTESTCPS}, + //{"__builtin_ia32_vtestcps256", &&IX86_BUILTIN_VTESTCPS256}, + //{"__builtin_ia32_vtestnzcpd", &&IX86_BUILTIN_VTESTNZCPD}, + //{"__builtin_ia32_vtestnzcpd256", &&IX86_BUILTIN_VTESTNZCPD256}, + //{"__builtin_ia32_vtestnzcps", &&IX86_BUILTIN_VTESTNZCPS}, + //{"__builtin_ia32_vtestnzcps256", &&IX86_BUILTIN_VTESTNZCPS256}, + //{"__builtin_ia32_vtestzpd", &&IX86_BUILTIN_VTESTZPD}, + //{"__builtin_ia32_vtestzpd256", &&IX86_BUILTIN_VTESTZPD256}, + //{"__builtin_ia32_vtestzps", &&IX86_BUILTIN_VTESTZPS}, + //{"__builtin_ia32_vtestzps256", &&IX86_BUILTIN_VTESTZPS256}, + //{"__builtin_ia32_vzeroall", &&IX86_BUILTIN_VZEROALL}, {"__builtin_ia32_xorpd", &&IX86_BUILTIN_XORPD}, - {"__builtin_ia32_xorpd256", &&IX86_BUILTIN_XORPD}, + //{"__builtin_ia32_xorpd256", &&IX86_BUILTIN_XORPD256}, {"__builtin_ia32_xorps", &&IX86_BUILTIN_XORPS}, - {"__builtin_ia32_xorps256", &&IX86_BUILTIN_XORPS} + //{"__builtin_ia32_xorps256", &&IX86_BUILTIN_XORPS256}, }; static std::vector FunctionCodeCache; @@ -500,17 +971,17 @@ Result = BuildVectorShuffle(Result, Ops[0], 4, 5, 2, 3); return true; } - IX86_BUILTIN_LOADQ: { - const PointerType *i64Ptr = Type::getInt64PtrTy(Context); - Ops[0] = Builder.CreateBitCast(Ops[0], i64Ptr); - Ops[0] = Builder.CreateLoad(Ops[0]); - Value *Zero = ConstantInt::get(Type::getInt64Ty(Context), 0); - Result = BuildVector(Zero, Zero, NULL); - Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), 0); - Result = Builder.CreateInsertElement(Result, Ops[0], Idx); - Result = Builder.CreateBitCast(Result, ResultType); - return true; - } +//TODO IX86_BUILTIN_LOADQ: { +//TODO const PointerType *i64Ptr = Type::getInt64PtrTy(Context); +//TODO Ops[0] = Builder.CreateBitCast(Ops[0], i64Ptr); +//TODO Ops[0] = Builder.CreateLoad(Ops[0]); +//TODO Value *Zero = ConstantInt::get(Type::getInt64Ty(Context), 0); +//TODO Result = BuildVector(Zero, Zero, NULL); +//TODO Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), 0); +//TODO Result = Builder.CreateInsertElement(Result, Ops[0], Idx); +//TODO Result = Builder.CreateBitCast(Result, ResultType); +//TODO return true; +//TODO } IX86_BUILTIN_LOADUPS: { VectorType *v4f32 = VectorType::get(Type::getFloatTy(Context), 4); const PointerType *v4f32Ptr = v4f32->getPointerTo(); From grosbach at apple.com Mon Nov 2 10:47:33 2009 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 02 Nov 2009 16:47:33 -0000 Subject: [llvm-commits] [test-suite] r85804 - /test-suite/trunk/Makefile.programs Message-ID: <200911021647.nA2GlX7H009663@zion.cs.uiuc.edu> Author: grosbach Date: Mon Nov 2 10:47:33 2009 New Revision: 85804 URL: http://llvm.org/viewvc/llvm-project?rev=85804&view=rev Log: ARM LLCBETA does not use NEON for scalar floating point. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=85804&r1=85803&r2=85804&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Mon Nov 2 10:47:33 2009 @@ -244,12 +244,12 @@ LLCBETAOPTION := -enable-sparc-v9-insts endif ifeq ($(ARCH),ARM) -LLCBETAOPTION := -arm-dynamic-stack-alignment +LLCBETAOPTION := -arm-use-neon-fp=0 #-combiner-alias-analysis #-schedule-livein-copies endif ifeq ($(ARCH),THUMB) -LLCBETAOPTION := -arm-dynamic-stack-alignment +LLCBETAOPTION := -arm-use-neon-fp=0 #-combiner-alias-analysis #-enable-thumb-reg-scavenging endif From bob.wilson at apple.com Mon Nov 2 10:58:32 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 02 Nov 2009 16:58:32 -0000 Subject: [llvm-commits] [llvm] r85805 - /llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <200911021658.nA2GwWdK010062@zion.cs.uiuc.edu> Author: bwilson Date: Mon Nov 2 10:58:31 2009 New Revision: 85805 URL: http://llvm.org/viewvc/llvm-project?rev=85805&view=rev Log: Prune unnecessary include. Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=85805&r1=85804&r2=85805&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon Nov 2 10:58:31 2009 @@ -13,7 +13,6 @@ #include "ARM.h" #include "ARMAddressingModes.h" -#include "ARMConstantPoolValue.h" #include "ARMISelLowering.h" #include "ARMTargetMachine.h" #include "llvm/CallingConv.h" From bob.wilson at apple.com Mon Nov 2 10:59:06 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 02 Nov 2009 16:59:06 -0000 Subject: [llvm-commits] [llvm] r85806 - in /llvm/trunk/lib/Target/ARM: ARMCodeEmitter.cpp ARMConstantPoolValue.cpp ARMConstantPoolValue.h AsmPrinter/ARMAsmPrinter.cpp Message-ID: <200911021659.nA2Gx7nO010095@zion.cs.uiuc.edu> Author: bwilson Date: Mon Nov 2 10:59:06 2009 New Revision: 85806 URL: http://llvm.org/viewvc/llvm-project?rev=85806&view=rev Log: Add support for BlockAddress values in ARM constant pools. Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=85806&r1=85805&r2=85806&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Nov 2 10:59:06 2009 @@ -428,6 +428,7 @@ DEBUG(errs() << " ** ARM constant pool #" << CPI << " @ " << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n'); + assert(ACPV->isGlobalValue() && "unsupported constant pool value"); GlobalValue *GV = ACPV->getGV(); if (GV) { Reloc::Model RelocM = TM.getRelocationModel(); Modified: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp?rev=85806&r1=85805&r2=85806&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp Mon Nov 2 10:59:06 2009 @@ -13,19 +13,21 @@ #include "ARMConstantPoolValue.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/Constant.h" +#include "llvm/Constants.h" #include "llvm/GlobalValue.h" #include "llvm/Type.h" #include "llvm/Support/raw_ostream.h" #include using namespace llvm; -ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, unsigned id, +ARMConstantPoolValue::ARMConstantPoolValue(Constant *cval, unsigned id, ARMCP::ARMCPKind K, unsigned char PCAdj, const char *Modif, bool AddCA) - : MachineConstantPoolValue((const Type*)gv->getType()), - GV(gv), S(NULL), LabelId(id), Kind(K), PCAdjust(PCAdj), + : MachineConstantPoolValue((const Type*)cval->getType()), + CVal(cval), S(NULL), LabelId(id), Kind(K), PCAdjust(PCAdj), Modifier(Modif), AddCurrentAddress(AddCA) {} ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, @@ -34,14 +36,22 @@ const char *Modif, bool AddCA) : MachineConstantPoolValue((const Type*)Type::getInt32Ty(C)), - GV(NULL), S(strdup(s)), LabelId(id), Kind(ARMCP::CPValue), PCAdjust(PCAdj), - Modifier(Modif), AddCurrentAddress(AddCA) {} + CVal(NULL), S(strdup(s)), LabelId(id), Kind(ARMCP::CPExtSymbol), + PCAdjust(PCAdj), Modifier(Modif), AddCurrentAddress(AddCA) {} ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, const char *Modif) : MachineConstantPoolValue((const Type*)Type::getInt32Ty(gv->getContext())), - GV(gv), S(NULL), LabelId(0), Kind(ARMCP::CPValue), PCAdjust(0), + CVal(gv), S(NULL), LabelId(0), Kind(ARMCP::CPValue), PCAdjust(0), Modifier(Modif) {} +GlobalValue *ARMConstantPoolValue::getGV() const { + return dyn_cast_or_null(CVal); +} + +BlockAddress *ARMConstantPoolValue::getBlockAddress() const { + return dyn_cast_or_null(CVal); +} + int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) { unsigned AlignMask = Alignment - 1; @@ -51,7 +61,7 @@ (Constants[i].getAlignment() & AlignMask) == 0) { ARMConstantPoolValue *CPV = (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; - if (CPV->GV == GV && + if (CPV->CVal == CVal && CPV->S == S && CPV->LabelId == LabelId && CPV->PCAdjust == PCAdjust) @@ -68,7 +78,7 @@ void ARMConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) { - ID.AddPointer(GV); + ID.AddPointer(CVal); ID.AddPointer(S); ID.AddInteger(LabelId); ID.AddInteger(PCAdjust); @@ -80,8 +90,8 @@ void ARMConstantPoolValue::print(raw_ostream &O) const { - if (GV) - O << GV->getName(); + if (CVal) + O << CVal->getName(); else O << S; if (Modifier) O << "(" << Modifier << ")"; Modified: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h?rev=85806&r1=85805&r2=85806&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h Mon Nov 2 10:59:06 2009 @@ -18,31 +18,35 @@ namespace llvm { +class Constant; +class BlockAddress; class GlobalValue; class LLVMContext; namespace ARMCP { enum ARMCPKind { CPValue, + CPExtSymbol, + CPBlockAddress, CPLSDA }; } /// ARMConstantPoolValue - ARM specific constantpool value. This is used to /// represent PC relative displacement between the address of the load -/// instruction and the global value being loaded, i.e. (&GV-(LPIC+8)). +/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). class ARMConstantPoolValue : public MachineConstantPoolValue { - GlobalValue *GV; // GlobalValue being loaded. + Constant *CVal; // Constant being loaded. const char *S; // ExtSymbol being loaded. unsigned LabelId; // Label id of the load. - ARMCP::ARMCPKind Kind; // Value or LSDA? + ARMCP::ARMCPKind Kind; // Kind of constant. unsigned char PCAdjust; // Extra adjustment if constantpool is pc relative. // 8 for ARM, 4 for Thumb. const char *Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) bool AddCurrentAddress; public: - ARMConstantPoolValue(GlobalValue *gv, unsigned id, + ARMConstantPoolValue(Constant *cval, unsigned id, ARMCP::ARMCPKind Kind = ARMCP::CPValue, unsigned char PCAdj = 0, const char *Modifier = NULL, bool AddCurrentAddress = false); @@ -53,14 +57,17 @@ ARMConstantPoolValue(); ~ARMConstantPoolValue(); - - GlobalValue *getGV() const { return GV; } + GlobalValue *getGV() const; const char *getSymbol() const { return S; } + BlockAddress *getBlockAddress() const; const char *getModifier() const { return Modifier; } bool hasModifier() const { return Modifier != NULL; } bool mustAddCurrentAddress() const { return AddCurrentAddress; } unsigned getLabelId() const { return LabelId; } unsigned char getPCAdjustment() const { return PCAdjust; } + bool isGlobalValue() const { return Kind == ARMCP::CPValue; } + bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } + bool isBlockAddress() { return Kind == ARMCP::CPBlockAddress; } bool isLSDA() { return Kind == ARMCP::CPLSDA; } virtual unsigned getRelocationInfo() const { @@ -69,7 +76,6 @@ return 2; } - virtual int getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment); Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=85806&r1=85805&r2=85806&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Mon Nov 2 10:59:06 2009 @@ -159,7 +159,6 @@ printDataDirective(MCPV->getType()); ARMConstantPoolValue *ACPV = static_cast(MCPV); - GlobalValue *GV = ACPV->getGV(); std::string Name; if (ACPV->isLSDA()) { @@ -167,7 +166,10 @@ raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); Name = LSDAName.str(); - } else if (GV) { + } else if (ACPV->isBlockAddress()) { + Name = GetBlockAddressSymbol(ACPV->getBlockAddress())->getName(); + } else if (ACPV->isGlobalValue()) { + GlobalValue *GV = ACPV->getGV(); bool isIndirect = Subtarget->isTargetDarwin() && Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); if (!isIndirect) @@ -188,8 +190,10 @@ StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); } } - } else + } else { + assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); Name = Mang->makeNameProper(ACPV->getSymbol()); + } O << Name; if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; From grosbach at apple.com Mon Nov 2 10:59:18 2009 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 2 Nov 2009 08:59:18 -0800 Subject: [llvm-commits] [llvm] r85787 - in /llvm/trunk: lib/Target/ARM/ARMBaseInstrInfo.cpp test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll In-Reply-To: <200911020444.nA24iuOZ030845@zion.cs.uiuc.edu> References: <200911020444.nA24iuOZ030845@zion.cs.uiuc.edu> Message-ID: <63860812-1A15-4269-A0DE-2C6603627455@apple.com> Hi Evan, Looks good. Trivial comment tweak below. -Jim On Nov 1, 2009, at 8:44 PM, Evan Cheng wrote: > Author: evancheng > Date: Sun Nov 1 22:44:55 2009 > New Revision: 85787 > > URL: http://llvm.org/viewvc/llvm-project?rev=85787&view=rev > Log: > Unbreak ARMBaseRegisterInfo::copyRegToReg. > > Added: > llvm/trunk/test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll > Modified: > llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=85787&r1=85786&r2=85787&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Sun Nov 1 > 22:44:55 2009 > @@ -660,26 +660,27 @@ > } else if (DestRC == ARM::DPRRegisterClass) { > const ARMBaseRegisterInfo* TRI = &getRegisterInfo(); > > + // If we do not found an instruction defining the reg, this > means the s/found/find > + // register should be live-in for this BB. It's always to > better to use > + // NEON reg-reg moves. > + unsigned Domain = ARMII::DomainNEON; > + > // Find the Machine Instruction which defines SrcReg. > - MachineBasicBlock::iterator J = (I == MBB.begin() ? I : prior > (I)); > - while (J != MBB.begin()) { > - if (J->modifiesRegister(SrcReg, TRI)) > - break; > - --J; > - } > + if (!MBB.empty()) { > + MachineBasicBlock::iterator J = (I == MBB.begin() ? I : prior > (I)); > + while (J != MBB.begin()) { > + if (J->modifiesRegister(SrcReg, TRI)) > + break; > + --J; > + } > > - unsigned Domain; > - if (J->modifiesRegister(SrcReg, TRI)) { > - Domain = J->getDesc().TSFlags & ARMII::DomainMask; > - // Instructions in general domain are subreg accesses. > - // Map them to NEON reg-reg moves. > - if (Domain == ARMII::DomainGeneral) > - Domain = ARMII::DomainNEON; > - } else { > - // We reached the beginning of the BB and found no > instruction defining > - // the reg. This means that register should be live-in for > this BB. > - // It's always to better to use NEON reg-reg moves. > - Domain = ARMII::DomainNEON; > + if (J->modifiesRegister(SrcReg, TRI)) { > + Domain = J->getDesc().TSFlags & ARMII::DomainMask; > + // Instructions in general domain are subreg accesses. > + // Map them to NEON reg-reg moves. > + if (Domain == ARMII::DomainGeneral) > + Domain = ARMII::DomainNEON; > + } > } > > if ((Domain & ARMII::DomainNEON) && getSubtarget().hasNEON()) { > > Added: llvm/trunk/test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll?rev=85787&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll > (added) > +++ llvm/trunk/test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll Sun > Nov 1 22:44:55 2009 > @@ -0,0 +1,29 @@ > +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -relocation-model=pic > -disable-fp-elim -mcpu=cortex-a8 > + > +define arm_apcscc void @get_initial_mb16x16_cost() nounwind { > +entry: > + br i1 undef, label %bb4, label %bb1 > + > +bb1: ; preds = %entry > + br label %bb7 > + > +bb4: ; preds = %entry > + br i1 undef, label %bb7.thread, label %bb5 > + > +bb5: ; preds = %bb4 > + br label %bb7 > + > +bb7.thread: ; preds = %bb4 > + br label %bb8 > + > +bb7: ; preds = %bb5, > %bb1 > + br i1 undef, label %bb8, label %bb10 > + > +bb8: ; preds = %bb7, > %bb7.thread > + %0 = phi double [ 5.120000e+02, %bb7.thread ], [ undef, %bb7 ] ; > [#uses=1] > + %1 = fdiv double %0, undef ; > [#uses=0] > + unreachable > + > +bb10: ; preds = %bb7 > + ret void > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From david_goodwin at apple.com Mon Nov 2 11:06:28 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 02 Nov 2009 17:06:28 -0000 Subject: [llvm-commits] [llvm] r85807 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200911021706.nA2H6SZm010309@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Nov 2 11:06:28 2009 New Revision: 85807 URL: http://llvm.org/viewvc/llvm-project?rev=85807&view=rev Log: Chain dependencies used to enforce memory order should have latency of 0 (except for true dependency of Store followed by aliased Load... we estimate that case with a single cycle of latency assuming the hardware will bypass) Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=85807&r1=85806&r2=85807&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Mon Nov 2 11:06:28 2009 @@ -317,29 +317,35 @@ } // Add chain dependencies. + // Chain dependencies used to enforce memory order should have + // latency of 0 (except for true dependency of Store followed by + // aliased Load... we estimate that with a single cycle of latency + // assuming the hardware will bypass) // Note that isStoreToStackSlot and isLoadFromStackSLot are not usable // after stack slots are lowered to actual addresses. // TODO: Use an AliasAnalysis and do real alias-analysis queries, and // produce more precise dependence information. +#define STORE_LOAD_LATENCY 1 + unsigned TrueMemOrderLatency = 0; if (TID.isCall() || TID.hasUnmodeledSideEffects()) { new_chain: // This is the conservative case. Add dependencies on all memory // references. if (Chain) - Chain->addPred(SDep(SU, SDep::Order, SU->Latency)); + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); Chain = SU; for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) - PendingLoads[k]->addPred(SDep(SU, SDep::Order, SU->Latency)); + PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); PendingLoads.clear(); for (std::map::iterator I = MemDefs.begin(), E = MemDefs.end(); I != E; ++I) { - I->second->addPred(SDep(SU, SDep::Order, SU->Latency)); + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); I->second = SU; } for (std::map >::iterator I = MemUses.begin(), E = MemUses.end(); I != E; ++I) { for (unsigned i = 0, e = I->second.size(); i != e; ++i) - I->second[i]->addPred(SDep(SU, SDep::Order, SU->Latency)); + I->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); I->second.clear(); } // See if it is known to just have a single memory reference. @@ -356,12 +362,13 @@ // Unknown memory accesses. Assume the worst. ChainMMO = 0; } else if (TID.mayStore()) { + TrueMemOrderLatency = STORE_LOAD_LATENCY; if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) { // A store to a specific PseudoSourceValue. Add precise dependencies. // Handle the def in MemDefs, if there is one. std::map::iterator I = MemDefs.find(V); if (I != MemDefs.end()) { - I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0, + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0, /*isNormalMemory=*/true)); I->second = SU; } else { @@ -372,35 +379,37 @@ MemUses.find(V); if (J != MemUses.end()) { for (unsigned i = 0, e = J->second.size(); i != e; ++i) - J->second[i]->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0, - /*isNormalMemory=*/true)); + J->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency, + /*Reg=*/0, /*isNormalMemory=*/true)); J->second.clear(); } // Add dependencies from all the PendingLoads, since without // memoperands we must assume they alias anything. for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) - PendingLoads[k]->addPred(SDep(SU, SDep::Order, SU->Latency)); + PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); // Add a general dependence too, if needed. if (Chain) - Chain->addPred(SDep(SU, SDep::Order, SU->Latency)); - } else + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + } else { // Treat all other stores conservatively. goto new_chain; + } } else if (TID.mayLoad()) { + TrueMemOrderLatency = 0; if (MI->isInvariantLoad(AA)) { // Invariant load, no chain dependencies needed! } else if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) { // A load from a specific PseudoSourceValue. Add precise dependencies. std::map::iterator I = MemDefs.find(V); if (I != MemDefs.end()) - I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0, + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0, /*isNormalMemory=*/true)); MemUses[V].push_back(SU); // Add a general dependence too, if needed. if (Chain && (!ChainMMO || (ChainMMO->isStore() || ChainMMO->isVolatile()))) - Chain->addPred(SDep(SU, SDep::Order, SU->Latency)); + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); } else if (MI->hasVolatileMemoryRef()) { // Treat volatile loads conservatively. Note that this includes // cases where memoperand information is unavailable. @@ -411,10 +420,10 @@ // we can't even assume that the load doesn't alias well-behaved // memory locations. if (Chain) - Chain->addPred(SDep(SU, SDep::Order, SU->Latency)); + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); for (std::map::iterator I = MemDefs.begin(), E = MemDefs.end(); I != E; ++I) - I->second->addPred(SDep(SU, SDep::Order, SU->Latency)); + I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); PendingLoads.push_back(SU); } } From bob.wilson at apple.com Mon Nov 2 11:10:38 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 02 Nov 2009 17:10:38 -0000 Subject: [llvm-commits] [llvm] r85808 - /llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h Message-ID: <200911021710.nA2HAc12010447@zion.cs.uiuc.edu> Author: bwilson Date: Mon Nov 2 11:10:37 2009 New Revision: 85808 URL: http://llvm.org/viewvc/llvm-project?rev=85808&view=rev Log: Hyphenate some comments. Modified: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h Modified: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h?rev=85808&r1=85807&r2=85808&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h Mon Nov 2 11:10:37 2009 @@ -33,14 +33,14 @@ } /// ARMConstantPoolValue - ARM specific constantpool value. This is used to -/// represent PC relative displacement between the address of the load +/// represent PC-relative displacement between the address of the load /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). class ARMConstantPoolValue : public MachineConstantPoolValue { Constant *CVal; // Constant being loaded. const char *S; // ExtSymbol being loaded. unsigned LabelId; // Label id of the load. ARMCP::ARMCPKind Kind; // Kind of constant. - unsigned char PCAdjust; // Extra adjustment if constantpool is pc relative. + unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. // 8 for ARM, 4 for Thumb. const char *Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) bool AddCurrentAddress; @@ -86,7 +86,6 @@ void dump() const; }; - inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { V.print(O); return O; From david_goodwin at apple.com Mon Nov 2 11:26:25 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 2 Nov 2009 09:26:25 -0800 Subject: [llvm-commits] [llvm] r85697 - in /llvm/trunk: lib/Target/ARM/ARMInstrNEON.td test/CodeGen/ARM/fmacs.ll test/CodeGen/ARM/fnmacs.ll test/CodeGen/Thumb2/cross-rc-coalescing-2.ll In-Reply-To: References: <200910312257.n9VMvbZm030355@zion.cs.uiuc.edu> Message-ID: The itineraries are much more expressive now. They can model arbitrary resource usage as well as operand use and def stages (see ARMScheduleV7.td... don't get me started on the cortex-a8 microarchitecture ;-). I've been comparing our cortex-a8 scheduling against shark and so far it is quite accurate. There is also a generic callback into the subtarget to let it adjust latency for cases that don't fit the model... though I haven't used that yet. I assume this is an important case that is not being handled correctly. Is there an example? David On Nov 1, 2009, at 10:31 AM, Evan Cheng wrote: > > On Nov 1, 2009, at 10:22 AM, Anton Korobeynikov wrote: > >> Hello, Evan >> >>> On the other hand, a vmla.32 followed by another vmla.32 is just >>> fine. And >>> it is faster than vmul + vadd. I agree we should try to solve it >>> better. >>> Perhaps expanding it before or during schedule2. >> Right, NEON scheduling is tricky, it seems that our instruction >> itineraries are not expressible enough for such complex pipelines. > > I think we should be able to handle at least the true dependency > cases. Instruction latency is a function of both defining > instruction and the use. cc'ing David for his comments. > > Evan > >> >> -- >> With best regards, Anton Korobeynikov >> Faculty of Mathematics and Mechanics, Saint Petersburg State >> University > From david_goodwin at apple.com Mon Nov 2 11:28:36 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 02 Nov 2009 17:28:36 -0000 Subject: [llvm-commits] [llvm] r85809 - in /llvm/trunk/lib/Target/ARM: ARMInstrInfo.td ARMInstrThumb2.td Message-ID: <200911021728.nA2HSa6Q011387@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Nov 2 11:28:36 2009 New Revision: 85809 URL: http://llvm.org/viewvc/llvm-project?rev=85809&view=rev Log: Fix schedule model for BFC. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85809&r1=85808&r2=85809&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Nov 2 11:28:36 2009 @@ -1205,7 +1205,7 @@ BinOpFrag<(and node:$LHS, (not node:$RHS))>>; def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), - AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi, + AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, "bfc", "\t$dst, $imm", "$src = $dst", [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>, Requires<[IsARM, HasV6T2]> { Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=85809&r1=85808&r2=85809&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Nov 2 11:28:36 2009 @@ -787,7 +787,7 @@ let Constraints = "$src = $dst" in def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), - IIC_iALUi, "bfc", "\t$dst, $imm", + IIC_iUNAsi, "bfc", "\t$dst, $imm", [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>; def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), From sabre at nondot.org Mon Nov 2 12:22:51 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 18:22:51 -0000 Subject: [llvm-commits] [llvm] r85810 - in /llvm/trunk: lib/Transforms/Scalar/SCCP.cpp test/Transforms/SCCP/2008-03-10-sret.ll test/Transforms/SCCP/ipsccp-basic.ll Message-ID: <200911021822.nA2IMp41013382@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 12:22:51 2009 New Revision: 85810 URL: http://llvm.org/viewvc/llvm-project?rev=85810&view=rev Log: disable IPSCCP support for multiple return values, it is buggy, so just disable it until I can fix it. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85810&r1=85809&r2=85810&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 12:22:51 2009 @@ -1650,7 +1650,8 @@ // If this is a strong or ODR definition of this function, then we can // propagate information about its result into callsites of it. - if (!F->mayBeOverridden()) + if (!F->mayBeOverridden() && + !isa(F->getReturnType())) Solver.AddTrackedFunction(F); // If this function only has direct calls that we can see, we can track its Modified: llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll?rev=85810&r1=85809&r2=85810&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll (original) +++ llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll Mon Nov 2 12:22:51 2009 @@ -4,6 +4,8 @@ ; RUN: grep {%mrv1 = insertvalue %T %mrv, i32 17, 1} %t ; RUN: grep {ret %T %mrv1} %t +; XFAIL: * + %T = type {i32,i32} define internal {i32, i32} @bar(i32 %A) { Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll?rev=85810&r1=85809&r2=85810&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll (original) +++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Mon Nov 2 12:22:51 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -ipsccp -S | FileCheck %s +; XFAIL: * ;;======================== test1 From baldrick at free.fr Mon Nov 2 12:22:47 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 02 Nov 2009 19:22:47 +0100 Subject: [llvm-commits] [llvm] r85368 - in /llvm/trunk/lib/AsmParser: LLLexer.cpp LLParser.cpp LLParser.h LLToken.h In-Reply-To: <200910280339.n9S3dOUJ029862@zion.cs.uiuc.edu> References: <200910280339.n9S3dOUJ029862@zion.cs.uiuc.edu> Message-ID: <4AEF2377.3090103@free.fr> Hi Chris, > + "cannot take address of numeric label after it the function is defined"); after it the -> after the Ciao, Duncan. From sabre at nondot.org Mon Nov 2 12:27:22 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 18:27:22 -0000 Subject: [llvm-commits] [llvm] r85811 - in /llvm/trunk/test/Transforms/SCCP: 2008-03-10-sret.ll ipsccp-basic.ll Message-ID: <200911021827.nA2IRMUT013610@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 12:27:22 2009 New Revision: 85811 URL: http://llvm.org/viewvc/llvm-project?rev=85811&view=rev Log: merge 2008-03-10-sret.ll into ipsccp-basic.ll, and upgrade its syntax. Removed: llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Removed: llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll?rev=85810&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll (original) +++ llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll (removed) @@ -1,21 +0,0 @@ -; RUN: opt < %s -ipsccp -S > %t -; RUN: grep {ret i32 36} %t -; RUN: grep {%mrv = insertvalue %T undef, i32 18, 0} %t -; RUN: grep {%mrv1 = insertvalue %T %mrv, i32 17, 1} %t -; RUN: grep {ret %T %mrv1} %t - -; XFAIL: * - -%T = type {i32,i32} - -define internal {i32, i32} @bar(i32 %A) { - %X = add i32 1, %A - ret i32 %X, i32 %A -} - -define i32 @foo() { - %X = call {i32, i32} @bar(i32 17) - %Y = getresult {i32, i32} %X, 0 - %Z = add i32 %Y, %Y - ret i32 %Z -} Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll?rev=85811&r1=85810&r2=85811&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll (original) +++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Mon Nov 2 12:27:22 2009 @@ -149,3 +149,29 @@ ; CHECK: define i64 @test6b ; CHECK: ret i64 0 +;;======================== test7 + + +%T = type {i32,i32} + +define internal {i32, i32} @test7a(i32 %A) { + %X = add i32 1, %A + %mrv0 = insertvalue %T undef, i32 %X, 0 + %mrv1 = insertvalue %T %mrv0, i32 %A, 1 + ret %T %mrv1 +; CHECK: @test7a +; CHECK-NEXT: %mrv0 = insertvalue %T undef, i32 18, 0 +; CHECK-NEXT: %mrv1 = insertvalue %T %mrv0, i32 17, 1 +} + +define i32 @test7b() { + %X = call {i32, i32} @test7a(i32 17) + %Y = extractvalue {i32, i32} %X, 0 + %Z = add i32 %Y, %Y + ret i32 %Z +; CHECK: define i32 @test7b +; CHECK-NEXT: call %T @test7a(i32 17) +; CHECK-NEXT: ret i32 36 +} + + From sabre at nondot.org Mon Nov 2 12:28:46 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 18:28:46 -0000 Subject: [llvm-commits] [llvm] r85812 - /llvm/trunk/lib/AsmParser/LLParser.cpp Message-ID: <200911021828.nA2ISkIV013702@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 12:28:45 2009 New Revision: 85812 URL: http://llvm.org/viewvc/llvm-project?rev=85812&view=rev Log: typo Modified: llvm/trunk/lib/AsmParser/LLParser.cpp Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=85812&r1=85811&r2=85812&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Nov 2 12:28:45 2009 @@ -130,7 +130,7 @@ Res = PFS->GetBB(Refs[i].first.UIntVal, Refs[i].first.Loc); } else if (Refs[i].first.Kind == ValID::t_LocalID) { return Error(Refs[i].first.Loc, - "cannot take address of numeric label after it the function is defined"); + "cannot take address of numeric label after the function is defined"); } else { Res = dyn_cast_or_null( TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal)); From mrs at apple.com Mon Nov 2 12:39:12 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 2 Nov 2009 10:39:12 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r85649 - /llvm-gcc-4.2/trunk/gcc/cp/decl.c In-Reply-To: <4AEDF65C.9000308@mxc.ca> References: <200910310927.n9V9R6bi001921@zion.cs.uiuc.edu> <4AED5991.4050202@free.fr> <4AEDF65C.9000308@mxc.ca> Message-ID: On Nov 1, 2009, at 12:58 PM, Nick Lewycky wrote: > The other thing is that not all GCC thunks can be lowered to LLVM > aliases. See PR2861 for the case that hit me. I'm waiting to see what > happens when clang needs to codegen the same thing :) I think I'll be starting in on thunk codegen for clang next... I don't see how aliases could be used; thunks require extra code, and I didn't see any provision for extra code for aliases. From vhernandez at apple.com Mon Nov 2 12:51:29 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Mon, 02 Nov 2009 18:51:29 -0000 Subject: [llvm-commits] [llvm] r85814 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Message-ID: <200911021851.nA2IpTYX014735@zion.cs.uiuc.edu> Author: hernande Date: Mon Nov 2 12:51:28 2009 New Revision: 85814 URL: http://llvm.org/viewvc/llvm-project?rev=85814&view=rev Log: Set bit instead of calling pow() to compute 2 << n Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=85814&r1=85813&r2=85814&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Mon Nov 2 12:51:28 2009 @@ -16,6 +16,7 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Module.h" +#include "llvm/ADT/APInt.h" #include "llvm/Analysis/ConstantFolding.h" using namespace llvm; @@ -156,15 +157,22 @@ return Op1; } if (Opcode == Instruction::Shl) { - ConstantInt* Op1Int = dyn_cast(Op1); - if (!Op1Int) return NULL; - Value* Op1Pow = ConstantInt::get(Op1->getType(), (uint64_t) - pow(2.0, (double) Op1Int->getZExtValue())); + ConstantInt* Op1CI = dyn_cast(Op1); + if (!Op1CI) return NULL; + + APInt Op1Int = Op1CI->getValue(); + unsigned Op1Width = Op1Int.getBitWidth(); + // check for overflow + if (Op1Int.getActiveBits() > 64 || Op1Int.getZExtValue() > Op1Width) + return NULL; + Value* Op1Pow = ConstantInt::get(Context, + APInt(Op1Width, 0).set(Op1Int.getZExtValue())); + if (Op0 == ElementSize || (FoldedElementSize && Op0 == FoldedElementSize)) // ArraySize << log2(ElementSize) return Op1Pow; if (Op1Pow == ElementSize || - (FoldedElementSize && Op1Pow == FoldedElementSize)) + (FoldedElementSize && Op1Pow == FoldedElementSize)) // ElementSize << log2(ArraySize) return Op0; } From vhernandez at apple.com Mon Nov 2 12:52:12 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Mon, 2 Nov 2009 10:52:12 -0800 Subject: [llvm-commits] [llvm] r85478 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp In-Reply-To: <4AEA9CC9.3080305@free.fr> References: <200910290343.n9T3hBGO002753@zion.cs.uiuc.edu> <4AE951BB.2000105@free.fr> <4AEA9CC9.3080305@free.fr> Message-ID: <4ECCC52D-2654-4F03-81B5-075C727ABA9F@apple.com> Duncan, Thanks for the feedback. I just committed the pow removal. Victor On Oct 30, 2009, at 12:59 AM, Duncan Sands wrote: > Hi Victor, > >> + unsigned Op1BitWidth = Op1->getType()->getPrimitiveSizeInBits >> (); > > you could also get the constant int as an APInt and use the > getBitWidth > method. > >> + // check for overflow >> + if (Op1Int->getZExtValue() > Op1BitWidth) >> + return NULL; > > This will cause an assertion failure if Op1Int's value does not fit > in 64 bits. > >> + >> + Value* Op1Pow = ConstantInt::get(Context, >> + APInt(Op1BitWidth, 1, false) << Op1Int- >> >getValue()); > > The APInt class has a "set" method that allows you to set a > particular bit. I think that would be better. > > Ciao, > > Duncan. From ofv at wanadoo.es Mon Nov 2 13:11:03 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Mon, 02 Nov 2009 19:11:03 -0000 Subject: [llvm-commits] [llvm] r85817 - /llvm/trunk/cmake/modules/LLVMProcessSources.cmake Message-ID: <200911021911.nA2JB38U015629@zion.cs.uiuc.edu> Author: ofv Date: Mon Nov 2 13:11:03 2009 New Revision: 85817 URL: http://llvm.org/viewvc/llvm-project?rev=85817&view=rev Log: CMake: Report an error if there is an unknown .cpp file in a source directory. This is useful in case someone who works with the config&make build system forgot to add a file to its CMakeLists.txt. Instead of obtaining undefined references at link time, cmake will complain at configure time on the first build after a svn update. 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=85817&r1=85816&r2=85817&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMProcessSources.cmake (original) +++ llvm/trunk/cmake/modules/LLVMProcessSources.cmake Mon Nov 2 13:11:03 2009 @@ -22,6 +22,7 @@ function(llvm_process_sources OUT_VAR) set( sources ${ARGN} ) + llvm_check_source_file_list( ${sources} ) # Create file dependencies on the tablegenned files, if any. Seems # that this is not strictly needed, as dependencies of the .cpp # sources on the tablegenned .inc files are detected and handled, @@ -37,3 +38,17 @@ endif() set( ${OUT_VAR} ${sources} PARENT_SCOPE ) endfunction(llvm_process_sources) + + +function(llvm_check_source_file_list) + set(listed ${ARGN}) + file(GLOB globbed *.cpp) + foreach(g ${globbed}) + get_filename_component(fn ${g} NAME) + list(FIND listed ${fn} idx) + if( idx LESS 0 ) + message(SEND_ERROR "Found unknown source file ${g} +Please update ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt\n") + endif() + endforeach() +endfunction(llvm_check_source_file_list) From kennethuil at gmail.com Mon Nov 2 13:13:34 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Mon, 2 Nov 2009 13:13:34 -0600 Subject: [llvm-commits] [PATCH] Make opt default to not adding a target data string, and update tests Message-ID: <400d33ea0911021113h7385041fo34c1fafd3ca38b19@mail.gmail.com> All tests in the test directory that depend on target data now explicitly include the target data in the input assembly. This makes it safe for opt to not add target data whenever it's not supplied by either the module or the command line, which in turn stops opt from breaking valid code with bogus target data assumptions. -------------- next part -------------- A non-text attachment was scrubbed... Name: tests-opt.patch Type: application/octet-stream Size: 36041 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091102/82f5ceec/attachment.obj From sabre at nondot.org Mon Nov 2 13:31:11 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 19:31:11 -0000 Subject: [llvm-commits] [llvm] r85818 - in /llvm/trunk: include/llvm/Support/StandardPasses.h lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911021931.nA2JVB3a016469@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 13:31:10 2009 New Revision: 85818 URL: http://llvm.org/viewvc/llvm-project?rev=85818&view=rev Log: revert r8579[56], which are causing unhappiness in buildbot land. Modified: llvm/trunk/include/llvm/Support/StandardPasses.h llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=85818&r1=85817&r2=85818&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Nov 2 13:31:10 2009 @@ -99,6 +99,7 @@ if (UnitAtATime) { PM->add(createGlobalOptimizerPass()); // Optimize out global vars + PM->add(createIPConstantPropagationPass()); // IP CP PM->add(createIPSCCPPass()); // IP SCCP PM->add(createDeadArgEliminationPass()); // Dead argument elimination } Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85818&r1=85817&r2=85818&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 13:31:10 2009 @@ -25,6 +25,7 @@ #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Target/TargetData.h" @@ -226,6 +227,7 @@ /// and out of the specified function (which cannot have its address taken), /// this method must be called. void AddTrackedFunction(Function *F) { + assert(F->hasLocalLinkage() && "Can only track internal functions!"); // Add an entry, F -> undef. if (const StructType *STy = dyn_cast(F->getReturnType())) { for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) @@ -378,9 +380,11 @@ // instruction that was just changed state somehow. Based on this // information, we need to update the specified user of this instruction. // - void OperandChangedState(Instruction *I) { - if (BBExecutable.count(I->getParent())) // Inst is executable? - visit(*I); + void OperandChangedState(User *U) { + // Only instructions use other variable values! + Instruction &I = cast(*U); + if (BBExecutable.count(I.getParent())) // Inst is executable? + visit(I); } /// RemoveFromOverdefinedPHIs - If I has any entries in the @@ -424,6 +428,8 @@ void visitLoadInst (LoadInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); void visitCallInst (CallInst &I) { + if (isFreeCall(&I)) + return; visitCallSite(CallSite::get(&I)); } void visitInvokeInst (InvokeInst &II) { @@ -650,19 +656,19 @@ markConstant(&PN, OperandVal); // Acquire operand value } - - - void SCCPSolver::visitReturnInst(ReturnInst &I) { if (I.getNumOperands() == 0) return; // ret void Function *F = I.getParent()->getParent(); - // If we are tracking the return value of this function, merge it in. + if (!F->hasLocalLinkage()) + return; + if (!TrackedRetVals.empty()) { DenseMap::iterator TFRVI = TrackedRetVals.find(F); - if (TFRVI != TrackedRetVals.end()) { + if (TFRVI != TrackedRetVals.end() && + !TFRVI->second.isOverdefined()) { mergeInValue(TFRVI->second, F, getValueState(I.getOperand(0))); return; } @@ -1158,14 +1164,14 @@ // The common case is that we aren't tracking the callee, either because we // are not doing interprocedural analysis or the callee is indirect, or is // external. Handle these cases first. - if (F == 0 || F->isDeclaration()) { + if (F == 0 || !F->hasLocalLinkage()) { CallOverdefined: // Void return and not tracking callee, just bail. if (I->getType()->isVoidTy()) return; // Otherwise, if we have a single return value case, and if the function is // a declaration, maybe we can constant fold it. - if (F && F->isDeclaration() && !isa(I->getType()) && + if (!isa(I->getType()) && F && F->isDeclaration() && canConstantFoldCallTo(F)) { SmallVector Operands; @@ -1229,7 +1235,7 @@ // common path above. goto CallOverdefined; } - + // Finally, if this is the first call to the function hit, mark its entry // block executable. MarkBlockExecutable(F->begin()); @@ -1238,8 +1244,6 @@ CallSite::arg_iterator CAI = CS.arg_begin(); for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI, ++CAI) { - // If this argument is byval, and if the function is not readonly, there - // will be an implicit copy formed of the input aggregate. if (AI->hasByValAttr() && !F->onlyReadsMemory()) { markOverdefined(AI); continue; @@ -1269,8 +1273,7 @@ // for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) - if (Instruction *I = dyn_cast(*UI)) - OperandChangedState(I); + OperandChangedState(*UI); } // Process the instruction work list. @@ -1289,8 +1292,7 @@ if (!getValueState(I).isOverdefined()) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) - if (Instruction *I = dyn_cast(*UI)) - OperandChangedState(I); + OperandChangedState(*UI); } // Process the basic block work list. @@ -1648,25 +1650,14 @@ if (F->isDeclaration()) continue; - // If this is a strong or ODR definition of this function, then we can - // propagate information about its result into callsites of it. - if (!F->mayBeOverridden() && - !isa(F->getReturnType())) + if (!F->hasLocalLinkage() || AddressIsTaken(F)) { + Solver.MarkBlockExecutable(F->begin()); + for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); + AI != E; ++AI) + Solver.markOverdefined(AI); + } else { Solver.AddTrackedFunction(F); - - // If this function only has direct calls that we can see, we can track its - // arguments and return value aggressively, and can assume it is not called - // unless we see evidence to the contrary. - if (F->hasLocalLinkage() && !AddressIsTaken(F)) - continue; - - // Assume the function is called. - Solver.MarkBlockExecutable(F->begin()); - - // Assume nothing about the incoming arguments. - for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); - AI != E; ++AI) - Solver.markOverdefined(AI); + } } // Loop over global variables. We inform the solver about any internal global @@ -1814,21 +1805,16 @@ // TODO: Process multiple value ret instructions also. const DenseMap &RV = Solver.getTrackedRetVals(); for (DenseMap::const_iterator I = RV.begin(), - E = RV.end(); I != E; ++I) { - Function *F = I->first; - if (I->second.isOverdefined() || F->getReturnType()->isVoidTy()) - continue; - - // We can only do this if we know that nothing else can call the function. - if (!F->hasLocalLinkage() || AddressIsTaken(F)) - continue; - - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) - if (ReturnInst *RI = dyn_cast(BB->getTerminator())) - if (!isa(RI->getOperand(0))) - RI->setOperand(0, UndefValue::get(F->getReturnType())); - } - + E = RV.end(); I != E; ++I) + if (!I->second.isOverdefined() && + !I->first->getReturnType()->isVoidTy()) { + Function *F = I->first; + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) + if (!isa(RI->getOperand(0))) + RI->setOperand(0, UndefValue::get(F->getReturnType())); + } + // If we infered constant or undef values for globals variables, we can delete // the global and any stores that remain to it. const DenseMap &TG = Solver.getTrackedGlobals(); From enderby at apple.com Mon Nov 2 14:14:47 2009 From: enderby at apple.com (Kevin Enderby) Date: Mon, 02 Nov 2009 20:14:47 -0000 Subject: [llvm-commits] [llvm] r85823 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Message-ID: <200911022014.nA2KEoqg018908@zion.cs.uiuc.edu> Author: enderby Date: Mon Nov 2 14:14:39 2009 New Revision: 85823 URL: http://llvm.org/viewvc/llvm-project?rev=85823&view=rev Log: Fix ARMAsmParser::ParseMemoryOffsetReg() where the parameter OffsetRegNum should have been passed as a reference. Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=85823&r1=85822&r2=85823&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Nov 2 14:14:39 2009 @@ -56,7 +56,7 @@ const MCExpr *&ShiftAmount, const MCExpr *&Offset, bool &OffsetIsReg, - int OffsetRegNum); + int &OffsetRegNum); bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount); @@ -393,7 +393,7 @@ const MCExpr *&ShiftAmount, const MCExpr *&Offset, bool &OffsetIsReg, - int OffsetRegNum) { + int &OffsetRegNum) { ARMOperand Op; Negative = false; OffsetRegShifted = false; From bob.wilson at apple.com Mon Nov 2 14:59:24 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 02 Nov 2009 20:59:24 -0000 Subject: [llvm-commits] [llvm] r85824 - in /llvm/trunk/lib/Target/ARM: ARMISelLowering.cpp ARMInstrInfo.td ARMInstrThumb.td ARMInstrThumb2.td Message-ID: <200911022059.nA2KxOTV021097@zion.cs.uiuc.edu> Author: bwilson Date: Mon Nov 2 14:59:23 2009 New Revision: 85824 URL: http://llvm.org/viewvc/llvm-project?rev=85824&view=rev Log: Put BlockAddresses into ARM constant pools. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=85824&r1=85823&r2=85824&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Nov 2 14:59:23 2009 @@ -1209,9 +1209,26 @@ SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) { DebugLoc DL = Op.getDebugLoc(); + EVT PtrVT = getPointerTy(); BlockAddress *BA = cast(Op)->getBlockAddress(); - SDValue Result = DAG.getBlockAddress(BA, DL, /*isTarget=*/true); - return DAG.getNode(ARMISD::Wrapper, DL, getPointerTy(), Result); + Reloc::Model RelocM = getTargetMachine().getRelocationModel(); + SDValue CPAddr; + if (RelocM == Reloc::Static) { + CPAddr = DAG.getTargetConstantPool(BA, PtrVT, 4); + } else { + unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; + ARMConstantPoolValue *CPV = new ARMConstantPoolValue(BA, ARMPCLabelIndex, + ARMCP::CPBlockAddress, + PCAdj); + CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); + } + CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr); + SDValue Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), CPAddr, + PseudoSourceValue::getConstantPool(), 0); + if (RelocM == Reloc::Static) + return Result; + SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); + return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel); } // Lower ISD::GlobalTLSAddress using the "general dynamic" model Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85824&r1=85823&r2=85824&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Nov 2 14:59:23 2009 @@ -1607,7 +1607,6 @@ // ConstantPool, GlobalAddress, and JumpTable def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>; def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; -def : ARMPat<(ARMWrapper tblockaddress:$dst), (LEApcrel tblockaddress:$dst)>; def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), (LEApcrelJT tjumptable:$dst, imm:$id)>; Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85824&r1=85823&r2=85824&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Nov 2 14:59:23 2009 @@ -685,7 +685,6 @@ // ConstantPool, GlobalAddress def : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; -def : T1Pat<(ARMWrapper tblockaddress:$dst), (tLEApcrel tblockaddress:$dst)>; // JumpTable def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=85824&r1=85823&r2=85824&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Nov 2 14:59:23 2009 @@ -1169,7 +1169,6 @@ // ConstantPool, GlobalAddress, and JumpTable def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>; def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>; -def : T2Pat<(ARMWrapper tblockaddress:$dst), (t2LEApcrel tblockaddress:$dst)>; def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), (t2LEApcrelJT tjumptable:$dst, imm:$id)>; From evan.cheng at apple.com Mon Nov 2 15:49:14 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 02 Nov 2009 21:49:14 -0000 Subject: [llvm-commits] [llvm] r85827 - in /llvm/trunk: lib/CodeGen/MachineLICM.cpp test/CodeGen/ARM/remat.ll test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Message-ID: <200911022149.nA2LnES6023664@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 2 15:49:14 2009 New Revision: 85827 URL: http://llvm.org/viewvc/llvm-project?rev=85827&view=rev Log: Revert 85799 for now. It might be breaking llvm-gcc driver. Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/test/CodeGen/ARM/remat.ll llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=85827&r1=85826&r2=85827&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Mon Nov 2 15:49:14 2009 @@ -56,12 +56,12 @@ // State that is updated as we process loops bool Changed; // True if a loop is changed. - bool FirstInLoop; // True if it's the first LICM in the loop. MachineLoop *CurLoop; // The current loop we are working on. MachineBasicBlock *CurPreheader; // The preheader for CurLoop. - // For each opcode, keep a list of potentail CSE instructions. - DenseMap > CSEMap; + // For each BB and opcode pair, keep a list of hoisted instructions. + DenseMap, + std::vector > CSEMap; public: static char ID; // Pass identification, replacement for typeid MachineLICM() : MachineFunctionPass(&ID) {} @@ -115,11 +115,6 @@ /// that is safe to hoist, this instruction is called to do the dirty work. /// void Hoist(MachineInstr *MI); - - /// InitCSEMap - Initialize the CSE map with instructions that are in the - /// current loop preheader that may become duplicates of instructions that - /// are hoisted out of the loop. - void InitCSEMap(MachineBasicBlock *BB); }; } // end anonymous namespace @@ -145,7 +140,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { DEBUG(errs() << "******** Machine LICM ********\n"); - Changed = FirstInLoop = false; + Changed = false; TM = &MF.getTarget(); TII = TM->getInstrInfo(); TRI = TM->getRegisterInfo(); @@ -157,7 +152,8 @@ DT = &getAnalysis(); AA = &getAnalysis(); - for (MachineLoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) { + for (MachineLoopInfo::iterator + I = LI->begin(), E = LI->end(); I != E; ++I) { CurLoop = *I; // Only visit outer-most preheader-sporting loops. @@ -174,11 +170,7 @@ if (!CurPreheader) continue; - // CSEMap is initialized for loop header when the first instruction is - // being hoisted. - FirstInLoop = true; HoistRegion(DT->getNode(CurLoop->getHeader())); - CSEMap.clear(); } return Changed; @@ -199,7 +191,10 @@ for (MachineBasicBlock::iterator MII = BB->begin(), E = BB->end(); MII != E; ) { MachineBasicBlock::iterator NextMII = MII; ++NextMII; - Hoist(&*MII); + MachineInstr &MI = *MII; + + Hoist(&MI); + MII = NextMII; } @@ -435,27 +430,6 @@ return NewMIs[0]; } -void MachineLICM::InitCSEMap(MachineBasicBlock *BB) { - for (MachineBasicBlock::iterator I = BB->begin(),E = BB->end(); I != E; ++I) { - const MachineInstr *MI = &*I; - // FIXME: For now, only hoist re-materilizable instructions. LICM will - // increase register pressure. We want to make sure it doesn't increase - // spilling. - if (TII->isTriviallyReMaterializable(MI, AA)) { - unsigned Opcode = MI->getOpcode(); - DenseMap >::iterator - CI = CSEMap.find(Opcode); - if (CI != CSEMap.end()) - CI->second.push_back(MI); - else { - std::vector CSEMIs; - CSEMIs.push_back(MI); - CSEMap.insert(std::make_pair(Opcode, CSEMIs)); - } - } - } -} - /// Hoist - When an instruction is found to use only loop invariant operands /// that are safe to hoist, this instruction is called to do the dirty work. /// @@ -480,14 +454,11 @@ errs() << "\n"; }); - // If this is the first instruction being hoisted to the preheader, - // initialize the CSE map with potential common expressions. - InitCSEMap(CurPreheader); - // Look for opportunity to CSE the hoisted instruction. - unsigned Opcode = MI->getOpcode(); - DenseMap >::iterator - CI = CSEMap.find(Opcode); + std::pair BBOpcPair = + std::make_pair(CurPreheader->getNumber(), MI->getOpcode()); + DenseMap, + std::vector >::iterator CI = CSEMap.find(BBOpcPair); bool DoneCSE = false; if (CI != CSEMap.end()) { const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo); @@ -506,15 +477,15 @@ // Otherwise, splice the instruction to the preheader. if (!DoneCSE) { - CurPreheader->splice(CurPreheader->getFirstTerminator(),MI->getParent(),MI); - + CurPreheader->splice(CurPreheader->getFirstTerminator(), + MI->getParent(), MI); // Add to the CSE map. if (CI != CSEMap.end()) CI->second.push_back(MI); else { std::vector CSEMIs; CSEMIs.push_back(MI); - CSEMap.insert(std::make_pair(Opcode, CSEMIs)); + CSEMap.insert(std::make_pair(BBOpcPair, CSEMIs)); } } Modified: llvm/trunk/test/CodeGen/ARM/remat.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/remat.ll?rev=85827&r1=85826&r2=85827&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/remat.ll (original) +++ llvm/trunk/test/CodeGen/ARM/remat.ll Mon Nov 2 15:49:14 2009 @@ -1,5 +1,5 @@ ; RUN: llc < %s -mtriple=arm-apple-darwin -; RUN: llc < %s -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 5 +; RUN: llc < %s -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 4 %struct.CONTENTBOX = type { i32, i32, i32, i32, i32 } %struct.LOCBOX = type { i32, i32, i32, i32 } Modified: llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll?rev=85827&r1=85826&r2=85827&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Mon Nov 2 15:49:14 2009 @@ -1,5 +1,6 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s -; Increment in loop bb.i28.i adjusted to 2, to prevent loop reversal from +; RUN: llc < %s -march=x86 -mattr=+sse2 -stats |& \ +; RUN: grep {1 .*folded into instructions} +; Increment in loop bb.128.i adjusted to 2, to prevent loop reversal from ; kicking in. declare fastcc void @rdft(i32, i32, double*, i32*, double*) @@ -33,9 +34,6 @@ br label %bb.i28.i bb.i28.i: ; preds = %bb.i28.i, %cond_next36.i -; CHECK: %bb.i28.i -; CHECK: addl $2 -; CHECK: addl $2 %j.0.reg2mem.0.i16.i = phi i32 [ 0, %cond_next36.i ], [ %indvar.next39.i, %bb.i28.i ] ; [#uses=2] %din_addr.1.reg2mem.0.i17.i = phi double [ 0.000000e+00, %cond_next36.i ], [ %tmp16.i25.i, %bb.i28.i ] ; [#uses=1] %tmp1.i18.i = fptosi double %din_addr.1.reg2mem.0.i17.i to i32 ; [#uses=2] From bob.wilson at apple.com Mon Nov 2 16:44:23 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 02 Nov 2009 22:44:23 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85835 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h Message-ID: <200911022244.nA2MiNFd026188@zion.cs.uiuc.edu> Author: bwilson Date: Mon Nov 2 16:44:23 2009 New Revision: 85835 URL: http://llvm.org/viewvc/llvm-project?rev=85835&view=rev Log: Reimplement indirect goto support using Duncan's code from dragonegg. GCC is already transforming the code to have a single indirect goto per function, so repeating that transformation when we convert to llvm is only adding overhead. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-internal.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85835&r1=85834&r2=85835&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Nov 2 16:44:23 2009 @@ -181,9 +181,7 @@ FuncEHSelector = 0; FuncEHGetTypeID = 0; -#ifdef USEINDIRECTBRANCH - IndirectBranch = 0; -#else +#ifndef USEINDIRECTBRANCH NumAddressTakenBlocks = 0; IndirectGotoBlock = 0; #endif @@ -730,22 +728,7 @@ EmitPostPads(); EmitUnwindBlock(); -#ifdef USEINDIRECTBRANCH - // If someone did an indirect goto, emit the indirect goto block at the end of - // the function. - if (IndirectBranch) { - EmitBlock(IndirectBranch->getParent()); - Builder.ClearInsertionPoint(); - - // If someone took the address of a label but never did an indirect goto, - // we made a zero entry PHI node, which is illegal. Zap it now. - PHINode *PN = cast(IndirectBranch->getAddress()); - if (PN->getNumIncomingValues() == 0) { - PN->replaceAllUsesWith(UndefValue::get(PN->getType())); - PN->eraseFromParent(); - } - } -#else +#ifndef USEINDIRECTBRANCH // If this function takes the address of a label, emit the indirect goto // block. if (IndirectGotoBlock) { @@ -1076,8 +1059,12 @@ // Constants. case LABEL_DECL: { +#ifdef USEINDIRECTBRANCH + LV = LValue(EmitLV_LABEL_DECL(exp), 1); +#else Value *Ptr = TreeConstantToLLVM::EmitLV_LABEL_DECL(exp); LV = LValue(Ptr, 1); +#endif break; } case COMPLEX_CST: { @@ -1702,23 +1689,11 @@ } } +#ifndef USEINDIRECTBRANCH //===----------------------------------------------------------------------===// // ... Address Of Labels Extension Support ... //===----------------------------------------------------------------------===// -#ifdef USEINDIRECTBRANCH -/// getBlockAddress - Create a BlockAddress and add it as a possible -/// destination of the IndirectBranch. -BlockAddress *TreeToLLVM::getBlockAddress(BasicBlock *BB) { - // Make sure that there is a block for the indirect goto. - if (IndirectBranch == 0) - getIndirectGotoBlock(); - - // Make sure the indirect branch includes all of the address-taken blocks. - IndirectBranch->addDestination(BB); - return BlockAddress::get(Fn, BB); -} -#else /// getIndirectGotoBlockNumber - Return the unique ID of the specified basic /// block for uses that take the address of it. Constant *TreeToLLVM::getIndirectGotoBlockNumber(BasicBlock *BB) { @@ -1734,26 +1709,10 @@ cast(getIndirectGotoBlock()->getTerminator())->addCase(Val, BB); return Val; } -#endif /// getIndirectGotoBlock - Get (and potentially lazily create) the indirect /// goto block. BasicBlock *TreeToLLVM::getIndirectGotoBlock() { -#ifdef USEINDIRECTBRANCH - // If we already made the indirect branch for indirect goto, return its block. - if (IndirectBranch) return IndirectBranch->getParent(); - - BasicBlock *IndirectGotoBlock = BasicBlock::Create(Context, "indirectgoto"); - LLVMBuilder TmpBuilder(IndirectGotoBlock, *TheFolder); - const Type *Int8PtrTy = Type::getInt8PtrTy(Context); - - // Create the PHI node that indirect gotos will add entries to. - Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest"); - - // Create the indirect branch instruction. - IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal); - return IndirectBranch->getParent(); -#else if (IndirectGotoBlock) return IndirectGotoBlock; // Create a temporary for the value to be switched on. @@ -1766,8 +1725,8 @@ // Finally, return it. return IndirectGotoBlock; -#endif } +#endif //===----------------------------------------------------------------------===// @@ -1782,32 +1741,38 @@ } Value *TreeToLLVM::EmitGOTO_EXPR(tree exp) { - if (TREE_CODE(TREE_OPERAND(exp, 0)) == LABEL_DECL) { + tree dest = GOTO_DESTINATION(exp); + if (TREE_CODE(dest) == LABEL_DECL) { // Direct branch. - Builder.CreateBr(getLabelDeclBlock(TREE_OPERAND(exp, 0))); + Builder.CreateBr(getLabelDeclBlock(dest)); } else { +#ifdef USEINDIRECTBRANCH + // Indirect branch. + basic_block bb = bb_for_stmt(exp); + Value *V = Emit(dest, 0); + IndirectBrInst *Br = Builder.CreateIndirectBr(V, EDGE_COUNT(bb->succs)); + + // Add the list of possible destinations. + edge e; + edge_iterator ei; + FOR_EACH_EDGE (e, ei, bb->succs) + Br->addDestination(getLabelDeclBlock(tree_block_label(e->dest))); +#else // Otherwise we have an indirect goto. BasicBlock *DestBB = getIndirectGotoBlock(); -#ifdef USEINDIRECTBRANCH - Value *V = Emit(TREE_OPERAND(exp, 0), 0); - V = Builder.CreateBitCast(V, Type::getInt8PtrTy(Context)); - // The first instruction in the indirect goto block has to be the PHI for - // the indirect branch address; add an entry for this branch. - cast(DestBB->begin())->addIncoming(V, Builder.GetInsertBlock()); -#else // Store the destination block to the GotoValue alloca. - Value *V = Emit(TREE_OPERAND(exp, 0), 0); + Value *V = Emit(dest); V = CastToType(Instruction::PtrToInt, V, TD.getIntPtrType(Context)); Builder.CreateStore(V, IndirectGotoValue); -#endif // NOTE: This is HORRIBLY INCORRECT in the presence of exception handlers. // There should be one collector block per cleanup level! Note that // standard GCC gets this wrong as well. // Builder.CreateBr(DestBB); +#endif } EmitBlock(BasicBlock::Create(Context, "")); return 0; @@ -6974,6 +6939,14 @@ return LValue(Builder.CreateStructGEP(Ptr.Ptr, Idx), Alignment); } +#ifdef USEINDIRECTBRANCH +Constant *TreeToLLVM::EmitLV_LABEL_DECL(tree exp) { + // GCC kindly diverts labels for unreachable basic blocks to reachable blocks, + // so we are not obliged to output unreachable blocks even if the original + // code took the address of one. + return BlockAddress::get(Fn, getLabelDeclBlock(exp)); +} +#endif //===----------------------------------------------------------------------===// // ... Constant Expressions ... @@ -8052,11 +8025,10 @@ "Taking the address of a label that isn't in the current fn!?"); } - BasicBlock *BB = getLabelDeclBlock(exp); #ifdef USEINDIRECTBRANCH - Constant *Ptr = TheTreeToLLVM->getBlockAddress(BB); - return TheFolder->CreateBitCast(Ptr, Type::getInt8PtrTy(Context)); + return TheTreeToLLVM->EmitLV_LABEL_DECL(exp); #else + BasicBlock *BB = getLabelDeclBlock(exp); Constant *C = TheTreeToLLVM->getIndirectGotoBlockNumber(BB); return TheFolder->CreateIntToPtr(C, Type::getInt8PtrTy(Context)); #endif Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=85835&r1=85834&r2=85835&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Mon Nov 2 16:44:23 2009 @@ -331,13 +331,7 @@ /// FuncEHGetTypeID - Function used to return type id for give typeinfo. Function *FuncEHGetTypeID; -#ifdef USEINDIRECTBRANCH - /// IndirectBranch - The first time an indirect goto is seen we create a - /// block with an indirect branch. Every time we see the address of a label - /// taken, we add the label to the indirect goto. Every subsequent indirect - /// goto is codegen'd as a jump to the IndirectBranch's basic block. - IndirectBrInst *IndirectBranch; -#else +#ifndef USEINDIRECTBRANCH /// NumAddressTakenBlocks - Count the number of labels whose addresses are /// taken. uint64_t NumAddressTakenBlocks; @@ -370,11 +364,7 @@ /// the address of the result. LValue EmitLV(tree_node *exp); -#ifdef USEINDIRECTBRANCH - /// getBlockAddress - Create a BlockAddress and add it as a possible - /// destination of the IndirectBranch. - BlockAddress *getBlockAddress(BasicBlock *BB); -#else +#ifndef USEINDIRECTBRANCH /// getIndirectGotoBlockNumber - Return the unique ID of the specified basic /// block for uses that take the address of it. Constant *getIndirectGotoBlockNumber(BasicBlock *BB); @@ -622,6 +612,12 @@ Value *&Result, const Type *ResultType, std::vector &Ops); + +#ifdef USEINDIRECTBRANCH +public: + // Helper for taking the address of a label. + Constant *EmitLV_LABEL_DECL(tree_node *exp); +#endif }; /// TreeConstantToLLVM - An instance of this class is created and used to From bob.wilson at apple.com Mon Nov 2 16:42:34 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 2 Nov 2009 14:42:34 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r85513 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h In-Reply-To: References: <200910291733.n9THXTXM017953@zion.cs.uiuc.edu> <4AE9FD88.1080507@free.fr> <59C841C1-4D28-47E4-87C3-EE49578066A1@apple.com> <4AEA02BD.7060509@free.fr> Message-ID: On Oct 29, 2009, at 3:09 PM, Bob Wilson wrote: > > On Oct 29, 2009, at 2:01 PM, Duncan Sands wrote: > >> Hi Bob, >> >>> Besides consistency with clang, the idea behind doing it this way >>> is to reduce the number of edges in the CFG. Indirect branches are >>> typically used in things like interpreter loops, where you have a >>> large number of labels and a large number of gotos. If you add an >>> edge from every goto to every label, the CFG can blow up. Instead >>> we have a single indirect branch and all the gotos branch to it, >>> basically factoring out the CFG. >> >> but gcc already does this factorization for you IIRC. So you should >> find >> that there is already only one computed goto in the gimple no matter >> how >> many there were to start off with. > > Oh, I didn't know that. I was just trying to be consistent with the > existing code in llvm-gcc and clang. I'll have another look at it. > If what you say is correct, I agree that the dragonegg approach would > be better. I've changed it to use the dragonegg code. Thanks, Duncan! From bob.wilson at apple.com Mon Nov 2 17:14:22 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 02 Nov 2009 23:14:22 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85837 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200911022314.nA2NENbt027470@zion.cs.uiuc.edu> Author: bwilson Date: Mon Nov 2 17:14:19 2009 New Revision: 85837 URL: http://llvm.org/viewvc/llvm-project?rev=85837&view=rev Log: Fix broken build. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85837&r1=85836&r2=85837&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Nov 2 17:14:19 2009 @@ -1763,7 +1763,7 @@ BasicBlock *DestBB = getIndirectGotoBlock(); // Store the destination block to the GotoValue alloca. - Value *V = Emit(dest); + Value *V = Emit(dest, 0); V = CastToType(Instruction::PtrToInt, V, TD.getIntPtrType(Context)); Builder.CreateStore(V, IndirectGotoValue); From sabre at nondot.org Mon Nov 2 17:25:40 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 02 Nov 2009 23:25:40 -0000 Subject: [llvm-commits] [llvm] r85840 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911022325.nA2NPetB027923@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 17:25:39 2009 New Revision: 85840 URL: http://llvm.org/viewvc/llvm-project?rev=85840&view=rev Log: fix a nasty iterator invalidation bug from my conversion from std::map to DenseMap, exposed on release llvm-gcc bootstrap. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85840&r1=85839&r2=85840&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 17:25:39 2009 @@ -1079,8 +1079,7 @@ // can turn this into a getelementptr ConstantExpr. // void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) { - LatticeVal &IV = ValueState[&I]; - if (IV.isOverdefined()) return; + if (ValueState[&I].isOverdefined()) return; SmallVector Operands; Operands.reserve(I.getNumOperands()); @@ -1091,7 +1090,7 @@ return; // Operands are not resolved yet. if (State.isOverdefined()) - return markOverdefined(IV, &I); + return markOverdefined(&I); assert(State.isConstant() && "Unknown state!"); Operands.push_back(State.getConstant()); From bob.wilson at apple.com Mon Nov 2 18:02:06 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 03 Nov 2009 00:02:06 -0000 Subject: [llvm-commits] [llvm] r85844 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <200911030002.nA3026E3029272@zion.cs.uiuc.edu> Author: bwilson Date: Mon Nov 2 18:02:05 2009 New Revision: 85844 URL: http://llvm.org/viewvc/llvm-project?rev=85844&view=rev Log: Revert previous change to a comment. The BlockAddresses go in the constant pool so they don't get wrapped separately. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=85844&r1=85843&r2=85844&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Nov 2 18:02:05 2009 @@ -1186,12 +1186,12 @@ return result; } -// ConstantPool, BlockAddress, JumpTable, GlobalAddress, and ExternalSymbol are -// lowered as their target counterpart wrapped in the ARMISD::Wrapper -// node. Suppose N is one of the above mentioned nodes. It has to be wrapped -// because otherwise Select(N) returns N. So the raw TargetGlobalAddress -// nodes, etc. can only be used to form addressing mode. These wrapped nodes -// will be selected into MOVi. +// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as +// their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is +// one of the above mentioned nodes. It has to be wrapped because otherwise +// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only +// be used to form addressing mode. These wrapped nodes will be selected +// into MOVi. static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) { EVT PtrVT = Op.getValueType(); // FIXME there is no actual debug info here From anton at korobeynikov.info Mon Nov 2 18:24:06 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Tue, 3 Nov 2009 03:24:06 +0300 Subject: [llvm-commits] [llvm] r85049 - in /llvm/trunk/lib/Target/ARM: ARMBaseRegisterInfo.cpp ARMBaseRegisterInfo.h In-Reply-To: <200910250753.n9P7rSQb019706@zion.cs.uiuc.edu> References: <200910250753.n9P7rSQb019706@zion.cs.uiuc.edu> Message-ID: Hello, Evan > Add ARM getMatchingSuperRegClass to handle S / D / Q cross regclass coalescing. This causes PR5367, I've reverted it for now. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From asl at math.spbu.ru Mon Nov 2 18:24:48 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 03 Nov 2009 00:24:48 -0000 Subject: [llvm-commits] [llvm] r85847 - in /llvm/trunk: lib/Target/ARM/ARMBaseRegisterInfo.cpp test/CodeGen/ARM/2009-11-01-NeonMoves.ll Message-ID: <200911030024.nA30Ombr030165@zion.cs.uiuc.edu> Author: asl Date: Mon Nov 2 18:24:48 2009 New Revision: 85847 URL: http://llvm.org/viewvc/llvm-project?rev=85847&view=rev Log: Revert r85049, it is causing PR5367 Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=85847&r1=85846&r2=85847&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Mon Nov 2 18:24:48 2009 @@ -257,6 +257,7 @@ ARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned SubIdx) const { +#if 0 switch (SubIdx) { default: return 0; case 1: @@ -277,6 +278,7 @@ // D sub-registers. return A; } +#endif return 0; } Modified: llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll?rev=85847&r1=85846&r2=85847&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll Mon Nov 2 18:24:48 2009 @@ -1,4 +1,4 @@ -; RUN: llc -mcpu=cortex-a8 < %s | grep vmov | count 1 +; RUN: llc -mcpu=cortex-a8 < %s | grep vmov | count 2 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" target triple = "armv7-eabi" From asl at math.spbu.ru Mon Nov 2 18:37:36 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 03 Nov 2009 00:37:36 -0000 Subject: [llvm-commits] [llvm] r85848 - in /llvm/trunk/test/CodeGen/Thumb2: 2009-08-04-SubregLoweringBug.ll cross-rc-coalescing-2.ll Message-ID: <200911030037.nA30bbr7030592@zion.cs.uiuc.edu> Author: asl Date: Mon Nov 2 18:37:36 2009 New Revision: 85848 URL: http://llvm.org/viewvc/llvm-project?rev=85848&view=rev Log: Temporary xfail until PR5367 will be resolved Modified: llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll Modified: llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll?rev=85848&r1=85847&r2=85848&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll Mon Nov 2 18:37:36 2009 @@ -1,6 +1,7 @@ ; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mattr=+neon -arm-use-neon-fp ; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mattr=+neon -arm-use-neon-fp | not grep fcpys ; rdar://7117307 +; XFAIL: * %struct.Hosp = type { i32, i32, i32, %struct.List, %struct.List, %struct.List, %struct.List } %struct.List = type { %struct.List*, %struct.Patient*, %struct.List* } Modified: llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll?rev=85848&r1=85847&r2=85848&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll Mon Nov 2 18:37:36 2009 @@ -1,4 +1,5 @@ ; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | grep fcpys | count 4 +; XFAIL: * define arm_apcscc void @fht(float* nocapture %fz, i16 signext %n) nounwind { entry: From anton at korobeynikov.info Mon Nov 2 18:56:06 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Tue, 3 Nov 2009 03:56:06 +0300 Subject: [llvm-commits] [llvm] r85362 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/ARM/ARMInstrVFP.td lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp lib/Target/ARM/AsmPrinter/ARMInstPrinter.h test/CodeGen/A Message-ID: Hello, Evan > +define arm_apcscc float @t4(float %x) nounwind readnone optsize { > +entry: > +; CHECK: t4: > +; CHECK: fconsts s1, 184 > + ?%0 = fmul float %x, -2.400000e+01 > + ?ret float %0 > +} This is invalid assembler. According to ARM docs immediate should have '#' in the beginning. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From asl at math.spbu.ru Mon Nov 2 19:04:26 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 03 Nov 2009 01:04:26 -0000 Subject: [llvm-commits] [llvm] r85850 - in /llvm/trunk/lib/Target/ARM: ARM.h ARMBaseInstrInfo.cpp ARMTargetMachine.cpp NEONMoveFix.cpp Message-ID: <200911030104.nA314RYX031608@zion.cs.uiuc.edu> Author: asl Date: Mon Nov 2 19:04:26 2009 New Revision: 85850 URL: http://llvm.org/viewvc/llvm-project?rev=85850&view=rev Log: Turn neon reg-reg moves fixup code into separate pass. This should reduce the compile time. Added: llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp Modified: llvm/trunk/lib/Target/ARM/ARM.h llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Modified: llvm/trunk/lib/Target/ARM/ARM.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.h?rev=85850&r1=85849&r2=85850&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARM.h (original) +++ llvm/trunk/lib/Target/ARM/ARM.h Mon Nov 2 19:04:26 2009 @@ -105,6 +105,7 @@ FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false); FunctionPass *createARMConstantIslandPass(); FunctionPass *createNEONPreAllocPass(); +FunctionPass *createNEONMoveFixPass(); FunctionPass *createThumb2ITBlockPass(); FunctionPass *createThumb2SizeReductionPass(); Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=85850&r1=85849&r2=85850&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Mon Nov 2 19:04:26 2009 @@ -658,39 +658,8 @@ // Always use neon reg-reg move if source or dest is NEON-only regclass. BuildMI(MBB, I, DL, get(ARM::VMOVD), DestReg).addReg(SrcReg); } else if (DestRC == ARM::DPRRegisterClass) { - const ARMBaseRegisterInfo* TRI = &getRegisterInfo(); - - // If we do not found an instruction defining the reg, this means the - // register should be live-in for this BB. It's always to better to use - // NEON reg-reg moves. - unsigned Domain = ARMII::DomainNEON; - - // Find the Machine Instruction which defines SrcReg. - if (!MBB.empty()) { - MachineBasicBlock::iterator J = (I == MBB.begin() ? I : prior(I)); - while (J != MBB.begin()) { - if (J->modifiesRegister(SrcReg, TRI)) - break; - --J; - } - - if (J->modifiesRegister(SrcReg, TRI)) { - Domain = J->getDesc().TSFlags & ARMII::DomainMask; - // Instructions in general domain are subreg accesses. - // Map them to NEON reg-reg moves. - if (Domain == ARMII::DomainGeneral) - Domain = ARMII::DomainNEON; - } - } - - if ((Domain & ARMII::DomainNEON) && getSubtarget().hasNEON()) { - BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); - } else { - assert((Domain & ARMII::DomainVFP || - !getSubtarget().hasNEON()) && "Invalid domain!"); - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg) - .addReg(SrcReg)); - } + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg) + .addReg(SrcReg)); } else if (DestRC == ARM::QPRRegisterClass || DestRC == ARM::QPR_VFP2RegisterClass) { BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp?rev=85850&r1=85849&r2=85850&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Mon Nov 2 19:04:26 2009 @@ -112,8 +112,11 @@ bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel) { // FIXME: temporarily disabling load / store optimization pass for Thumb1. - if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only()) - PM.add(createIfConverterPass()); + if (OptLevel != CodeGenOpt::None) { + if (!Subtarget.isThumb1Only()) + PM.add(createIfConverterPass()); + PM.add(createNEONMoveFixPass()); + } if (Subtarget.isThumb2()) { PM.add(createThumb2ITBlockPass()); Added: llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp?rev=85850&view=auto ============================================================================== --- llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp (added) +++ llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp Mon Nov 2 19:04:26 2009 @@ -0,0 +1,144 @@ +//===-- NEONMoveFix.cpp - Convert vfp reg-reg moves into neon ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "neon-mov-fix" +#include "ARM.h" +#include "ARMMachineFunctionInfo.h" +#include "ARMInstrInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +STATISTIC(NumVMovs, "Number of reg-reg moves converted"); + +namespace { + struct NEONMoveFixPass : public MachineFunctionPass { + static char ID; + NEONMoveFixPass() : MachineFunctionPass(&ID) {} + + virtual bool runOnMachineFunction(MachineFunction &Fn); + + virtual const char *getPassName() const { + return "NEON reg-reg move conversion"; + } + + private: + const TargetRegisterInfo *TRI; + const ARMBaseInstrInfo *TII; + const ARMSubtarget *Subtarget; + + typedef DenseMap RegMap; + + bool InsertMoves(MachineBasicBlock &MBB); + }; + char NEONMoveFixPass::ID = 0; +} + +bool NEONMoveFixPass::InsertMoves(MachineBasicBlock &MBB) { + RegMap Defs; + bool Modified = false; + + // Walk over MBB tracking the def points of the registers. + MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end(); + MachineBasicBlock::iterator NextMII; + for (; MII != E; MII = NextMII) { + NextMII = next(MII); + MachineInstr *MI = &*MII; + + if (MI->getOpcode() == ARM::FCPYD && + !TII->isPredicated(MI)) { + unsigned SrcReg = MI->getOperand(1).getReg(); + // If we do not found an instruction defining the reg, this means the + // register should be live-in for this BB. It's always to better to use + // NEON reg-reg moves. + unsigned Domain = ARMII::DomainNEON; + RegMap::iterator DefMI = Defs.find(SrcReg); + if (DefMI != Defs.end()) { + Domain = DefMI->second->getDesc().TSFlags & ARMII::DomainMask; + // Instructions in general domain are subreg accesses. + // Map them to NEON reg-reg moves. + if (Domain == ARMII::DomainGeneral) + Domain = ARMII::DomainNEON; + } + + if ((Domain & ARMII::DomainNEON) && Subtarget->hasNEON()) { + // Convert FCPYD to VMOVD. + unsigned DestReg = MI->getOperand(0).getReg(); + + DEBUG({errs() << "vmov convert: "; MI->dump();}); + + // It's safe to ignore imp-defs / imp-uses here, since: + // - We're running late, no intelligent condegen passes should be run + // afterwards + // - The imp-defs / imp-uses are superregs only, we don't care about + // them. + BuildMI(MBB, *MI, MI->getDebugLoc(), + TII->get(ARM::VMOVD), DestReg).addReg(SrcReg); + MBB.erase(MI); + MachineBasicBlock::iterator I = prior(NextMII); + MI = &*I; + + DEBUG({errs() << " into: "; MI->dump();}); + + Modified = true; + ++NumVMovs; + } else { + assert((Domain & ARMII::DomainVFP || + !Subtarget->hasNEON()) && "Invalid domain!"); + // Do nothing. + } + } + + // Update def information. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand& MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) + continue; + unsigned MOReg = MO.getReg(); + + Defs[MOReg] = MI; + // Catch subregs as well. + for (const unsigned *R = TRI->getSubRegisters(MOReg); *R; ++R) + Defs[*R] = MI; + } + } + + return Modified; +} + +bool NEONMoveFixPass::runOnMachineFunction(MachineFunction &Fn) { + ARMFunctionInfo *AFI = Fn.getInfo(); + const TargetMachine &TM = Fn.getTarget(); + + if (AFI->isThumbFunction()) + return false; + + TRI = TM.getRegisterInfo(); + Subtarget = &TM.getSubtarget(); + TII = static_cast(TM.getInstrInfo()); + + bool Modified = false; + for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; + ++MFI) { + MachineBasicBlock &MBB = *MFI; + Modified |= InsertMoves(MBB); + } + + return Modified; +} + +/// createNEONMoveFixPass - Returns an instance of the NEON reg-reg moves fix +/// pass. +FunctionPass *llvm::createNEONMoveFixPass() { + return new NEONMoveFixPass(); +} From evan.cheng at apple.com Mon Nov 2 20:13:57 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 2 Nov 2009 18:13:57 -0800 Subject: [llvm-commits] [llvm] r85850 - in /llvm/trunk/lib/Target/ARM: ARM.h ARMBaseInstrInfo.cpp ARMTargetMachine.cpp NEONMoveFix.cpp In-Reply-To: <200911030104.nA314RYX031608@zion.cs.uiuc.edu> References: <200911030104.nA314RYX031608@zion.cs.uiuc.edu> Message-ID: <1C12EC22-892A-4F26-8005-B2AD1EBEDBC8@apple.com> On Nov 2, 2009, at 5:04 PM, Anton Korobeynikov wrote: > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Mon Nov 2 19:04:26 2009 > @@ -112,8 +112,11 @@ > bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM, > CodeGenOpt::Level OptLevel) { > // FIXME: temporarily disabling load / store optimization pass for Thumb1. > - if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only()) > - PM.add(createIfConverterPass()); > + if (OptLevel != CodeGenOpt::None) { > + if (!Subtarget.isThumb1Only()) > + PM.add(createIfConverterPass()); > + PM.add(createNEONMoveFixPass()); Please make sure this is run only when NEON is available. Evan > + } > > if (Subtarget.isThumb2()) { > PM.add(createThumb2ITBlockPass()); > > Added: llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp?rev=85850&view=auto > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp (added) > +++ llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp Mon Nov 2 19:04:26 2009 > @@ -0,0 +1,144 @@ > +//===-- NEONMoveFix.cpp - Convert vfp reg-reg moves into neon ---*- C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#define DEBUG_TYPE "neon-mov-fix" > +#include "ARM.h" > +#include "ARMMachineFunctionInfo.h" > +#include "ARMInstrInfo.h" > +#include "llvm/CodeGen/MachineInstr.h" > +#include "llvm/CodeGen/MachineInstrBuilder.h" > +#include "llvm/CodeGen/MachineFunctionPass.h" > +#include "llvm/ADT/Statistic.h" > +#include "llvm/Support/Debug.h" > +#include "llvm/Support/raw_ostream.h" > +using namespace llvm; > + > +STATISTIC(NumVMovs, "Number of reg-reg moves converted"); > + > +namespace { > + struct NEONMoveFixPass : public MachineFunctionPass { > + static char ID; > + NEONMoveFixPass() : MachineFunctionPass(&ID) {} > + > + virtual bool runOnMachineFunction(MachineFunction &Fn); > + > + virtual const char *getPassName() const { > + return "NEON reg-reg move conversion"; > + } > + > + private: > + const TargetRegisterInfo *TRI; > + const ARMBaseInstrInfo *TII; > + const ARMSubtarget *Subtarget; > + > + typedef DenseMap RegMap; > + > + bool InsertMoves(MachineBasicBlock &MBB); > + }; > + char NEONMoveFixPass::ID = 0; > +} > + > +bool NEONMoveFixPass::InsertMoves(MachineBasicBlock &MBB) { > + RegMap Defs; > + bool Modified = false; > + > + // Walk over MBB tracking the def points of the registers. > + MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end(); > + MachineBasicBlock::iterator NextMII; > + for (; MII != E; MII = NextMII) { > + NextMII = next(MII); > + MachineInstr *MI = &*MII; > + > + if (MI->getOpcode() == ARM::FCPYD && > + !TII->isPredicated(MI)) { > + unsigned SrcReg = MI->getOperand(1).getReg(); > + // If we do not found an instruction defining the reg, this means the > + // register should be live-in for this BB. It's always to better to use > + // NEON reg-reg moves. > + unsigned Domain = ARMII::DomainNEON; > + RegMap::iterator DefMI = Defs.find(SrcReg); > + if (DefMI != Defs.end()) { > + Domain = DefMI->second->getDesc().TSFlags & ARMII::DomainMask; > + // Instructions in general domain are subreg accesses. > + // Map them to NEON reg-reg moves. > + if (Domain == ARMII::DomainGeneral) > + Domain = ARMII::DomainNEON; > + } > + > + if ((Domain & ARMII::DomainNEON) && Subtarget->hasNEON()) { > + // Convert FCPYD to VMOVD. > + unsigned DestReg = MI->getOperand(0).getReg(); > + > + DEBUG({errs() << "vmov convert: "; MI->dump();}); > + > + // It's safe to ignore imp-defs / imp-uses here, since: > + // - We're running late, no intelligent condegen passes should be run > + // afterwards > + // - The imp-defs / imp-uses are superregs only, we don't care about > + // them. > + BuildMI(MBB, *MI, MI->getDebugLoc(), > + TII->get(ARM::VMOVD), DestReg).addReg(SrcReg); > + MBB.erase(MI); > + MachineBasicBlock::iterator I = prior(NextMII); > + MI = &*I; > + > + DEBUG({errs() << " into: "; MI->dump();}); > + > + Modified = true; > + ++NumVMovs; > + } else { > + assert((Domain & ARMII::DomainVFP || > + !Subtarget->hasNEON()) && "Invalid domain!"); > + // Do nothing. > + } > + } > + > + // Update def information. > + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + const MachineOperand& MO = MI->getOperand(i); > + if (!MO.isReg() || !MO.isDef()) > + continue; > + unsigned MOReg = MO.getReg(); > + > + Defs[MOReg] = MI; > + // Catch subregs as well. > + for (const unsigned *R = TRI->getSubRegisters(MOReg); *R; ++R) > + Defs[*R] = MI; > + } > + } > + > + return Modified; > +} > + > +bool NEONMoveFixPass::runOnMachineFunction(MachineFunction &Fn) { > + ARMFunctionInfo *AFI = Fn.getInfo(); > + const TargetMachine &TM = Fn.getTarget(); > + > + if (AFI->isThumbFunction()) > + return false; > + > + TRI = TM.getRegisterInfo(); > + Subtarget = &TM.getSubtarget(); > + TII = static_cast(TM.getInstrInfo()); > + > + bool Modified = false; > + for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; > + ++MFI) { > + MachineBasicBlock &MBB = *MFI; > + Modified |= InsertMoves(MBB); > + } > + > + return Modified; > +} > + > +/// createNEONMoveFixPass - Returns an instance of the NEON reg-reg moves fix > +/// pass. > +FunctionPass *llvm::createNEONMoveFixPass() { > + return new NEONMoveFixPass(); > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From natebegeman at mac.com Mon Nov 2 20:19:31 2009 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 03 Nov 2009 02:19:31 -0000 Subject: [llvm-commits] [llvm] r85853 - /llvm/trunk/test/CodeGen/Generic/intrinsics.ll Message-ID: <200911030219.nA32JV5U002185@zion.cs.uiuc.edu> Author: sampo Date: Mon Nov 2 20:19:31 2009 New Revision: 85853 URL: http://llvm.org/viewvc/llvm-project?rev=85853&view=rev Log: Declare sin & cos as readonly so they match the code in SelectionDAGBuild Modified: llvm/trunk/test/CodeGen/Generic/intrinsics.ll Modified: llvm/trunk/test/CodeGen/Generic/intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/intrinsics.ll?rev=85853&r1=85852&r2=85853&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/intrinsics.ll (original) +++ llvm/trunk/test/CodeGen/Generic/intrinsics.ll Mon Nov 2 20:19:31 2009 @@ -14,9 +14,9 @@ ; SIN -declare float @sinf(float) +declare float @sinf(float) readonly -declare double @sin(double) +declare double @sin(double) readonly define double @test_sin(float %F) { %G = call float @sinf( float %F ) ; [#uses=1] @@ -27,9 +27,9 @@ ; COS -declare float @cosf(float) +declare float @cosf(float) readonly -declare double @cos(double) +declare double @cos(double) readonly define double @test_cos(float %F) { %G = call float @cosf( float %F ) ; [#uses=1] From gohman at apple.com Mon Nov 2 21:16:40 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 2 Nov 2009 19:16:40 -0800 Subject: [llvm-commits] [PATCH] Make opt default to not adding a target data string, and update tests In-Reply-To: <400d33ea0911021113h7385041fo34c1fafd3ca38b19@mail.gmail.com> References: <400d33ea0911021113h7385041fo34c1fafd3ca38b19@mail.gmail.com> Message-ID: <06A3392E-15EA-4760-A3D9-B3B9CEDE6F67@apple.com> Hello, If I read this correctly, this makes the NoDefaultDataLayout option unused. Is that right? If so, please remove the option completely. Otherwise, this patch looks fine. Thanks for updating all those tests! Dan On Nov 2, 2009, at 11:13 AM, Kenneth Uildriks wrote: > All tests in the test directory that depend on target data now > explicitly include the target data in the input assembly. This makes > it safe for opt to not add target data whenever it's not supplied by > either the module or the command line, which in turn stops opt from > breaking valid code with bogus target data assumptions. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From lessen42 at gmail.com Mon Nov 2 03:53:12 2009 From: lessen42 at gmail.com (David Conrad) Date: Mon, 2 Nov 2009 04:53:12 -0500 Subject: [llvm-commits] [llvm] r85697 - in /llvm/trunk: lib/Target/ARM/ARMInstrNEON.td test/CodeGen/ARM/fmacs.ll test/CodeGen/ARM/fnmacs.ll test/CodeGen/Thumb2/cross-rc-coalescing-2.ll In-Reply-To: References: <200910312257.n9VMvbZm030355@zion.cs.uiuc.edu> Message-ID: <72AADD0D-6CAF-433E-8533-A8157E28F8D9@gmail.com> On Nov 1, 2009, at 1:31 PM, Evan Cheng wrote: > > On Nov 1, 2009, at 10:22 AM, Anton Korobeynikov wrote: > >> Hello, Evan >> >>> On the other hand, a vmla.32 followed by another vmla.32 is just >>> fine. And >>> it is faster than vmul + vadd. I agree we should try to solve it >>> better. >>> Perhaps expanding it before or during schedule2. >> Right, NEON scheduling is tricky, it seems that our instruction >> itineraries are not expressible enough for such complex pipelines. > > I think we should be able to handle at least the true dependency > cases. Instruction latency is a function of both defining instruction > and the use. cc'ing David for his comments. Whoops, I'm too used to MLs with reply-to set to the list address. Anyway, I misread the commit, but separating vmla.f32 into vmul.f32 + vadd.f32 doesn't help either. The vmul+vadd chain will have the result available the same cycle as worst-case vmla: 9 cycles after issue. Ignoring pipelined instructions, the vmul+vadd will stall for 4 cycles between the instructions and 4 cycles after, equal to the 8 cycles for vmla in the same situation. The note in the ref manual about vmla/vmls is just calling attention to the special forwarding path available to only those instructions; the 8 cycle stall is what would always happen otherwise based on the cycle timings. Thus even without modeling the special behaviour of vmla it's always better to use it: it'll always be at least as fast as a separate vmul +vadd. This applies to the integer versions as well. From natebegeman at mac.com Mon Nov 2 21:30:51 2009 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 03 Nov 2009 03:30:51 -0000 Subject: [llvm-commits] [llvm] r85857 - /llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Message-ID: <200911030330.nA33UpH5004693@zion.cs.uiuc.edu> Author: sampo Date: Mon Nov 2 21:30:51 2009 New Revision: 85857 URL: http://llvm.org/viewvc/llvm-project?rev=85857&view=rev Log: Add a couple more target nodes Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=85857&r1=85856&r2=85857&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original) +++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Mon Nov 2 21:30:51 2009 @@ -329,6 +329,8 @@ def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>; +def fexp2 : SDNode<"ISD::FEXP2" , SDTFPUnaryOp>; +def flog2 : SDNode<"ISD::FLOG2" , SDTFPUnaryOp>; def frint : SDNode<"ISD::FRINT" , SDTFPUnaryOp>; def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>; def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>; From clattner at apple.com Mon Nov 2 21:40:06 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 2 Nov 2009 19:40:06 -0800 Subject: [llvm-commits] [llvm] r85738 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/phi.ll In-Reply-To: <4AEEEB73.9070101@free.fr> References: <200911012007.nA1K78eB012267@zion.cs.uiuc.edu> <4AEEEB73.9070101@free.fr> Message-ID: On Nov 2, 2009, at 6:23 AM, Duncan Sands wrote: > Hi Chris, > >> - LoadAlignment = std::max(LoadAlignment, LI->getAlignment()); >> + LoadAlignment = std::min(LoadAlignment, LI->getAlignment()); > > if one alignment is zero and the other is not, then zero (the > minimum) may > be the wrong result. On the other hand, if one is zero and the > other is > over aligned (bigger than the ABI alignment), then zero is the right > thing, > not the bigger alignment. You need target data to get this right. The transformation explicitly does not transform the case when some loads have an alignment specified and others do. It only xforms when all are specified or none are. -Chris From sabre at nondot.org Mon Nov 2 21:42:52 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 03:42:52 -0000 Subject: [llvm-commits] [llvm] r85858 - in /llvm/trunk: include/llvm/Support/StandardPasses.h lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911030342.nA33gq5U005301@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 21:42:51 2009 New Revision: 85858 URL: http://llvm.org/viewvc/llvm-project?rev=85858&view=rev Log: turn IPSCCP back on now that the iterator invalidation bug is fixed. Modified: llvm/trunk/include/llvm/Support/StandardPasses.h llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=85858&r1=85857&r2=85858&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Nov 2 21:42:51 2009 @@ -99,7 +99,6 @@ if (UnitAtATime) { PM->add(createGlobalOptimizerPass()); // Optimize out global vars - PM->add(createIPConstantPropagationPass()); // IP CP PM->add(createIPSCCPPass()); // IP SCCP PM->add(createDeadArgEliminationPass()); // Dead argument elimination } Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85858&r1=85857&r2=85858&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Nov 2 21:42:51 2009 @@ -25,7 +25,6 @@ #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Target/TargetData.h" @@ -227,7 +226,6 @@ /// and out of the specified function (which cannot have its address taken), /// this method must be called. void AddTrackedFunction(Function *F) { - assert(F->hasLocalLinkage() && "Can only track internal functions!"); // Add an entry, F -> undef. if (const StructType *STy = dyn_cast(F->getReturnType())) { for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) @@ -380,11 +378,9 @@ // instruction that was just changed state somehow. Based on this // information, we need to update the specified user of this instruction. // - void OperandChangedState(User *U) { - // Only instructions use other variable values! - Instruction &I = cast(*U); - if (BBExecutable.count(I.getParent())) // Inst is executable? - visit(I); + void OperandChangedState(Instruction *I) { + if (BBExecutable.count(I->getParent())) // Inst is executable? + visit(*I); } /// RemoveFromOverdefinedPHIs - If I has any entries in the @@ -428,8 +424,6 @@ void visitLoadInst (LoadInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); void visitCallInst (CallInst &I) { - if (isFreeCall(&I)) - return; visitCallSite(CallSite::get(&I)); } void visitInvokeInst (InvokeInst &II) { @@ -656,19 +650,19 @@ markConstant(&PN, OperandVal); // Acquire operand value } + + + void SCCPSolver::visitReturnInst(ReturnInst &I) { if (I.getNumOperands() == 0) return; // ret void Function *F = I.getParent()->getParent(); + // If we are tracking the return value of this function, merge it in. - if (!F->hasLocalLinkage()) - return; - if (!TrackedRetVals.empty()) { DenseMap::iterator TFRVI = TrackedRetVals.find(F); - if (TFRVI != TrackedRetVals.end() && - !TFRVI->second.isOverdefined()) { + if (TFRVI != TrackedRetVals.end()) { mergeInValue(TFRVI->second, F, getValueState(I.getOperand(0))); return; } @@ -1163,14 +1157,14 @@ // The common case is that we aren't tracking the callee, either because we // are not doing interprocedural analysis or the callee is indirect, or is // external. Handle these cases first. - if (F == 0 || !F->hasLocalLinkage()) { + if (F == 0 || F->isDeclaration()) { CallOverdefined: // Void return and not tracking callee, just bail. if (I->getType()->isVoidTy()) return; // Otherwise, if we have a single return value case, and if the function is // a declaration, maybe we can constant fold it. - if (!isa(I->getType()) && F && F->isDeclaration() && + if (F && F->isDeclaration() && !isa(I->getType()) && canConstantFoldCallTo(F)) { SmallVector Operands; @@ -1234,7 +1228,7 @@ // common path above. goto CallOverdefined; } - + // Finally, if this is the first call to the function hit, mark its entry // block executable. MarkBlockExecutable(F->begin()); @@ -1243,6 +1237,8 @@ CallSite::arg_iterator CAI = CS.arg_begin(); for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI, ++CAI) { + // If this argument is byval, and if the function is not readonly, there + // will be an implicit copy formed of the input aggregate. if (AI->hasByValAttr() && !F->onlyReadsMemory()) { markOverdefined(AI); continue; @@ -1272,7 +1268,8 @@ // for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) - OperandChangedState(*UI); + if (Instruction *I = dyn_cast(*UI)) + OperandChangedState(I); } // Process the instruction work list. @@ -1291,7 +1288,8 @@ if (!getValueState(I).isOverdefined()) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) - OperandChangedState(*UI); + if (Instruction *I = dyn_cast(*UI)) + OperandChangedState(I); } // Process the basic block work list. @@ -1649,14 +1647,25 @@ if (F->isDeclaration()) continue; - if (!F->hasLocalLinkage() || AddressIsTaken(F)) { - Solver.MarkBlockExecutable(F->begin()); - for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); - AI != E; ++AI) - Solver.markOverdefined(AI); - } else { + // If this is a strong or ODR definition of this function, then we can + // propagate information about its result into callsites of it. + if (!F->mayBeOverridden() && + !isa(F->getReturnType())) Solver.AddTrackedFunction(F); - } + + // If this function only has direct calls that we can see, we can track its + // arguments and return value aggressively, and can assume it is not called + // unless we see evidence to the contrary. + if (F->hasLocalLinkage() && !AddressIsTaken(F)) + continue; + + // Assume the function is called. + Solver.MarkBlockExecutable(F->begin()); + + // Assume nothing about the incoming arguments. + for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); + AI != E; ++AI) + Solver.markOverdefined(AI); } // Loop over global variables. We inform the solver about any internal global @@ -1804,16 +1813,21 @@ // TODO: Process multiple value ret instructions also. const DenseMap &RV = Solver.getTrackedRetVals(); for (DenseMap::const_iterator I = RV.begin(), - E = RV.end(); I != E; ++I) - if (!I->second.isOverdefined() && - !I->first->getReturnType()->isVoidTy()) { - Function *F = I->first; - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) - if (ReturnInst *RI = dyn_cast(BB->getTerminator())) - if (!isa(RI->getOperand(0))) - RI->setOperand(0, UndefValue::get(F->getReturnType())); - } - + E = RV.end(); I != E; ++I) { + Function *F = I->first; + if (I->second.isOverdefined() || F->getReturnType()->isVoidTy()) + continue; + + // We can only do this if we know that nothing else can call the function. + if (!F->hasLocalLinkage() || AddressIsTaken(F)) + continue; + + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) + if (!isa(RI->getOperand(0))) + RI->setOperand(0, UndefValue::get(F->getReturnType())); + } + // If we infered constant or undef values for globals variables, we can delete // the global and any stores that remain to it. const DenseMap &TG = Solver.getTrackedGlobals(); From kremenek at apple.com Mon Nov 2 22:01:54 2009 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 03 Nov 2009 04:01:54 -0000 Subject: [llvm-commits] [llvm] r85859 - /llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Message-ID: <200911030401.nA341svN006074@zion.cs.uiuc.edu> Author: kremenek Date: Mon Nov 2 22:01:53 2009 New Revision: 85859 URL: http://llvm.org/viewvc/llvm-project?rev=85859&view=rev Log: Alphabetize. Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=85859&r1=85858&r2=85859&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Mon Nov 2 22:01:53 2009 @@ -13,6 +13,7 @@ LCSSA.cpp Local.cpp LoopSimplify.cpp + LoopUnroll.cpp LowerInvoke.cpp LowerSwitch.cpp Mem2Reg.cpp @@ -21,7 +22,6 @@ SSI.cpp SimplifyCFG.cpp UnifyFunctionExitNodes.cpp - LoopUnroll.cpp ValueMapper.cpp ) From kremenek at apple.com Mon Nov 2 22:06:58 2009 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 03 Nov 2009 04:06:58 -0000 Subject: [llvm-commits] [llvm] r85860 - /llvm/trunk/utils/UpdateCMakeLists.pl Message-ID: <200911030406.nA346wTK006274@zion.cs.uiuc.edu> Author: kremenek Date: Mon Nov 2 22:06:58 2009 New Revision: 85860 URL: http://llvm.org/viewvc/llvm-project?rev=85860&view=rev Log: Support updating 'llvm_add_target' lists as well. Modified: llvm/trunk/utils/UpdateCMakeLists.pl Modified: llvm/trunk/utils/UpdateCMakeLists.pl URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/UpdateCMakeLists.pl?rev=85860&r1=85859&r2=85860&view=diff ============================================================================== --- llvm/trunk/utils/UpdateCMakeLists.pl (original) +++ llvm/trunk/utils/UpdateCMakeLists.pl Mon Nov 2 22:06:58 2009 @@ -68,7 +68,7 @@ while() { if (!$foundLibrary) { print OUT $_; - if (/^add_clang_library\(/ || /^add_llvm_library\(/) { + if (/^add_clang_library\(/ || /^add_llvm_library\(/ || /^add_llvm_target\(/) { $foundLibrary = 1; EmitCMakeList($dir); } From kremenek at apple.com Mon Nov 2 22:14:14 2009 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 03 Nov 2009 04:14:14 -0000 Subject: [llvm-commits] [llvm] r85861 - /llvm/trunk/lib/Target/ARM/CMakeLists.txt Message-ID: <200911030414.nA34EEf2006597@zion.cs.uiuc.edu> Author: kremenek Date: Mon Nov 2 22:14:12 2009 New Revision: 85861 URL: http://llvm.org/viewvc/llvm-project?rev=85861&view=rev Log: Update CMake file. Modified: llvm/trunk/lib/Target/ARM/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=85861&r1=85860&r2=85861&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/ARM/CMakeLists.txt Mon Nov 2 22:14:12 2009 @@ -17,15 +17,16 @@ ARMCodeEmitter.cpp ARMConstantIslandPass.cpp ARMConstantPoolValue.cpp - ARMInstrInfo.cpp ARMISelDAGToDAG.cpp ARMISelLowering.cpp + ARMInstrInfo.cpp ARMJITInfo.cpp ARMLoadStoreOptimizer.cpp ARMMCAsmInfo.cpp ARMRegisterInfo.cpp ARMSubtarget.cpp ARMTargetMachine.cpp + NEONMoveFix.cpp NEONPreAllocPass.cpp Thumb1InstrInfo.cpp Thumb1RegisterInfo.cpp From kennethuil at gmail.com Mon Nov 2 22:26:45 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Mon, 2 Nov 2009 22:26:45 -0600 Subject: [llvm-commits] [PATCH] Make opt default to not adding a target data string, and update tests In-Reply-To: <06A3392E-15EA-4760-A3D9-B3B9CEDE6F67@apple.com> References: <400d33ea0911021113h7385041fo34c1fafd3ca38b19@mail.gmail.com> <06A3392E-15EA-4760-A3D9-B3B9CEDE6F67@apple.com> Message-ID: <400d33ea0911022026y163086b5h64b7ff0d75a969e3@mail.gmail.com> On Mon, Nov 2, 2009 at 9:16 PM, Dan Gohman wrote: > Hello, > > If I read this correctly, this makes the NoDefaultDataLayout > option unused. Is that right? If so, please remove the option > completely. > > Otherwise, this patch looks fine. Thanks for updating all those tests! > > Dan > Here's the revised patch. -------------- next part -------------- A non-text attachment was scrubbed... Name: tests-opt2.patch Type: text/x-patch Size: 36572 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091102/1b8ed399/attachment.bin From clattner at apple.com Mon Nov 2 22:29:17 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 2 Nov 2009 20:29:17 -0800 Subject: [llvm-commits] [llvm] r85814 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp In-Reply-To: <200911021851.nA2IpTYX014735@zion.cs.uiuc.edu> References: <200911021851.nA2IpTYX014735@zion.cs.uiuc.edu> Message-ID: On Nov 2, 2009, at 10:51 AM, Victor Hernandez wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=85814&view=rev > Log: > Set bit instead of calling pow() to compute 2 << n Thanks Victor, > +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Mon Nov 2 12:51:28 > 2009 > @@ -16,6 +16,7 @@ > #include "llvm/Constants.h" > #include "llvm/Instructions.h" > #include "llvm/Module.h" > +#include "llvm/ADT/APInt.h" You don't need this #include, please remove it. > @@ -156,15 +157,22 @@ > return Op1; > } > if (Opcode == Instruction::Shl) { > - ConstantInt* Op1Int = dyn_cast(Op1); > - if (!Op1Int) return NULL; > - Value* Op1Pow = ConstantInt::get(Op1->getType(), (uint64_t) > - pow(2.0, (double) Op1Int- > >getZExtValue())); > + ConstantInt* Op1CI = dyn_cast(Op1); > + if (!Op1CI) return NULL; > + > + APInt Op1Int = Op1CI->getValue(); > + unsigned Op1Width = Op1Int.getBitWidth(); > + // check for overflow > + if (Op1Int.getActiveBits() > 64 || Op1Int.getZExtValue() > > Op1Width) > + return NULL; If the shift overflows, the original code is undefined. Please just use the APInt::getLimitedValue method (with the bitwidth as the argument) to handle this. You'll end up with much more elegant code. Finally, please use: ConstantInt *Op1CI instead of: ConstantInt* Op1CI With Op1CI and many other variables in this file. Thanks, -Chris > + Value* Op1Pow = ConstantInt::get(Context, > + APInt(Op1Width, 0).set > (Op1Int.getZExtValue())); > + > if (Op0 == ElementSize || (FoldedElementSize && Op0 == > FoldedElementSize)) > // ArraySize << log2(ElementSize) > return Op1Pow; > if (Op1Pow == ElementSize || > - (FoldedElementSize && Op1Pow == FoldedElementSize)) > + (FoldedElementSize && Op1Pow == FoldedElementSize)) > // ElementSize << log2(ArraySize) > return Op0; > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Mon Nov 2 22:59:23 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 02 Nov 2009 20:59:23 -0800 Subject: [llvm-commits] [PATCH] Make opt default to not adding a target data string, and update tests In-Reply-To: <400d33ea0911022026y163086b5h64b7ff0d75a969e3@mail.gmail.com> References: <400d33ea0911021113h7385041fo34c1fafd3ca38b19@mail.gmail.com> <06A3392E-15EA-4760-A3D9-B3B9CEDE6F67@apple.com> <400d33ea0911022026y163086b5h64b7ff0d75a969e3@mail.gmail.com> Message-ID: Looks good; please apply. Thanks! Dan On Nov 2, 2009, at 8:26 PM, Kenneth Uildriks wrote: > On Mon, Nov 2, 2009 at 9:16 PM, Dan Gohman wrote: >> Hello, >> >> If I read this correctly, this makes the NoDefaultDataLayout >> option unused. Is that right? If so, please remove the option >> completely. >> >> Otherwise, this patch looks fine. Thanks for updating all those >> tests! >> >> Dan >> > > Here's the revised patch. > From sabre at nondot.org Mon Nov 2 23:33:46 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 05:33:46 -0000 Subject: [llvm-commits] [llvm] r85863 - /llvm/trunk/lib/Transforms/Utils/Local.cpp Message-ID: <200911030533.nA35XklX009860@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 23:33:46 2009 New Revision: 85863 URL: http://llvm.org/viewvc/llvm-project?rev=85863&view=rev Log: remove a isFreeCall check: it is a callinst that can write to memory already. Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=85863&r1=85862&r2=85863&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon Nov 2 23:33:46 2009 @@ -24,7 +24,6 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/DebugInfo.h" -#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/GetElementPtrTypeIterator.h" @@ -60,8 +59,8 @@ // If we see a free or a call which may write to memory (i.e. which might do // a free) the pointer could be marked invalid. - if (isFreeCall(BBI) || (isa(BBI) && BBI->mayWriteToMemory() && - !isa(BBI))) + if (isa(BBI) && BBI->mayWriteToMemory() && + !isa(BBI)) return false; if (LoadInst *LI = dyn_cast(BBI)) { From sabre at nondot.org Mon Nov 2 23:34:52 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 05:34:52 -0000 Subject: [llvm-commits] [llvm] r85865 - /llvm/trunk/lib/Analysis/CaptureTracking.cpp Message-ID: <200911030534.nA35Yqj5009914@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 23:34:51 2009 New Revision: 85865 URL: http://llvm.org/viewvc/llvm-project?rev=85865&view=rev Log: remove a check of isFreeCall: the argument to free is already nocapture so the generic call code works fine. Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=85865&r1=85864&r2=85865&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Mon Nov 2 23:34:51 2009 @@ -17,7 +17,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CaptureTracking.h" -#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Instructions.h" #include "llvm/Value.h" #include "llvm/ADT/SmallSet.h" @@ -49,9 +48,6 @@ switch (I->getOpcode()) { case Instruction::Call: - if (isFreeCall(I)) - // Freeing a pointer does not cause it to be captured. - break; case Instruction::Invoke: { CallSite CS = CallSite::get(I); // Not captured if the callee is readonly, doesn't return a copy through From sabre at nondot.org Mon Nov 2 23:35:19 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 05:35:19 -0000 Subject: [llvm-commits] [llvm] r85866 - /llvm/trunk/lib/Analysis/AliasSetTracker.cpp Message-ID: <200911030535.nA35ZJHk009942@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 2 23:35:19 2009 New Revision: 85866 URL: http://llvm.org/viewvc/llvm-project?rev=85866&view=rev Log: remove unneeded checks of isFreeCall Modified: llvm/trunk/lib/Analysis/AliasSetTracker.cpp Modified: llvm/trunk/lib/Analysis/AliasSetTracker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasSetTracker.cpp?rev=85866&r1=85865&r2=85866&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/AliasSetTracker.cpp (original) +++ llvm/trunk/lib/Analysis/AliasSetTracker.cpp Mon Nov 2 23:35:19 2009 @@ -13,7 +13,6 @@ #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" @@ -305,13 +304,6 @@ bool AliasSetTracker::add(CallSite CS) { - Instruction* Inst = CS.getInstruction(); - if (isFreeCall(Inst)) { - bool NewPtr; - addPointer(Inst->getOperand(1), ~0, AliasSet::Mods, NewPtr); - return NewPtr; - } - if (isa(CS.getInstruction())) return true; // Ignore DbgInfo Intrinsics. if (AA.doesNotAccessMemory(CS)) @@ -435,14 +427,6 @@ } bool AliasSetTracker::remove(CallSite CS) { - Instruction* Inst = CS.getInstruction(); - if (isFreeCall(Inst)) { - AliasSet *AS = findAliasSetForPointer(Inst->getOperand(1), ~0); - if (!AS) return false; - remove(*AS); - return true; - } - if (AA.doesNotAccessMemory(CS)) return false; // doesn't alias anything From clattner at apple.com Mon Nov 2 23:36:14 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 2 Nov 2009 21:36:14 -0800 Subject: [llvm-commits] [llvm] r85176 - in /llvm/trunk: examples/BrainF/ include/llvm-c/ include/llvm/ include/llvm/Analysis/ include/llvm/Support/ include/llvm/Transforms/ lib/Analysis/ lib/Analysis/IPA/ lib/AsmParser/ lib/Bitcode/Writer/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/Interpreter/ lib/Target/CBackend/ lib/Target/CppBackend/ lib/Target/MSIL/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ In-Reply-To: <200910262343.n9QNhpYj012068@zion.cs.uiuc.edu> References: <200910262343.n9QNhpYj012068@zion.cs.uiuc.edu> Message-ID: On Oct 26, 2009, at 4:43 PM, Victor Hernandez wrote: > Author: hernande > Date: Mon Oct 26 18:43:48 2009 > New Revision: 85176 > > URL: http://llvm.org/viewvc/llvm-project?rev=85176&view=rev > Log: > Remove FreeInst. > Remove LowerAllocations pass. > Update some more passes to treate free calls just like they were > treating FreeInst. Thanks Victor, > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/VMCore/Instruction.cpp (original) > +// Code here matches isFreeCall from MallocHelper, which is not in > VMCore. > +static bool isFreeCall(const Value* I) { > + const CallInst *CI = dyn_cast(I); > + if (!CI) > + return false; > + > + const Module* M = CI->getParent()->getParent()->getParent(); > + Function *FreeFunc = M->getFunction("free"); > + > + if (CI->getOperand(0) != FreeFunc) > + return false; Please use something like this, which would be much more efficient: const CallInst *CI = dyn_cast(I); if (!CI) return false; Function *Callee = CI->getCalledFunction(); if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "free") return false; > + > + // Check free prototype. > + // FIXME: workaround for PR5130, this will be obsolete when a > nobuiltin > + // attribute will exist. > + const FunctionType *FTy = FreeFunc->getFunctionType(); > + if (FTy->getReturnType() != Type::getVoidTy(M->getContext())) Use ->isVoidTy() instead of comparing against a newly constructed type. > /// mayReadFromMemory - Return true if this instruction may read > memory. > /// > bool Instruction::mayReadFromMemory() const { > switch (getOpcode()) { > default: return false; > - case Instruction::Free: > case Instruction::VAArg: > case Instruction::Load: > return true; > case Instruction::Call: > + if (isFreeCall(this)) > + return true; > return !cast(this)->doesNotAccessMemory(); This call to isFreeCall isn't needed because the existing code works for it. > case Instruction::Invoke: > return !cast(this)->doesNotAccessMemory(); > @@ -326,11 +352,12 @@ > bool Instruction::mayWriteToMemory() const { > switch (getOpcode()) { > default: return false; > - case Instruction::Free: > case Instruction::Store: > case Instruction::VAArg: > return true; > case Instruction::Call: > + if (isFreeCall(this)) > + return true; > return !cast(this)->onlyReadsMemory(); Likewise. I removed some other ones that are not needed. -Chris From evan.cheng at apple.com Mon Nov 2 23:50:58 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 05:50:58 -0000 Subject: [llvm-commits] [llvm] r85869 - /llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Message-ID: <200911030550.nA35owXu010430@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 2 23:50:57 2009 New Revision: 85869 URL: http://llvm.org/viewvc/llvm-project?rev=85869&view=rev Log: Add QPR_8 as a superreg class of SPR_8 and DPR_8. Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=85869&r1=85868&r2=85869&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Mon Nov 2 23:50:57 2009 @@ -357,6 +357,13 @@ let SubRegClassList = [SPR, SPR, SPR, SPR, DPR_VFP2, DPR_VFP2]; } +// Subset of QPR that have DPR_8 and SPR_8 subregs. +def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], + 128, + [Q0, Q1, Q2, Q3]> { + let SubRegClassList = [SPR_8, SPR_8, SPR_8, SPR_8, DPR_8, DPR_8]; +} + // Condition code registers. def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>; From evan.cheng at apple.com Mon Nov 2 23:51:39 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 05:51:39 -0000 Subject: [llvm-commits] [llvm] r85870 - /llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Message-ID: <200911030551.nA35pdm3010458@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 2 23:51:39 2009 New Revision: 85870 URL: http://llvm.org/viewvc/llvm-project?rev=85870&view=rev Log: Clean up copyRegToReg. Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=85870&r1=85869&r2=85870&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Mon Nov 2 23:51:39 2009 @@ -620,28 +620,12 @@ if (I != MBB.end()) DL = I->getDebugLoc(); if (DestRC != SrcRC) { - // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies - // Allow QPR / QPR_VFP2 cross-class copies - if (DestRC == ARM::DPRRegisterClass) { - if (SrcRC == ARM::DPR_VFP2RegisterClass || - SrcRC == ARM::DPR_8RegisterClass) { - } else - return false; - } else if (DestRC == ARM::DPR_VFP2RegisterClass) { - if (SrcRC == ARM::DPRRegisterClass || - SrcRC == ARM::DPR_8RegisterClass) { - } else - return false; - } else if (DestRC == ARM::DPR_8RegisterClass) { - if (SrcRC == ARM::DPRRegisterClass || - SrcRC == ARM::DPR_VFP2RegisterClass) { - } else - return false; - } else if ((DestRC == ARM::QPRRegisterClass && - SrcRC == ARM::QPR_VFP2RegisterClass) || - (DestRC == ARM::QPR_VFP2RegisterClass && - SrcRC == ARM::QPRRegisterClass)) { - } else + if (DestRC->getSize() != SrcRC->getSize()) + return false; + + // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies. + // Allow QPR / QPR_VFP2 / QPR_8 cross-class copies. + if (DestRC->getSize() != 8 && DestRC->getSize() != 16) return false; } @@ -651,17 +635,18 @@ } else if (DestRC == ARM::SPRRegisterClass) { AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg) .addReg(SrcReg)); + } else if (DestRC == ARM::DPRRegisterClass) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg) + .addReg(SrcReg)); } else if (DestRC == ARM::DPR_VFP2RegisterClass || DestRC == ARM::DPR_8RegisterClass || SrcRC == ARM::DPR_VFP2RegisterClass || SrcRC == ARM::DPR_8RegisterClass) { // Always use neon reg-reg move if source or dest is NEON-only regclass. BuildMI(MBB, I, DL, get(ARM::VMOVD), DestReg).addReg(SrcReg); - } else if (DestRC == ARM::DPRRegisterClass) { - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg) - .addReg(SrcReg)); } else if (DestRC == ARM::QPRRegisterClass || - DestRC == ARM::QPR_VFP2RegisterClass) { + DestRC == ARM::QPR_VFP2RegisterClass || + DestRC == ARM::QPR_8RegisterClass) { BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); } else { return false; @@ -736,7 +721,8 @@ .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); } else { assert((RC == ARM::QPRRegisterClass || - RC == ARM::QPR_VFP2RegisterClass) && "Unknown regclass!"); + RC == ARM::QPR_VFP2RegisterClass || + RC == ARM::QPR_8RegisterClass) && "Unknown regclass!"); // FIXME: Neon instructions should support predicates BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg).addFrameIndex(FI).addImm(0). addMemOperand(MMO); From evan.cheng at apple.com Mon Nov 2 23:52:54 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 05:52:54 -0000 Subject: [llvm-commits] [llvm] r85871 - in /llvm/trunk: lib/Target/ARM/ARMBaseRegisterInfo.cpp test/CodeGen/ARM/2009-10-02-NEONSubregsBug.ll test/CodeGen/ARM/2009-11-01-NeonMoves.ll test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll test/CodeGen/Thumb2/cross-rc-coalescing-2.ll Message-ID: <200911030552.nA35qsRU010526@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 2 23:52:54 2009 New Revision: 85871 URL: http://llvm.org/viewvc/llvm-project?rev=85871&view=rev Log: Fix PR5367. QPR_8 is the super regclass of DPR_8 and SPR_8. Added: llvm/trunk/test/CodeGen/ARM/2009-10-02-NEONSubregsBug.ll Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=85871&r1=85870&r2=85871&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Mon Nov 2 23:52:54 2009 @@ -257,7 +257,6 @@ ARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned SubIdx) const { -#if 0 switch (SubIdx) { default: return 0; case 1: @@ -266,19 +265,27 @@ case 4: // S sub-registers. if (A->getSize() == 8) { + if (B == &ARM::SPR_8RegClass) + return &ARM::DPR_8RegClass; + assert(B == &ARM::SPRRegClass && "Expecting SPR register class!"); if (A == &ARM::DPR_8RegClass) return A; return &ARM::DPR_VFP2RegClass; } assert(A->getSize() == 16 && "Expecting a Q register class!"); + if (B == &ARM::SPR_8RegClass) + return &ARM::QPR_8RegClass; return &ARM::QPR_VFP2RegClass; case 5: case 6: // D sub-registers. + if (B == &ARM::DPR_VFP2RegClass) + return &ARM::QPR_VFP2RegClass; + if (B == &ARM::DPR_8RegClass) + return &ARM::QPR_8RegClass; return A; } -#endif return 0; } Added: llvm/trunk/test/CodeGen/ARM/2009-10-02-NEONSubregsBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-10-02-NEONSubregsBug.ll?rev=85871&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2009-10-02-NEONSubregsBug.ll (added) +++ llvm/trunk/test/CodeGen/ARM/2009-10-02-NEONSubregsBug.ll Mon Nov 2 23:52:54 2009 @@ -0,0 +1,63 @@ +; RUN: llc -mtriple=armv7-eabi -mcpu=cortex-a8 -enable-unsafe-fp-math < %s +; PR5367 + +define arm_aapcs_vfpcc void @_Z27Benchmark_SceDualQuaternionPvm(i8* nocapture %pBuffer, i32 %numItems) nounwind { +entry: + br i1 undef, label %return, label %bb + +bb: ; preds = %bb, %entry + %0 = load float* undef, align 4 ; [#uses=1] + %1 = load float* null, align 4 ; [#uses=1] + %2 = insertelement <4 x float> undef, float undef, i32 1 ; <<4 x float>> [#uses=1] + %3 = insertelement <4 x float> %2, float %1, i32 2 ; <<4 x float>> [#uses=2] + %4 = insertelement <4 x float> undef, float %0, i32 2 ; <<4 x float>> [#uses=1] + %5 = insertelement <4 x float> %4, float 0.000000e+00, i32 3 ; <<4 x float>> [#uses=4] + %6 = fsub <4 x float> zeroinitializer, %3 ; <<4 x float>> [#uses=1] + %7 = shufflevector <4 x float> %6, <4 x float> undef, <4 x i32> zeroinitializer ; <<4 x float>> [#uses=2] + %8 = shufflevector <4 x float> %5, <4 x float> undef, <2 x i32> ; <<2 x float>> [#uses=1] + %9 = shufflevector <2 x float> %8, <2 x float> undef, <4 x i32> ; <<4 x float>> [#uses=2] + %10 = fmul <4 x float> %7, %9 ; <<4 x float>> [#uses=1] + %11 = shufflevector <4 x float> zeroinitializer, <4 x float> undef, <4 x i32> zeroinitializer ; <<4 x float>> [#uses=1] + %12 = shufflevector <4 x float> %5, <4 x float> undef, <2 x i32> ; <<2 x float>> [#uses=2] + %13 = shufflevector <2 x float> %12, <2 x float> undef, <4 x i32> zeroinitializer ; <<4 x float>> [#uses=1] + %14 = fmul <4 x float> %11, %13 ; <<4 x float>> [#uses=1] + %15 = fadd <4 x float> %10, %14 ; <<4 x float>> [#uses=1] + %16 = shufflevector <2 x float> %12, <2 x float> undef, <4 x i32> ; <<4 x float>> [#uses=1] + %17 = fadd <4 x float> %15, zeroinitializer ; <<4 x float>> [#uses=1] + %18 = shufflevector <4 x float> %17, <4 x float> zeroinitializer, <4 x i32> ; <<4 x float>> [#uses=1] + %19 = fmul <4 x float> %7, %16 ; <<4 x float>> [#uses=1] + %20 = fadd <4 x float> %19, zeroinitializer ; <<4 x float>> [#uses=1] + %21 = shufflevector <4 x float> %3, <4 x float> undef, <4 x i32> ; <<4 x float>> [#uses=1] + %22 = shufflevector <4 x float> %21, <4 x float> undef, <4 x i32> zeroinitializer ; <<4 x float>> [#uses=1] + %23 = fmul <4 x float> %22, %9 ; <<4 x float>> [#uses=1] + %24 = fadd <4 x float> %20, %23 ; <<4 x float>> [#uses=1] + %25 = shufflevector <4 x float> %18, <4 x float> %24, <4 x i32> ; <<4 x float>> [#uses=1] + %26 = shufflevector <4 x float> %25, <4 x float> undef, <4 x i32> ; <<4 x float>> [#uses=1] + %27 = fmul <4 x float> %26, ; <<4 x float>> [#uses=1] + %28 = fsub <4 x float> , %5 ; <<4 x float>> [#uses=1] + %29 = tail call <4 x float> @llvm.arm.neon.vrecpe.v4f32(<4 x float> zeroinitializer) nounwind ; <<4 x float>> [#uses=1] + %30 = fmul <4 x float> zeroinitializer, %29 ; <<4 x float>> [#uses=1] + %31 = fmul <4 x float> %30, ; <<4 x float>> [#uses=1] + %32 = shufflevector <4 x float> %27, <4 x float> undef, <4 x i32> zeroinitializer ; <<4 x float>> [#uses=1] + %33 = shufflevector <4 x float> %28, <4 x float> undef, <2 x i32> ; <<2 x float>> [#uses=1] + %34 = shufflevector <2 x float> %33, <2 x float> undef, <4 x i32> ; <<4 x float>> [#uses=1] + %35 = fmul <4 x float> %32, %34 ; <<4 x float>> [#uses=1] + %36 = fadd <4 x float> %35, zeroinitializer ; <<4 x float>> [#uses=1] + %37 = shufflevector <4 x float> %5, <4 x float> undef, <4 x i32> ; <<4 x float>> [#uses=1] + %38 = shufflevector <4 x float> %37, <4 x float> undef, <4 x i32> zeroinitializer ; <<4 x float>> [#uses=1] + %39 = fmul <4 x float> zeroinitializer, %38 ; <<4 x float>> [#uses=1] + %40 = fadd <4 x float> %36, %39 ; <<4 x float>> [#uses=1] + %41 = fadd <4 x float> %40, zeroinitializer ; <<4 x float>> [#uses=1] + %42 = shufflevector <4 x float> undef, <4 x float> %41, <4 x i32> ; <<4 x float>> [#uses=1] + %43 = fmul <4 x float> %42, %31 ; <<4 x float>> [#uses=1] + store float undef, float* undef, align 4 + store float 0.000000e+00, float* null, align 4 + %44 = extractelement <4 x float> %43, i32 1 ; [#uses=1] + store float %44, float* undef, align 4 + br i1 undef, label %return, label %bb + +return: ; preds = %bb, %entry + ret void +} + +declare <4 x float> @llvm.arm.neon.vrecpe.v4f32(<4 x float>) nounwind readnone Modified: llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll?rev=85871&r1=85870&r2=85871&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2009-11-01-NeonMoves.ll Mon Nov 2 23:52:54 2009 @@ -1,4 +1,4 @@ -; RUN: llc -mcpu=cortex-a8 < %s | grep vmov | count 2 +; RUN: llc -mcpu=cortex-a8 < %s | grep vmov | count 1 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" target triple = "armv7-eabi" Modified: llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll?rev=85871&r1=85870&r2=85871&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll Mon Nov 2 23:52:54 2009 @@ -1,7 +1,6 @@ ; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mattr=+neon -arm-use-neon-fp ; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mattr=+neon -arm-use-neon-fp | not grep fcpys ; rdar://7117307 -; XFAIL: * %struct.Hosp = type { i32, i32, i32, %struct.List, %struct.List, %struct.List, %struct.List } %struct.List = type { %struct.List*, %struct.Patient*, %struct.List* } Modified: llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll?rev=85871&r1=85870&r2=85871&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll Mon Nov 2 23:52:54 2009 @@ -1,5 +1,4 @@ ; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | grep fcpys | count 4 -; XFAIL: * define arm_apcscc void @fht(float* nocapture %fz, i16 signext %n) nounwind { entry: From jyasskin at google.com Tue Nov 3 00:29:37 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 03 Nov 2009 06:29:37 -0000 Subject: [llvm-commits] [llvm] r85873 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200911030629.nA36Tb2S011758@zion.cs.uiuc.edu> Author: jyasskin Date: Tue Nov 3 00:29:36 2009 New Revision: 85873 URL: http://llvm.org/viewvc/llvm-project?rev=85873&view=rev Log: Fix a funky "declared with greater visibility than the type of its field" warning from gcc by removing VISIBILITY_HIDDEN attributes. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=85873&r1=85872&r2=85873&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Nov 3 00:29:36 2009 @@ -124,7 +124,7 @@ //===----------------------------------------------------------------------===// /// DbgVariable - This class is used to track local variable information. /// -class VISIBILITY_HIDDEN DbgVariable { +class DbgVariable { DIVariable Var; // Variable Descriptor. unsigned FrameIndex; // Variable frame index. bool InlinedFnVar; // Variable for an inlined function. @@ -142,7 +142,7 @@ /// DbgScope - This class is used to track scope information. /// class DbgConcreteScope; -class VISIBILITY_HIDDEN DbgScope { +class DbgScope { DbgScope *Parent; // Parent to this scope. DIDescriptor Desc; // Debug info descriptor for scope. // FIXME use WeakVH for Desc. From bob.wilson at apple.com Tue Nov 3 00:29:56 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 03 Nov 2009 06:29:56 -0000 Subject: [llvm-commits] [llvm] r85874 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Message-ID: <200911030629.nA36TuQg011780@zion.cs.uiuc.edu> Author: bwilson Date: Tue Nov 3 00:29:56 2009 New Revision: 85874 URL: http://llvm.org/viewvc/llvm-project?rev=85874&view=rev Log: For Thumb indirect branches, use "mov pc, reg" which does not switch between ARM/Thumb modes and does not require the low bit of the target address to be set for Thumb. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85874&r1=85873&r2=85874&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov 3 00:29:56 2009 @@ -182,7 +182,7 @@ // Indirect branches let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { - def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "bx\t$dst", + def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst", [(brind GPR:$dst)]>; } From evan.cheng at apple.com Tue Nov 3 01:08:08 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 07:08:08 -0000 Subject: [llvm-commits] [llvm] r85878 - /llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Message-ID: <200911030708.nA3788L7013010@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 01:08:08 2009 New Revision: 85878 URL: http://llvm.org/viewvc/llvm-project?rev=85878&view=rev Log: Trim unnecessary include. Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=85878&r1=85877&r2=85878&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Tue Nov 3 01:08:08 2009 @@ -23,7 +23,6 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineMemOperand.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/CommandLine.h" From daniel at zuster.org Tue Nov 3 01:26:38 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 03 Nov 2009 07:26:38 -0000 Subject: [llvm-commits] [llvm] r85882 - /llvm/trunk/utils/lit/TestRunner.py Message-ID: <200911030726.nA37Qc82013917@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 3 01:26:38 2009 New Revision: 85882 URL: http://llvm.org/viewvc/llvm-project?rev=85882&view=rev Log: lit: Update Clang's test style to use XFAIL: and XTARGET: lines that match LLVM's tests. Modified: llvm/trunk/utils/lit/TestRunner.py Modified: llvm/trunk/utils/lit/TestRunner.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/TestRunner.py?rev=85882&r1=85881&r2=85882&view=diff ============================================================================== --- llvm/trunk/utils/lit/TestRunner.py (original) +++ llvm/trunk/utils/lit/TestRunner.py Tue Nov 3 01:26:38 2009 @@ -333,7 +333,24 @@ return executeCommand(command, cwd=cwd, env=test.config.environment) -def parseIntegratedTestScript(test, xfailHasColon, requireAndAnd): +def isExpectedFail(xfails, xtargets, target_triple): + # Check if any xfail matches this target. + for item in xfails: + if item == '*' or item in target_triple: + break + else: + return False + + # If so, see if it is expected to pass on this target. + # + # FIXME: Rename XTARGET to something that makes sense, like XPASS. + for item in xtargets: + if item == '*' or item in target_triple: + return False + + return True + +def parseIntegratedTestScript(test, requireAndAnd): """parseIntegratedTestScript - Scan an LLVM/Clang style integrated test script and extract the lines to 'RUN' as well as 'XFAIL' and 'XTARGET' information. The RUN lines also will have variable substitution performed. @@ -377,12 +394,9 @@ script[-1] = script[-1][:-1] + ln else: script.append(ln) - elif xfailHasColon and 'XFAIL:' in ln: + elif 'XFAIL:' in ln: items = ln[ln.index('XFAIL:') + 6:].split(',') xfails.extend([s.strip() for s in items]) - elif not xfailHasColon and 'XFAIL' in ln: - items = ln[ln.index('XFAIL') + 5:].split(',') - xfails.extend([s.strip() for s in items]) elif 'XTARGET:' in ln: items = ln[ln.index('XTARGET:') + 8:].split(',') xtargets.extend([s.strip() for s in items]) @@ -421,7 +435,8 @@ # Strip off '&&' script[i] = ln[:-2] - return script,xfails,xtargets,tmpBase,execdir + isXFail = isExpectedFail(xfails, xtargets, test.suite.config.target_triple) + return script,isXFail,tmpBase,execdir def formatTestOutput(status, out, err, exitCode, script): output = StringIO.StringIO() @@ -444,11 +459,11 @@ if test.config.unsupported: return (Test.UNSUPPORTED, 'Test is unsupported') - res = parseIntegratedTestScript(test, True, False) + res = parseIntegratedTestScript(test, False) if len(res) == 2: return res - script, xfails, xtargets, tmpBase, execdir = res + script, isXFail, tmpBase, execdir = res if litConfig.noExecute: return (Test.PASS, '') @@ -460,19 +475,6 @@ if len(res) == 2: return res - isXFail = False - for item in xfails: - if item == '*' or item in test.suite.config.target_triple: - isXFail = True - break - - # If this is XFAIL, see if it is expected to pass on this target. - if isXFail: - for item in xtargets: - if item == '*' or item in test.suite.config.target_triple: - isXFail = False - break - out,err,exitCode = res if isXFail: ok = exitCode != 0 @@ -490,11 +492,11 @@ if test.config.unsupported: return (Test.UNSUPPORTED, 'Test is unsupported') - res = parseIntegratedTestScript(test, False, requireAndAnd) + res = parseIntegratedTestScript(test, requireAndAnd) if len(res) == 2: return res - script, xfails, xtargets, tmpBase, execdir = res + script, isXFail, tmpBase, execdir = res if litConfig.noExecute: return (Test.PASS, '') @@ -510,7 +512,7 @@ return res out,err,exitCode = res - if xfails: + if isXFail: ok = exitCode != 0 status = (Test.XPASS, Test.XFAIL)[ok] else: From daniel at zuster.org Tue Nov 3 01:49:22 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 03 Nov 2009 07:49:22 -0000 Subject: [llvm-commits] [llvm] r85884 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <200911030749.nA37nM1l014684@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 3 01:49:22 2009 New Revision: 85884 URL: http://llvm.org/viewvc/llvm-project?rev=85884&view=rev Log: Speculatively redisable IPSCCP, I think its still breaking things. 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=85884&r1=85883&r2=85884&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Tue Nov 3 01:49:22 2009 @@ -99,7 +99,8 @@ if (UnitAtATime) { PM->add(createGlobalOptimizerPass()); // Optimize out global vars - PM->add(createIPSCCPPass()); // IP SCCP + PM->add(createIPConstantPropagationPass()); // IP CP +// PM->add(createIPSCCPPass()); // IP SCCP PM->add(createDeadArgEliminationPass()); // Dead argument elimination } PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE From baldrick at free.fr Tue Nov 3 03:40:08 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 03 Nov 2009 09:40:08 -0000 Subject: [llvm-commits] [llvm] r85893 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <200911030940.nA39e9ZV000318@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 3 03:40:08 2009 New Revision: 85893 URL: http://llvm.org/viewvc/llvm-project?rev=85893&view=rev Log: Run the functionattrs pass after the inliner, and not before. This makes both logical sense (see below) and increases the number of functions marked readnone/readonly by about 1-2% in practice. The number of functions marked nocapture goes up by about 5-10%. The reason it makes sense is shown by the following example: if you run -functionattrs -inline on it, then no attributes are assigned. But if you instead run -inline -functionattrs then @f is marked readnone because the simplifications produced by the inliner eliminate the store. @x = external global i32 define void @w(i1 %b) { br i1 %b, label %write, label %return write: store i32 1, i32 *@x br label %return return: ret void } define void @f() { call void @w(i1 0) ret void } 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=85893&r1=85892&r2=85893&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Tue Nov 3 03:40:08 2009 @@ -107,13 +107,12 @@ PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE // Start of CallGraph SCC passes. - if (UnitAtATime) { - if (HaveExceptions) - PM->add(createPruneEHPass()); // Remove dead EH info - PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs - } + if (UnitAtATime && HaveExceptions) + PM->add(createPruneEHPass()); // Remove dead EH info if (InliningPass) PM->add(InliningPass); + if (UnitAtATime) + PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs if (OptimizationLevel > 2) PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args From baldrick at free.fr Tue Nov 3 05:11:09 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 03 Nov 2009 12:11:09 +0100 Subject: [llvm-commits] [llvm-gcc-4.2] r85835 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h In-Reply-To: <200911022244.nA2MiNFd026188@zion.cs.uiuc.edu> References: <200911022244.nA2MiNFd026188@zion.cs.uiuc.edu> Message-ID: <4AF00FCD.7030508@free.fr> Hi Bob, thanks for doing this. > +Constant *TreeToLLVM::EmitLV_LABEL_DECL(tree exp) { > + // GCC kindly diverts labels for unreachable basic blocks to reachable blocks, > + // so we are not obliged to output unreachable blocks even if the original > + // code took the address of one. this comment is only really relevant to dragonegg, which outputs basic basic blocks in dom order (in order to translate phi nodes), and as a side-effect only outputs reachable basic blocks. Ciao, Duncan. From chandlerc at google.com Tue Nov 3 05:27:55 2009 From: chandlerc at google.com (Chandler Carruth) Date: Tue, 3 Nov 2009 03:27:55 -0800 Subject: [llvm-commits] PATCH: Use absolute paths rather than canonical paths in lit Message-ID: <74c447500911030327n7b98266ev8894339f2f0530b3@mail.gmail.com> Hey Daniel, This patch switches to use absolute paths instead of canonical paths in lit's test suite walking. Because the walking pattern is sensitive to file layout and walks up the paths to find test suite definitions, it is useful to allow that tree to be synthesized using symlinks. Seem reasonable? -------------- next part -------------- A non-text attachment was scrubbed... Name: no-realpath.patch Type: application/octet-stream Size: 986 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091103/8e164c30/attachment.obj From benny.kra at googlemail.com Tue Nov 3 06:52:51 2009 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 03 Nov 2009 12:52:51 -0000 Subject: [llvm-commits] [llvm] r85896 - /llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp Message-ID: <200911031252.nA3CqpG3008133@zion.cs.uiuc.edu> Author: d0k Date: Tue Nov 3 06:52:50 2009 New Revision: 85896 URL: http://llvm.org/viewvc/llvm-project?rev=85896&view=rev Log: Eliminate some temporaries. Modified: llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp Modified: llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp?rev=85896&r1=85895&r2=85896&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp Tue Nov 3 06:52:50 2009 @@ -47,9 +47,6 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/VectorExtras.h" -#include "llvm/ADT/SmallVector.h" #include using namespace llvm; @@ -108,7 +105,7 @@ void TransformLongJmpCall(CallInst* Inst); void TransformSetJmpCall(CallInst* Inst); - bool IsTransformableFunction(const std::string& Name); + bool IsTransformableFunction(StringRef Name); public: static char ID; // Pass identification, replacement for typeid LowerSetJmp() : ModulePass(&ID) {} @@ -249,13 +246,8 @@ // "llvm.{setjmp,longjmp}" functions and none of the setjmp/longjmp error // handling functions (beginning with __llvm_sjljeh_...they don't throw // exceptions). -bool LowerSetJmp::IsTransformableFunction(const std::string& Name) { - std::string SJLJEh("__llvm_sjljeh"); - - if (Name.size() > SJLJEh.size()) - return std::string(Name.begin(), Name.begin() + SJLJEh.size()) != SJLJEh; - - return true; +bool LowerSetJmp::IsTransformableFunction(StringRef Name) { + return !Name.startswith("__llvm_sjljeh_"); } // TransformLongJmpCall - Transform a longjmp call into a call to the @@ -263,8 +255,7 @@ // throwing the exception for us. void LowerSetJmp::TransformLongJmpCall(CallInst* Inst) { - const Type* SBPTy = - Type::getInt8PtrTy(Inst->getContext()); + const Type* SBPTy = Type::getInt8PtrTy(Inst->getContext()); // Create the call to "__llvm_sjljeh_throw_longjmp". This takes the // same parameters as "longjmp", except that the buffer is cast to a @@ -272,10 +263,8 @@ // Inst's uses and doesn't get a name. CastInst* CI = new BitCastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst); - SmallVector Args; - Args.push_back(CI); - Args.push_back(Inst->getOperand(2)); - CallInst::Create(ThrowLongJmp, Args.begin(), Args.end(), "", Inst); + Value *Args[] = { CI, Inst->getOperand(2) }; + CallInst::Create(ThrowLongJmp, Args, Args + 2, "", Inst); SwitchValuePair& SVP = SwitchValMap[Inst->getParent()->getParent()]; @@ -390,11 +379,11 @@ Type::getInt8PtrTy(Inst->getContext()); CastInst* BufPtr = new BitCastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst); - std::vector Args = - make_vector(GetSetJmpMap(Func), BufPtr, - ConstantInt::get(Type::getInt32Ty(Inst->getContext()), - SetJmpIDMap[Func]++), 0); - CallInst::Create(AddSJToMap, Args.begin(), Args.end(), "", Inst); + Value *Args[] = { + GetSetJmpMap(Func), BufPtr, + ConstantInt::get(Type::getInt32Ty(Inst->getContext()), SetJmpIDMap[Func]++) + }; + CallInst::Create(AddSJToMap, Args, Args + 3, "", Inst); // We are guaranteed that there are no values live across basic blocks // (because we are "not in SSA form" yet), but there can still be values live From baldrick at free.fr Tue Nov 3 07:26:22 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 03 Nov 2009 13:26:22 -0000 Subject: [llvm-commits] [dragonegg] r85897 - /dragonegg/trunk/gcc-patches/i386_static.diff Message-ID: <200911031326.nA3DQM8T009486@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 3 07:26:21 2009 New Revision: 85897 URL: http://llvm.org/viewvc/llvm-project?rev=85897&view=rev Log: Add prototypes, so that gcc successfully bootstraps with the patch applied. Modified: dragonegg/trunk/gcc-patches/i386_static.diff Modified: dragonegg/trunk/gcc-patches/i386_static.diff URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/gcc-patches/i386_static.diff?rev=85897&r1=85896&r2=85897&view=diff ============================================================================== --- dragonegg/trunk/gcc-patches/i386_static.diff (original) +++ dragonegg/trunk/gcc-patches/i386_static.diff Tue Nov 3 07:26:21 2009 @@ -1,39 +1,45 @@ Index: mainline/gcc/config/i386/i386.c =================================================================== ---- mainline.orig/gcc/config/i386/i386.c 2009-09-28 10:25:38.639572451 +0200 -+++ mainline/gcc/config/i386/i386.c 2009-09-28 10:58:43.498571902 +0200 -@@ -4898,7 +4898,7 @@ +--- mainline.orig/gcc/config/i386/i386.c 2009-11-02 17:21:03.257325701 +0100 ++++ mainline/gcc/config/i386/i386.c 2009-11-03 13:26:05.384538824 +0100 +@@ -4943,7 +4943,8 @@ case, we return the original mode and warn ABI change if CUM isn't NULL. */ -static enum machine_mode ++extern enum machine_mode type_natural_mode (const_tree, CUMULATIVE_ARGS *); +enum machine_mode type_natural_mode (const_tree type, CUMULATIVE_ARGS *cum) { enum machine_mode mode = TYPE_MODE (type); -@@ -5029,7 +5029,7 @@ +@@ -5074,7 +5075,9 @@ See the x86-64 PS ABI for details. */ -static int ++extern int classify_argument (enum machine_mode, const_tree, ++ enum x86_64_reg_class [MAX_CLASSES], int); +int classify_argument (enum machine_mode mode, const_tree type, enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset) { -@@ -5409,7 +5409,7 @@ +@@ -5454,7 +5457,9 @@ /* Examine the argument and return set number of register required in each class. Return 0 iff parameter should be passed in memory. */ -static int ++extern int examine_argument (enum machine_mode, const_tree, int, ++ int *, int *); +int examine_argument (enum machine_mode mode, const_tree type, int in_return, int *int_nregs, int *sse_nregs) { -@@ -6089,7 +6089,7 @@ +@@ -6134,7 +6139,8 @@ /* Return true when TYPE should be 128bit aligned for 32bit argument passing ABI. */ -static bool ++extern bool contains_aligned_value_p (tree); +bool contains_aligned_value_p (tree type) { From criswell at cs.uiuc.edu Tue Nov 3 09:16:49 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 09:16:49 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/Azulmedia.css people.html pubs.html links.html index.html Message-ID: <200911031516.nA3FGnga016706@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: Azulmedia.css added (r1.1) people.html added (r1.1) pubs.html added (r1.1) links.html added (r1.1) index.html updated: 1.25 -> 1.26 --- Log message: Adding new SAFECode web site. --- Diffs of the changes: (+862 -115) Azulmedia.css | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 232 +++++++++++++++++++++-------------------- links.html | 103 ++++++++++++++++++ people.html | 140 +++++++++++++++++++++++++ pubs.html | 180 ++++++++++++++++++++++++++++++++ 5 files changed, 862 insertions(+), 115 deletions(-) Index: llvm-www/safecode/Azulmedia.css diff -c /dev/null llvm-www/safecode/Azulmedia.css:1.1 *** /dev/null Tue Nov 3 09:16:08 2009 --- llvm-www/safecode/Azulmedia.css Tue Nov 3 09:15:58 2009 *************** *** 0 **** --- 1,322 ---- + /******************************************** + AUTHOR: Erwin Aligam + WEBSITE: http://www.styleshout.com/ + TEMPLATE NAME: Azulmedia + TEMPLATE CODE: S-0008 + VERSION: 2.0 + *******************************************/ + + /******************************************** + HTML ELEMENTS + ********************************************/ + + /* top elements */ + * { + padding: 0; margin: 0; + } + body { + margin: 0; padding: 0; + font: normal .80em/1.6em Verdana, Tahoma, sans-serif; + color: #BDBDBD; + background: #000; + text-align: center; + } + /* links */ + a { + color: #FFF; + background-color: inherit; + text-decoration: none; + } + a:hover { + color: #FFF; + background-color: inherit; + text-decoration: underline; + } + + /* headers */ + h1, h2, h3 { + font: normal 1.3em 'Trebuchet MS', Arial, Sans-serif; + color: #FFF; + } + h1 { font-size: 1.6em; } + h2 { font-size: 1.4em; text-transform:uppercase; font-weight: bold;} + h3 { font-size: 1.3em; font-weight: bold; } + + p, h1, h2, h3 { + margin: 0; + padding: 10px 15px; + } + + ul, ol { + margin: 10px 30px; + padding: 0 15px; + color: #FFF; + } + + /* images */ + img { + border: 3px solid #555; + } + img.no-border { + border: none; + } + img.float-right { + margin: 5px 0px 5px 15px; + } + img.float-left { + margin: 5px 15px 5px 0px; + } + a img { + border: 3px solid #555; + } + a:hover img { + border: 3px solid #CCC !important; /* IE fix*/ + border: 3px solid #555; + } + + code { + margin: 5px 0; + padding: 10px; + text-align: left; + display: block; + overflow: auto; + font: 500 1em/1.5em 'Lucida Console', 'courier new', monospace; + /* white-space: pre; */ + background: #0A1646; + } + acronym { + cursor: help; + border-bottom: 1px solid #777; + } + blockquote { + margin: 15px; + padding: 0 0 0 20px; + background: #0A1646; + font: bold 1.3em/1.5em 'Trebuchet MS', Sans-serif; + } + + /* form elements */ + form { + margin: 10px 15px; + padding: 0; + background: #0A1646; + } + label { + display:block; + font-weight:bold; + margin:5px 0; + } + input { + padding: 2px; + border:1px solid #eee; + font: normal 1em Verdana, sans-serif; + color:#777; + } + textarea { + width: 250px; + padding:2px; + font: normal 1em Verdana, sans-serif; + border:1px solid #eee; + height:100px; + display:block; + color:#777; + } + input.button { + margin: 0; + font: bold 1em Arial, Sans-serif; + border: 1px solid #CCC; + background: #FFF; + padding: 2px 3px; + color: #333; + } + + /* search form */ + .searchform form{ + background-color: transparent; + border: none; + margin: 0; padding: 0; + } + .searchform input.textbox { + margin: 0; + width: 145px; + border: 1px solid #777; + background: #FFF; + color: #333; + height: 14px; + vertical-align: top; + } + .searchform input.button { + margin: 0; + padding: 2px 3px; + font: bold 12px Arial, Sans-serif; + background: #FFF; + border: 1px solid #f2f2f2; + color: #333; + width: 65px; + vertical-align: top; + } + + /*********************** + LAYOUT + ************************/ + #wrap { + background: #212B5C url(images/bg.jpg) repeat-x 0 0; + margin: 20px auto 0 auto; + text-align: left; + border-color: #444; + border-style: solid; + border-width: 1px 1px 5px 1px; + } + #wrap, #footer-wrap { + width: 84%; + } + + /* header */ + #header { + position: relative; + height: 110px; + background: #7F8082 url(images/header-bg.jpg) repeat-x 0% 100%; + border-bottom: 5px solid #444; + } + #header h1#logo { + position: absolute; + top: 5px; left: 20px; + margin: 0; padding: 0; + font: bolder 50px 'Trebuchet MS', Arial, Sans-serif; + letter-spacing: -2px; + } + #header h2#slogan { + position: absolute; + top: 50px; left: 65px; + color: #FFF; + text-indent: 0px; + font: bold 18px Tahoma, 'Trebuchet MS', Sans-serif; + text-transform: none; + } + + /* content-wrap */ + #content-wrap { + clear: both; + margin: 0; padding: 0; + } + + /* box */ + .box { + margin: 10px 15px; + border: 1px solid #0A1646; + background-color: #1B2455; + } + + /* main */ + #main { + margin: 0 0 0 220px; + padding-top: 20px; + } + #main .box { + margin-left: 0; + } + + /* sidebar */ + #sidebar { + float: left; + width: 200px; + margin: 0; + padding-top: 20px; + } + #sidebar ul.sidemenu { + margin: 0 0 0 15px; padding: 0; + background: #242424; + border-top: 5px solid #444; + } + #sidebar ul.sidemenu li { + display: inline; + list-style: none; + } + #sidebar ul.sidemenu li a { + display: block; + padding: 5px 10px 5px 15px; + text-decoration: none; + color: #CCC; + font-weight: bold; + } + #sidebar ul.sidemenu li a:hover { + color: #333; + background: #A0A0A0; + } + + /* Footer */ + #footer-wrap { + clear: both; + color: #FFF; + background: #000; + margin: 0 auto; + padding: 0; + font-size: 88%; + } + #footer-wrap a { + text-decoration: none; + font-weight: bold; + color: #FFF; + } + #footer-wrap .footer-left{ + float: left; + width: 65%; + padding-bottom: 20px; + } + #footer-wrap .footer-right{ + float: right; + width: 30%; + padding-bottom: 20px; + } + + /* menu tabs */ + #header a { + position: absolute; + top: 20px; right: 20px; + margin:0; padding: 0; + list-style:none; + font: bold 1.3em 'Trebuchet MS', Tahoma, verdana, sans-serif; + height: 2.3em; + } + + #header ul { + position: absolute; + top: 20px; right: 20px; + margin:0; padding: 0; + list-style:none; + font: bold 1.3em 'Trebuchet MS', Tahoma, verdana, sans-serif; + height: 2.3em; + } + #header li { + display:inline; + margin:0; padding:0; + } + #header a { + float: left; + margin:0; + padding:3px 10px 2px 10px; + text-decoration:none; + color: #CCC; + } + #header #current a { + color: #FFF; + border-top: 5px solid #FFF; + } + /* end menu tabs */ + + /* alignment classes */ + .float-left { float: left; } + .float-right { float: right; } + .align-left { text-align: left; } + .align-right { text-align: right; } + + /* additional classes */ + .clear { clear: both; } + .gray { color: #A0A0A0; } + .comments { + text-align: right; + padding: 7px 15px; + margin: 20px 15px 15px 15px; + background: #0A1646; + } + Index: llvm-www/safecode/people.html diff -c /dev/null llvm-www/safecode/people.html:1.1 *** /dev/null Tue Nov 3 09:16:49 2009 --- llvm-www/safecode/people.html Tue Nov 3 09:15:58 2009 *************** *** 0 **** --- 1,140 ---- + + + + + + + + + + + + + + + + SAFECode + + + + + +
    + + + + +
    + + + +
    + +
    + +

    Project Members

    +
    + +

    Faculty

    + + + +

    Graduate Students

    +
      +
    • + John Criswell +
    • + +
    • + Andrew Lenharth +
    • + +
    • + Haohui Mai +
    • +
    + +

    Undergraduate Students

    +
      +
    • + Brice Lin +
    • +
    + +

    Graduate Student Alumni

    + + + +

    Undergraduate Student Alumni

    +
      +
    • + Billy Lau +
    • +
    +
    +
    + +
    + +
    + + +
    + + + + + + + Index: llvm-www/safecode/pubs.html diff -c /dev/null llvm-www/safecode/pubs.html:1.1 *** /dev/null Tue Nov 3 09:16:49 2009 --- llvm-www/safecode/pubs.html Tue Nov 3 09:15:58 2009 *************** *** 0 **** --- 1,180 ---- + + + + + + + + + + + + + + + + Publications + + + + + +
    + + + + +
    + + + +
    + + +
    + +

    SAFECode Publications

    +
    + +
    + + +
    + +

    Related Publications

    +
    + + + +
    +
    + +
    + +
    + + +
    + + + + + + + Index: llvm-www/safecode/links.html diff -c /dev/null llvm-www/safecode/links.html:1.1 *** /dev/null Tue Nov 3 09:16:49 2009 --- llvm-www/safecode/links.html Tue Nov 3 09:15:58 2009 *************** *** 0 **** --- 1,103 ---- + + + + + + + + + + + + + + + + Links + + + + + +
    + + + + +
    + + + +
    + + + +
    + +

    +

    + +
    + +
    + + +
    + + + + + + + Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.25 llvm-www/safecode/index.html:1.26 --- llvm-www/safecode/index.html:1.25 Thu Oct 1 18:27:17 2009 +++ llvm-www/safecode/index.html Tue Nov 3 09:15:58 2009 @@ -1,124 +1,126 @@ - - + + + + - SAFE Code - - - -
    SAFECode
    + + + + + + -
    + -

    Static Analysis For safe Execution of Code

    +SAFECode + + -

    SAFECode project aims at providing -memory safety guarantees to programs written in unsafe languages like -C and C++. - -

    As a part of this project, we developed a relatively simple -compilation strategy that for standard C programs guarantees sound -semantics for an aggressive interprocedural pointer analysis (or -simpler ones), a call graph, and type information for a subset of -memory. These provide the foundation for sophisticated static analyses -to be applied to such programs with a guarantee of soundness. Our work -builds on a previously published transformation called Automatic Pool -Allocation to ensure that hard-to-detect memory errors (dangling pointer -references and certain array bounds errors) cannot invalidate the call -graph, points-to information or type information. A technical report -on this work is available from here -
    - -

    Second, we developed a backwards-compatible run-time array bounds -checking solution that has very low overhead. More information on this -work is available from - here -
    - -

    Finally, we also developed a novel technique that can detect dangling -pointer errors (accesses to freed memory) with low over head in some -applications. More information on this -work is available here - - -

    - - -

    Project Members

    - -

    Faculty

    - - - -

    Graduate Students

    - - - -

    Publications

    - - - -

    Funding

    - -

    This project is sponsored by the NSF Embedded Systems program under award -CCR-02-09202 and in part by an NSF CAREER award, EIA-0093426 and ONR, -N0004-02-0102.

    - -

    Links

    - - -
    -
    - Valid CSS! - Valid HTML 4.01! + + +
    + + + +
    + + + +
    + +
    + +

    Home

    +
    + +

    + The purpose of the SAFECode project is to enable program safety without + runtime checks and garbage collection, using static analysis when + possible and run-time checks when necessary. SAFECode defines a code + representation with minimal semantic restrictions designed to enable + static enforcement of safety, using aggressive compiler techniques + developed in this project. +

    + +

    + SAFECode is designed to provide the following safety guarantees: +

      +
    • + Array bounds checking (prevents pointers from overflowing from one + memory object into another) +
    • + +
    • + Loads and stores only access valid memory objects +
    • + +
    • + Type safety for a subset of memory objects proven to be type-safe +
    • + +
    • + Sound operational semantics in the face of dangling pointer + errors (i.e., all safety guarantees hold even when dangling pointers + are dereferenced). +
    • + +
    • + Optional dangling pointer detection (induces more overhead) +
    • +
    +

    +
    +
    + +
    + +
    + + + + + + + From criswell at cs.uiuc.edu Tue Nov 3 09:18:42 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 09:18:42 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/images/ Message-ID: <200911031518.nA3FIgdK016775@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode/images: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm-www/safecode/images added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From criswell at cs.uiuc.edu Tue Nov 3 09:19:36 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 09:19:36 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/images/imark_bold.gif Message-ID: <200911031519.nA3FJa9v016820@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode/images: imark_bold.gif added (r1.1) --- Log message: Adding University of Illinois logo and link. --- Diffs of the changes: (+0 -0) imark_bold.gif | 0 1 files changed Index: llvm-www/safecode/images/imark_bold.gif From kennethuil at gmail.com Tue Nov 3 09:25:21 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Tue, 03 Nov 2009 15:25:21 -0000 Subject: [llvm-commits] [llvm] r85899 - /llvm/trunk/include/llvm/Module.h Message-ID: <200911031525.nA3FPLE9014344@zion.cs.uiuc.edu> Author: kennethuil Date: Tue Nov 3 09:25:20 2009 New Revision: 85899 URL: http://llvm.org/viewvc/llvm-project?rev=85899&view=rev Log: Added a comment to a function that had none Modified: llvm/trunk/include/llvm/Module.h Modified: llvm/trunk/include/llvm/Module.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Module.h?rev=85899&r1=85898&r2=85899&view=diff ============================================================================== --- llvm/trunk/include/llvm/Module.h (original) +++ llvm/trunk/include/llvm/Module.h Tue Nov 3 09:25:20 2009 @@ -252,6 +252,7 @@ AttrListPtr AttributeList, const Type *RetTy, ...) END_WITH_NULL; + /// getOrInsertFunction - Same as above, but without the attributes. Constant *getOrInsertFunction(const StringRef &Name, const Type *RetTy, ...) END_WITH_NULL; From kennethuil at gmail.com Tue Nov 3 09:29:07 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Tue, 03 Nov 2009 15:29:07 -0000 Subject: [llvm-commits] [llvm] r85900 - in /llvm/trunk: test/Analysis/BasicAA/ test/Analysis/ScalarEvolution/ test/CodeGen/X86/ test/Transforms/ArgumentPromotion/ test/Transforms/DeadStoreElimination/ test/Transforms/GlobalOpt/ test/Transforms/IndVarSimplify/ test/Transforms/Inline/ test/Transforms/InstCombine/ test/Transforms/MemCpyOpt/ test/Transforms/ScalarRepl/ tools/opt/ Message-ID: <200911031529.nA3FT9HY014534@zion.cs.uiuc.edu> Author: kennethuil Date: Tue Nov 3 09:29:06 2009 New Revision: 85900 URL: http://llvm.org/viewvc/llvm-project?rev=85900&view=rev Log: Make opt default to not adding a target data string and update tests that depend on target data to supply it within the test Modified: llvm/trunk/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll llvm/trunk/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll llvm/trunk/test/Analysis/BasicAA/featuretest.ll llvm/trunk/test/Analysis/BasicAA/global-size.ll llvm/trunk/test/Analysis/BasicAA/modref.ll llvm/trunk/test/Analysis/BasicAA/store-promote.ll llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll llvm/trunk/test/CodeGen/X86/vec_ins_extract.ll llvm/trunk/test/Transforms/ArgumentPromotion/aggregate-promote.ll llvm/trunk/test/Transforms/ArgumentPromotion/basictest.ll llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll llvm/trunk/test/Transforms/ArgumentPromotion/chained.ll llvm/trunk/test/Transforms/ArgumentPromotion/control-flow2.ll llvm/trunk/test/Transforms/DeadStoreElimination/2008-07-28-load-store.ll llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll llvm/trunk/test/Transforms/DeadStoreElimination/context-sensitive.ll llvm/trunk/test/Transforms/DeadStoreElimination/simple.ll llvm/trunk/test/Transforms/GlobalOpt/globalsra-partial.ll llvm/trunk/test/Transforms/GlobalOpt/globalsra.ll llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll llvm/trunk/test/Transforms/Inline/basictest.ll llvm/trunk/test/Transforms/InstCombine/2003-11-13-ConstExprCastCall.ll llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll llvm/trunk/test/Transforms/InstCombine/align-2d-gep.ll llvm/trunk/test/Transforms/InstCombine/align-addr.ll llvm/trunk/test/Transforms/InstCombine/align-inc.ll llvm/trunk/test/Transforms/InstCombine/alloca.ll llvm/trunk/test/Transforms/InstCombine/call.ll llvm/trunk/test/Transforms/InstCombine/cast-load-gep.ll llvm/trunk/test/Transforms/InstCombine/cast.ll llvm/trunk/test/Transforms/InstCombine/cast2.ll llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll llvm/trunk/test/Transforms/InstCombine/fp-ret-bitcast.ll llvm/trunk/test/Transforms/InstCombine/loadstore-alignment.ll llvm/trunk/test/Transforms/InstCombine/ptr-int-cast.ll llvm/trunk/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll llvm/trunk/test/Transforms/MemCpyOpt/align.ll llvm/trunk/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll llvm/trunk/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll llvm/trunk/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll llvm/trunk/test/Transforms/ScalarRepl/2008-09-22-vector-gep.ll llvm/trunk/test/Transforms/ScalarRepl/2009-03-04-MemCpyAlign.ll llvm/trunk/test/Transforms/ScalarRepl/DifferingTypes.ll llvm/trunk/test/Transforms/ScalarRepl/arraytest.ll llvm/trunk/test/Transforms/ScalarRepl/basictest.ll llvm/trunk/test/Transforms/ScalarRepl/bitfield-sroa.ll llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll llvm/trunk/test/Transforms/ScalarRepl/debuginfo.ll llvm/trunk/test/Transforms/ScalarRepl/load-store-aggregate.ll llvm/trunk/test/Transforms/ScalarRepl/memcpy-from-global.ll llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll llvm/trunk/test/Transforms/ScalarRepl/union-fp-int.ll llvm/trunk/test/Transforms/ScalarRepl/union-packed.ll llvm/trunk/test/Transforms/ScalarRepl/vector_memcpy.ll llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -aa-eval -disable-output |& grep {2 no alias respon} ; TEST that A[1][0] may alias A[0][i]. +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define void @test(i32 %N) { entry: Modified: llvm/trunk/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt -gvn -instcombine -S < %s | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" declare i8 @llvm.atomic.load.add.i8.p0i8(i8*, i8) Modified: llvm/trunk/test/Analysis/BasicAA/featuretest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/featuretest.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/featuretest.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/featuretest.ll Tue Nov 3 09:29:06 2009 @@ -2,6 +2,7 @@ ; determine, as noted in the comments. ; RUN: opt < %s -basicaa -gvn -instcombine -dce -S | not grep REMOVE +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @Global = external global { i32 } Modified: llvm/trunk/test/Analysis/BasicAA/global-size.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/global-size.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/global-size.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/global-size.ll Tue Nov 3 09:29:06 2009 @@ -2,6 +2,7 @@ ; the global. ; RUN: opt < %s -basicaa -gvn -instcombine -S | not grep load +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @B = global i16 8 ; [#uses=2] Modified: llvm/trunk/test/Analysis/BasicAA/modref.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/modref.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/modref.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/modref.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -basicaa -gvn -dse -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" declare void @llvm.memset.i32(i8*, i8, i32, i32) declare void @llvm.memset.i8(i8*, i8, i8, i32) @@ -88,4 +89,4 @@ call void @llvm.lifetime.end(i64 10, i8* %P) ret void ; CHECK: ret void -} \ No newline at end of file +} Modified: llvm/trunk/test/Analysis/BasicAA/store-promote.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/store-promote.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/store-promote.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/store-promote.ll Tue Nov 3 09:29:06 2009 @@ -3,6 +3,7 @@ ; two pointers, then the load should be hoisted, and the store sunk. ; RUN: opt < %s -basicaa -licm -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @A = global i32 7 ; [#uses=3] @B = global i32 8 ; [#uses=2] Modified: llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep {count is 2} ; PR3171 +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" %struct.Foo = type { i32 } %struct.NonPod = type { [2 x %struct.Foo] } Modified: llvm/trunk/test/CodeGen/X86/vec_ins_extract.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_ins_extract.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_ins_extract.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_ins_extract.ll Tue Nov 3 09:29:06 2009 @@ -3,6 +3,7 @@ ; This checks that various insert/extract idiom work without going to the ; stack. +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" define void @test(<4 x float>* %F, float %f) { entry: Modified: llvm/trunk/test/Transforms/ArgumentPromotion/aggregate-promote.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ArgumentPromotion/aggregate-promote.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ArgumentPromotion/aggregate-promote.ll (original) +++ llvm/trunk/test/Transforms/ArgumentPromotion/aggregate-promote.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -argpromotion -instcombine -S | not grep load +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" %QuadTy = type { i32, i32, i32, i32 } @G = constant %QuadTy { Modified: llvm/trunk/test/Transforms/ArgumentPromotion/basictest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ArgumentPromotion/basictest.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ArgumentPromotion/basictest.ll (original) +++ llvm/trunk/test/Transforms/ArgumentPromotion/basictest.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -argpromotion -mem2reg -S | not grep alloca +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define internal i32 @test(i32* %X, i32* %Y) { %A = load i32* %X ; [#uses=1] %B = load i32* %Y ; [#uses=1] Modified: llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll (original) +++ llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -argpromotion -scalarrepl -S | not grep load +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; Argpromote + scalarrepl should change this to passing the two integers by value. %struct.ss = type { i32, i64 } Modified: llvm/trunk/test/Transforms/ArgumentPromotion/chained.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ArgumentPromotion/chained.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ArgumentPromotion/chained.ll (original) +++ llvm/trunk/test/Transforms/ArgumentPromotion/chained.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -argpromotion -instcombine -S | not grep load +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @G1 = constant i32 0 ; [#uses=1] @G2 = constant i32* @G1 ; [#uses=1] Modified: llvm/trunk/test/Transforms/ArgumentPromotion/control-flow2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ArgumentPromotion/control-flow2.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ArgumentPromotion/control-flow2.ll (original) +++ llvm/trunk/test/Transforms/ArgumentPromotion/control-flow2.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -argpromotion -S | \ ; RUN: grep {load i32\\* %A} +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define internal i32 @callee(i1 %C, i32* %P) { br i1 %C, label %T, label %F Modified: llvm/trunk/test/Transforms/DeadStoreElimination/2008-07-28-load-store.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/2008-07-28-load-store.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/2008-07-28-load-store.ll (original) +++ llvm/trunk/test/Transforms/DeadStoreElimination/2008-07-28-load-store.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -dse -S | not grep tmp5 ; PR2599 +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define void @foo({ i32, i32 }* %x) nounwind { entry: Modified: llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll (original) +++ llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll Tue Nov 3 09:29:06 2009 @@ -2,6 +2,7 @@ ; RUN: not grep {store i8} ; Ensure that the dead store is deleted in this case. It is wholely ; overwritten by the second store. +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define i32 @test() { %V = alloca i32 ; [#uses=3] %V2 = bitcast i32* %V to i8* ; [#uses=1] Modified: llvm/trunk/test/Transforms/DeadStoreElimination/context-sensitive.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/context-sensitive.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/context-sensitive.ll (original) +++ llvm/trunk/test/Transforms/DeadStoreElimination/context-sensitive.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -dse -S | not grep DEAD +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" declare void @ext() Modified: llvm/trunk/test/Transforms/DeadStoreElimination/simple.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/simple.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/simple.ll (original) +++ llvm/trunk/test/Transforms/DeadStoreElimination/simple.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -dse -S | not grep DEAD +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define void @test(i32* %Q, i32* %P) { %DEAD = load i32* %Q ; [#uses=1] Modified: llvm/trunk/test/Transforms/GlobalOpt/globalsra-partial.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/globalsra-partial.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/globalsra-partial.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/globalsra-partial.ll Tue Nov 3 09:29:06 2009 @@ -1,6 +1,7 @@ ; In this case, the global can only be broken up by one level. ; RUN: opt < %s -globalopt -S | not grep 12345 +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @G = internal global { i32, [4 x float] } zeroinitializer ; <{ i32, [4 x float] }*> [#uses=3] Modified: llvm/trunk/test/Transforms/GlobalOpt/globalsra.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/globalsra.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/globalsra.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/globalsra.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -globalopt -S | not grep global +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @G = internal global { i32, float, { double } } { i32 1, Modified: llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -globalopt -S | not grep global +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @G = internal global i32* null ; [#uses=3] Modified: llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll (original) +++ llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll Tue Nov 3 09:29:06 2009 @@ -2,6 +2,7 @@ ; RUN: not grep inttoptr %t ; RUN: not grep ptrtoint %t ; RUN: grep scevgep %t +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; Indvars shouldn't need inttoptr/ptrtoint to expand an address here. Modified: llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll (original) +++ llvm/trunk/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -indvars -S \ ; RUN: | grep {\[%\]p.2.ip.1 = getelementptr \\\[3 x \\\[3 x double\\\]\\\]\\* \[%\]p, i64 2, i64 \[%\]tmp, i64 1} +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; Indvars shouldn't expand this to ; %p.2.ip.1 = getelementptr [3 x [3 x double]]* %p, i64 0, i64 %tmp, i64 19 Modified: llvm/trunk/test/Transforms/Inline/basictest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/basictest.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Inline/basictest.ll (original) +++ llvm/trunk/test/Transforms/Inline/basictest.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -inline -scalarrepl -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define i32 @test1f(i32 %i) { ret i32 %i Modified: llvm/trunk/test/Transforms/InstCombine/2003-11-13-ConstExprCastCall.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2003-11-13-ConstExprCastCall.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2003-11-13-ConstExprCastCall.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/2003-11-13-ConstExprCastCall.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" declare void @free(i8*) Modified: llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -instcombine -S | not grep call ; RUN: opt < %s -std-compile-opts -S | not grep xyz +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @.str = internal constant [4 x i8] c"xyz\00" ; <[4 x i8]*> [#uses=1] Modified: llvm/trunk/test/Transforms/InstCombine/align-2d-gep.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/align-2d-gep.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/align-2d-gep.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/align-2d-gep.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -instcombine -S | grep {align 16} | count 1 +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; A multi-dimensional array in a nested loop doing vector stores that ; aren't yet aligned. Instcombine can understand the addressing in the Modified: llvm/trunk/test/Transforms/InstCombine/align-addr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/align-addr.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/align-addr.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/align-addr.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -instcombine -S | grep {align 16} | count 1 +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; Instcombine should be able to prove vector alignment in the ; presence of a few mild address computation tricks. Modified: llvm/trunk/test/Transforms/InstCombine/align-inc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/align-inc.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/align-inc.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/align-inc.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -instcombine -S | grep {GLOBAL.*align 16} ; RUN: opt < %s -instcombine -S | grep {tmp = load} +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @GLOBAL = internal global [4 x i32] zeroinitializer Modified: llvm/trunk/test/Transforms/InstCombine/alloca.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/alloca.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/alloca.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/alloca.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; Zero byte allocas should be deleted. +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; RUN: opt < %s -instcombine -S | \ ; RUN: not grep alloca Modified: llvm/trunk/test/Transforms/InstCombine/call.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/call.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/call.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/call.ll Tue Nov 3 09:29:06 2009 @@ -1,6 +1,7 @@ ; Ignore stderr, we expect warnings there ; RUN: opt < %s -instcombine 2> /dev/null -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; Simple case, argument translatable without changing the value declare void @test1a(i8*) Modified: llvm/trunk/test/Transforms/InstCombine/cast-load-gep.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast-load-gep.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/cast-load-gep.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/cast-load-gep.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -instcombine -globaldce -S | \ ; RUN: not grep Array +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; Pulling the cast out of the load allows us to eliminate the load, and then ; the whole array. Modified: llvm/trunk/test/Transforms/InstCombine/cast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/cast.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/cast.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; Tests to make sure elimination of casts is working correctly ; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1] Modified: llvm/trunk/test/Transforms/InstCombine/cast2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast2.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/cast2.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/cast2.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; Tests to make sure elimination of casts is working correctly ; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define i16 @test1(i16 %a) { %tmp = zext i16 %a to i32 ; [#uses=2] Modified: llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" ; Constant folding should fix notionally out-of-bounds indices ; and add inbounds keywords. Modified: llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -instcombine -S | not grep icmp +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define i1 @f(i1 %x) { %b = and i1 %x, icmp eq (i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 2 to i8*)) Modified: llvm/trunk/test/Transforms/InstCombine/fp-ret-bitcast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fp-ret-bitcast.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fp-ret-bitcast.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fp-ret-bitcast.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -instcombine -S | \ ; RUN: grep {call float bitcast} | count 1 +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" %struct.NSObject = type { %struct.objc_class* } %struct.NSArray = type { %struct.NSObject } %struct.objc_class = type opaque Modified: llvm/trunk/test/Transforms/InstCombine/loadstore-alignment.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/loadstore-alignment.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/loadstore-alignment.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/loadstore-alignment.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -instcombine -S | grep {, align 16} | count 14 +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @x = external global <2 x i64>, align 16 @xx = external global [13 x <2 x i64>], align 16 Modified: llvm/trunk/test/Transforms/InstCombine/ptr-int-cast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/ptr-int-cast.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/ptr-int-cast.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/ptr-int-cast.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -instcombine -S > %t +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define i1 @test1(i32 *%x) nounwind { entry: Modified: llvm/trunk/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll (original) +++ llvm/trunk/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -memcpyopt -S | not grep {call.*memcpy.} +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" %a = type { i32 } %b = type { float } Modified: llvm/trunk/test/Transforms/MemCpyOpt/align.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/align.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/MemCpyOpt/align.ll (original) +++ llvm/trunk/test/Transforms/MemCpyOpt/align.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -S -memcpyopt | FileCheck %s +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" ; The resulting memset is only 4-byte aligned, despite containing ; a 16-byte alignmed store in the middle. Modified: llvm/trunk/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -scalarrepl -instcombine -S | not grep alloca +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" ; Test that an array is not incorrectly deconstructed. Modified: llvm/trunk/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -scalarrepl -S | not grep alloca +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define i32 @func(<4 x float> %v0, <4 x float> %v1) nounwind { %vsiidx = alloca [2 x <4 x i32>], align 16 ; <[2 x <4 x i32>]*> [#uses=3] Modified: llvm/trunk/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll Tue Nov 3 09:29:06 2009 @@ -4,6 +4,7 @@ ; values. This checks of scalarrepl splits up the struct and array properly. ; RUN: opt < %s -scalarrepl -S | not grep alloca +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define i32 @foo() { %target = alloca { i32, i32 } ; <{ i32, i32 }*> [#uses=1] Modified: llvm/trunk/test/Transforms/ScalarRepl/2008-09-22-vector-gep.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2008-09-22-vector-gep.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2008-09-22-vector-gep.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/2008-09-22-vector-gep.ll Tue Nov 3 09:29:06 2009 @@ -5,6 +5,7 @@ ; RUN: opt < %s -scalarrepl -S > %t ; RUN: cat %t | not grep alloca +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" %struct.two = type <{ < 2 x i8 >, i16 }> Modified: llvm/trunk/test/Transforms/ScalarRepl/2009-03-04-MemCpyAlign.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2009-03-04-MemCpyAlign.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2009-03-04-MemCpyAlign.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/2009-03-04-MemCpyAlign.ll Tue Nov 3 09:29:06 2009 @@ -2,6 +2,7 @@ ; is only known to access it with 1-byte alignment. ; RUN: opt < %s -scalarrepl -S | grep {store i16 1, .*, align 1} ; PR3720 +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" %struct.st = type { i16 } Modified: llvm/trunk/test/Transforms/ScalarRepl/DifferingTypes.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/DifferingTypes.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/DifferingTypes.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/DifferingTypes.ll Tue Nov 3 09:29:06 2009 @@ -3,6 +3,7 @@ ; depending on the endianness of the target... ; RUN: opt < %s -scalarrepl -S | \ ; RUN: not grep alloca +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define i32 @testfunc(i32 %i, i8 %j) { %I = alloca i32 ; [#uses=3] Modified: llvm/trunk/test/Transforms/ScalarRepl/arraytest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/arraytest.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/arraytest.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/arraytest.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -scalarrepl -mem2reg -S | not grep alloca +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define i32 @test() { %X = alloca [4 x i32] ; <[4 x i32]*> [#uses=1] Modified: llvm/trunk/test/Transforms/ScalarRepl/basictest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/basictest.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/basictest.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/basictest.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -scalarrepl -mem2reg -S | not grep alloca +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define i32 @test() { %X = alloca { i32, float } ; <{ i32, float }*> [#uses=1] Modified: llvm/trunk/test/Transforms/ScalarRepl/bitfield-sroa.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/bitfield-sroa.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/bitfield-sroa.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/bitfield-sroa.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -scalarrepl -S | not grep alloca ; rdar://6532315 +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" %t = type { { i32, i16, i8, i8 } } define i8 @foo(i64 %A) { Modified: llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -scalarrepl -S | not grep alloca ; PR3290 +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" ;; Store of integer to whole alloca struct. define i32 @test1(i64 %V) nounwind { Modified: llvm/trunk/test/Transforms/ScalarRepl/debuginfo.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/debuginfo.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/debuginfo.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/debuginfo.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -scalarrepl -S | not grep alloca +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" %llvm.dbg.anchor.type = type { i32, i32 } %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* } Modified: llvm/trunk/test/Transforms/ScalarRepl/load-store-aggregate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/load-store-aggregate.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/load-store-aggregate.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/load-store-aggregate.ll Tue Nov 3 09:29:06 2009 @@ -1,6 +1,7 @@ ; This testcase shows that scalarrepl is able to replace struct alloca's which ; are directly loaded from or stored to (using the first class aggregates ; feature). +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" ; RUN: opt < %s -scalarrepl -S > %t ; RUN: cat %t | not grep alloca Modified: llvm/trunk/test/Transforms/ScalarRepl/memcpy-from-global.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/memcpy-from-global.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/memcpy-from-global.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/memcpy-from-global.ll Tue Nov 3 09:29:06 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -scalarrepl -S | not grep {call.*memcpy} +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" @C.0.1248 = internal constant [128 x float] [ float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float -1.000000e+00, float 1.000000e+00, float -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float -1.000000e+00, float -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float 1.000000e+00! , float 1.000000e+00, float 0.000000e+00, float 0.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+00, float 0.000000e+00, float -1.000000e+00, float -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.! 000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.00! 0000e+00 , float -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 0.000000e+00, float 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 ], align 32 ; <[128 x float]*> [#uses=1] define float @grad4(i32 %hash, float %x, float %y, float %z, float %w) { Modified: llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll Tue Nov 3 09:29:06 2009 @@ -1,6 +1,7 @@ ; RUN: opt < %s -scalarrepl -S | not grep alloca ; RUN: opt < %s -scalarrepl -S | not grep {7 x double} ; RUN: opt < %s -scalarrepl -instcombine -S | grep {ret double %B} +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define double @test(double %A, double %B) { %ARR = alloca [7 x i64] Modified: llvm/trunk/test/Transforms/ScalarRepl/union-fp-int.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/union-fp-int.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/union-fp-int.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/union-fp-int.ll Tue Nov 3 09:29:06 2009 @@ -2,6 +2,7 @@ ; RUN: not grep alloca ; RUN: opt < %s -scalarrepl -S | \ ; RUN: grep {bitcast.*float.*i32} +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define i32 @test(float %X) { %X_addr = alloca float ; [#uses=2] Modified: llvm/trunk/test/Transforms/ScalarRepl/union-packed.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/union-packed.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/union-packed.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/union-packed.ll Tue Nov 3 09:29:06 2009 @@ -2,6 +2,7 @@ ; RUN: not grep alloca ; RUN: opt < %s -scalarrepl -S | \ ; RUN: grep bitcast +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define <4 x i32> @test(<4 x float> %X) { %X_addr = alloca <4 x float> ; <<4 x float>*> [#uses=2] Modified: llvm/trunk/test/Transforms/ScalarRepl/vector_memcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/vector_memcpy.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/vector_memcpy.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/vector_memcpy.ll Tue Nov 3 09:29:06 2009 @@ -1,6 +1,7 @@ ; RUN: opt < %s -scalarrepl -S > %t ; RUN: grep {ret <16 x float> %A} %t ; RUN: grep {ret <16 x float> zeroinitializer} %t +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define <16 x float> @foo(<16 x float> %A) nounwind { %tmp = alloca <16 x float>, align 16 Modified: llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll Tue Nov 3 09:29:06 2009 @@ -1,5 +1,6 @@ ; RUN: opt < %s -scalarrepl -S | not grep alloca ; RUN: opt < %s -scalarrepl -S | grep {load <4 x float>} +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" define void @test(<4 x float>* %F, float %f) { entry: Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=85900&r1=85899&r2=85900&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Tue Nov 3 09:29:06 2009 @@ -132,10 +132,6 @@ cl::desc("data layout string to use if not specified by module"), cl::value_desc("layout-string"), cl::init("")); -static cl::opt -NoDefaultDataLayout("no-default-data-layout", - cl::desc("no data layout assumptions unless module specifies data layout")); - // ---------- Define Printers for module and function passes ------------ namespace { @@ -401,7 +397,7 @@ const std::string &ModuleDataLayout = M.get()->getDataLayout(); if (!ModuleDataLayout.empty()) TD = new TargetData(ModuleDataLayout); - else if (!NoDefaultDataLayout) + else if (!DefaultDataLayout.empty()) TD = new TargetData(DefaultDataLayout); if (TD) From criswell at cs.uiuc.edu Tue Nov 3 09:37:36 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 09:37:36 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/sidebar.incl Message-ID: <200911031537.nA3FbaD8017249@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: sidebar.incl added (r1.1) --- Log message: Sidebar menu. --- Diffs of the changes: (+10 -0) sidebar.incl | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm-www/safecode/sidebar.incl diff -c /dev/null llvm-www/safecode/sidebar.incl:1.1 *** /dev/null Tue Nov 3 09:37:02 2009 --- llvm-www/safecode/sidebar.incl Tue Nov 3 09:36:52 2009 *************** *** 0 **** --- 1,10 ---- + + From criswell at cs.uiuc.edu Tue Nov 3 09:38:02 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 09:38:02 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/links.html Message-ID: <200911031538.nA3Fc2Hv017263@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: links.html updated: 1.1 -> 1.2 --- Log message: Use the new sidebar include file. --- Diffs of the changes: (+2 -11) links.html | 13 ++----------- 1 files changed, 2 insertions(+), 11 deletions(-) Index: llvm-www/safecode/links.html diff -u llvm-www/safecode/links.html:1.1 llvm-www/safecode/links.html:1.2 --- llvm-www/safecode/links.html:1.1 Tue Nov 3 09:15:58 2009 +++ llvm-www/safecode/links.html Tue Nov 3 09:37:22 2009 @@ -38,17 +38,8 @@
    - - + +
    From criswell at cs.uiuc.edu Tue Nov 3 09:39:38 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 09:39:38 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html people.html pubs.html Message-ID: <200911031539.nA3Fdcgs017336@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.26 -> 1.27 people.html updated: 1.1 -> 1.2 pubs.html updated: 1.1 -> 1.2 --- Log message: Switch to the new sidebar menu include file. --- Diffs of the changes: (+3 -30) index.html | 11 +---------- people.html | 11 +---------- pubs.html | 11 +---------- 3 files changed, 3 insertions(+), 30 deletions(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.26 llvm-www/safecode/index.html:1.27 --- llvm-www/safecode/index.html:1.26 Tue Nov 3 09:15:58 2009 +++ llvm-www/safecode/index.html Tue Nov 3 09:38:56 2009 @@ -38,17 +38,8 @@
    - -
    Index: llvm-www/safecode/people.html diff -u llvm-www/safecode/people.html:1.1 llvm-www/safecode/people.html:1.2 --- llvm-www/safecode/people.html:1.1 Tue Nov 3 09:15:58 2009 +++ llvm-www/safecode/people.html Tue Nov 3 09:38:56 2009 @@ -38,17 +38,8 @@
    - -
    Index: llvm-www/safecode/pubs.html diff -u llvm-www/safecode/pubs.html:1.1 llvm-www/safecode/pubs.html:1.2 --- llvm-www/safecode/pubs.html:1.1 Tue Nov 3 09:15:58 2009 +++ llvm-www/safecode/pubs.html Tue Nov 3 09:38:56 2009 @@ -41,17 +41,8 @@
    - -
    From criswell at cs.uiuc.edu Tue Nov 3 09:44:12 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 09:44:12 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/people.html Message-ID: <200911031544.nA3FiC69017467@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: people.html updated: 1.2 -> 1.3 --- Log message: Added Nicolas Geoffray to Alumni because of his work on Secure Virtual Architecture. --- Diffs of the changes: (+4 -0) people.html | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm-www/safecode/people.html diff -u llvm-www/safecode/people.html:1.2 llvm-www/safecode/people.html:1.3 --- llvm-www/safecode/people.html:1.2 Tue Nov 3 09:38:56 2009 +++ llvm-www/safecode/people.html Tue Nov 3 09:43:26 2009 @@ -83,6 +83,10 @@
  • + Nicolas Geoffray +
  • + +
  • Sumant Kowshik
  • From criswell at cs.uiuc.edu Tue Nov 3 10:02:26 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 10:02:26 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/people.html Message-ID: <200911031602.nA3G2QrL017884@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: people.html updated: 1.3 -> 1.4 --- Log message: Corrected title. --- Diffs of the changes: (+1 -1) people.html | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-www/safecode/people.html diff -u llvm-www/safecode/people.html:1.3 llvm-www/safecode/people.html:1.4 --- llvm-www/safecode/people.html:1.3 Tue Nov 3 09:43:26 2009 +++ llvm-www/safecode/people.html Tue Nov 3 10:01:44 2009 @@ -13,7 +13,7 @@ -SAFECode +Project Members From criswell at cs.uiuc.edu Tue Nov 3 10:20:49 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 10:20:49 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/pubs.html Message-ID: <200911031620.nA3GKnqs018290@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: pubs.html updated: 1.2 -> 1.3 --- Log message: Added missing SAFECode publications. Added SVA publication from Usenix Security 2009. Added full conference names for some entries. --- Diffs of the changes: (+59 -4) pubs.html | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 59 insertions(+), 4 deletions(-) Index: llvm-www/safecode/pubs.html diff -u llvm-www/safecode/pubs.html:1.2 llvm-www/safecode/pubs.html:1.3 --- llvm-www/safecode/pubs.html:1.2 Tue Nov 3 09:38:56 2009 +++ llvm-www/safecode/pubs.html Tue Nov 3 10:20:02 2009 @@ -50,7 +50,47 @@

    SAFECode Publications


    - + +
      +
    • + + Efficiently Detecting All Dangling Pointer Uses in Production Servers + +
      + Dinakar Dhurjati and Vikram Adve. +
      + International Conference on Dependable Systems and Networks (DSN), 2006 +
    • + +
      + +
        +
      • + + SAFECode: Enforcing Alias Analysis for Weakly Typed Languages + +
        + Dinakar Dhurjati, Sumant Kowshik, and Vikram Adve. +
        + ACM SIGPLAN Conference on Programming Language Design and +Implementation (PLDI), June 2006 +
      • + +
        + +
          +
        • + + Backwards-Compatible Array Bounds Checking for C with Very Low Overhead + +
          + Dinakar Dhurjati and Vikram Adve. +
          + International Conference on Software Engineering (ICSE), May 2006 +
        • + +
          +
          • @@ -61,7 +101,7 @@ Technical Report #UIUCDCS-R-2005-2657, Computer Science Dept., University of Illinois, Nov 2005
          • -

            +
          • @@ -85,7 +125,7 @@
            Dinakar Dhurjati, Sumant Kowshik, Vikram Adve and Chris Lattner.
            - LCTES 2003. + Languages Compilers and Tools for Embedded Systems (LCTES), June 2003.

          • @@ -98,7 +138,8 @@
            Sumant Kowshik, Dinakar Dhurjati, Vikram Adve.
            - CASES 2002. + Internaltional Conference on Compilers, Architecture and Synthesis for + Embedded Systems (CASES), October 2002.
            @@ -111,6 +152,20 @@
              +
            • + + Memory Safety for Low-Level Software/Hardware Interactions + +
              + John Criswell, Nicolas Geoffray, and Vikram Adve +
              + Proceedings of the Eighteenth USENIX Security Symposium, + Montreal, Canada, August 2009. +
            • + +
              + +
              • Secure Virtual Architecture: A Safe Execution Environment for Commodity From criswell at cs.uiuc.edu Tue Nov 3 10:24:05 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/pubs.html Message-ID: <200911031624.nA3GO5Xe018390@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: pubs.html updated: 1.3 -> 1.4 --- Log message: Fixed formatting mistakes. Fixed link to Usenix Security 2009 publication. --- Diffs of the changes: (+1 -5) pubs.html | 6 +----- 1 files changed, 1 insertion(+), 5 deletions(-) Index: llvm-www/safecode/pubs.html diff -u llvm-www/safecode/pubs.html:1.3 llvm-www/safecode/pubs.html:1.4 --- llvm-www/safecode/pubs.html:1.3 Tue Nov 3 10:20:02 2009 +++ llvm-www/safecode/pubs.html Tue Nov 3 10:23:20 2009 @@ -64,7 +64,6 @@
                -
                • SAFECode: Enforcing Alias Analysis for Weakly Typed Languages @@ -78,7 +77,6 @@
                  -
                  • Backwards-Compatible Array Bounds Checking for C with Very Low Overhead @@ -91,7 +89,6 @@
                    -
                    • Enforcing Alias Analysis for Weakly Typed Languages @@ -152,7 +149,7 @@
                        -
                      • +
                      • Memory Safety for Low-Level Software/Hardware Interactions @@ -165,7 +162,6 @@
                        -
                        • Secure Virtual Architecture: A Safe Execution Environment for Commodity From criswell at cs.uiuc.edu Tue Nov 3 10:25:47 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 10:25:47 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/pubs.html Message-ID: <200911031625.nA3GPlat018454@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: pubs.html updated: 1.4 -> 1.5 --- Log message: Fixed hyperlinks. --- Diffs of the changes: (+1 -1) pubs.html | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-www/safecode/pubs.html diff -u llvm-www/safecode/pubs.html:1.4 llvm-www/safecode/pubs.html:1.5 --- llvm-www/safecode/pubs.html:1.4 Tue Nov 3 10:23:20 2009 +++ llvm-www/safecode/pubs.html Tue Nov 3 10:25:04 2009 @@ -101,7 +101,7 @@
                        • - + Memory Safety Without Garbage Collection for Embedded Applications
                          From bob.wilson at apple.com Tue Nov 3 10:36:22 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 03 Nov 2009 16:36:22 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85902 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200911031636.nA3GaNEf017055@zion.cs.uiuc.edu> Author: bwilson Date: Tue Nov 3 10:36:22 2009 New Revision: 85902 URL: http://llvm.org/viewvc/llvm-project?rev=85902&view=rev Log: Remove comment that is not relevant here. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85902&r1=85901&r2=85902&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Nov 3 10:36:22 2009 @@ -6941,9 +6941,6 @@ #ifdef USEINDIRECTBRANCH Constant *TreeToLLVM::EmitLV_LABEL_DECL(tree exp) { - // GCC kindly diverts labels for unreachable basic blocks to reachable blocks, - // so we are not obliged to output unreachable blocks even if the original - // code took the address of one. return BlockAddress::get(Fn, getLabelDeclBlock(exp)); } #endif From bob.wilson at apple.com Tue Nov 3 10:33:24 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 3 Nov 2009 08:33:24 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r85835 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h In-Reply-To: <4AF00FCD.7030508@free.fr> References: <200911022244.nA2MiNFd026188@zion.cs.uiuc.edu> <4AF00FCD.7030508@free.fr> Message-ID: <25F07A47-09D1-4DF8-8367-7B33E34231FF@apple.com> On Nov 3, 2009, at 3:11 AM, Duncan Sands wrote: > Hi Bob, thanks for doing this. > >> +Constant *TreeToLLVM::EmitLV_LABEL_DECL(tree exp) { >> + // GCC kindly diverts labels for unreachable basic blocks to >> reachable blocks, >> + // so we are not obliged to output unreachable blocks even if >> the original >> + // code took the address of one. > > this comment is only really relevant to dragonegg, which outputs > basic basic > blocks in dom order (in order to translate phi nodes), and as a side- > effect > only outputs reachable basic blocks. OK. I removed it. Thanks for the review. From sabre at nondot.org Tue Nov 3 10:50:11 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 16:50:11 -0000 Subject: [llvm-commits] [llvm] r85903 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911031650.nA3GoBAO017521@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 10:50:11 2009 New Revision: 85903 URL: http://llvm.org/viewvc/llvm-project?rev=85903&view=rev Log: fix a subtle bug I introduced when refactoring SCCP. Testcase to follow. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85903&r1=85902&r2=85903&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Tue Nov 3 10:50:11 2009 @@ -107,7 +107,7 @@ /// markConstant - Return true if this is a change in status. bool markConstant(Constant *V) { - if (isConstant()) { + if (getLatticeValue() == constant) { // Constant but not forcedconstant. assert(getConstant() == V && "Marking constant with different value"); return false; } From sabre at nondot.org Tue Nov 3 11:03:02 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 17:03:02 -0000 Subject: [llvm-commits] [llvm] r85906 - /llvm/trunk/test/Transforms/SCCP/crash.ll Message-ID: <200911031703.nA3H323j018003@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 11:03:02 2009 New Revision: 85906 URL: http://llvm.org/viewvc/llvm-project?rev=85906&view=rev Log: testcase for r85903 Added: llvm/trunk/test/Transforms/SCCP/crash.ll Added: llvm/trunk/test/Transforms/SCCP/crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/crash.ll?rev=85906&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SCCP/crash.ll (added) +++ llvm/trunk/test/Transforms/SCCP/crash.ll Tue Nov 3 11:03:02 2009 @@ -0,0 +1,24 @@ +; RUN: opt %s -sccp -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" +target triple = "x86_64-apple-darwin10.0" + +define void @test1(i8 %arg) { +entry: + br i1 undef, label %return, label %bb + +bb: + br label %bb34 + +bb23: + %c = icmp eq i8 %arg, undef + br i1 %c, label %bb34, label %bb23 + +bb34: + %Kind.1 = phi i32 [ undef, %bb ], [ %ins174, %bb23 ] + %mask173 = or i32 %Kind.1, 7 + %ins174 = and i32 %mask173, -249 + br label %bb23 + +return: + ret void +} From sabre at nondot.org Tue Nov 3 11:54:13 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 17:54:13 -0000 Subject: [llvm-commits] [llvm] r85907 - /llvm/trunk/test/FrontendC++/integration-O2.cpp Message-ID: <200911031754.nA3HsD0u019580@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 11:54:12 2009 New Revision: 85907 URL: http://llvm.org/viewvc/llvm-project?rev=85907&view=rev Log: xfail this test since daniel turned off ipsccp Modified: llvm/trunk/test/FrontendC++/integration-O2.cpp Modified: llvm/trunk/test/FrontendC++/integration-O2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/integration-O2.cpp?rev=85907&r1=85906&r2=85907&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/integration-O2.cpp (original) +++ llvm/trunk/test/FrontendC++/integration-O2.cpp Tue Nov 3 11:54:12 2009 @@ -1,4 +1,5 @@ // RUN: %llvmgxx %s -O2 -S -o - | FileCheck %s +// XFAIL: * // This test verifies that we get expected codegen out of the -O2 optimization // level from the full optimizer. From dpatel at apple.com Tue Nov 3 12:30:28 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 03 Nov 2009 18:30:28 -0000 Subject: [llvm-commits] [llvm] r85909 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200911031830.nA3IUStM020955@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 3 12:30:27 2009 New Revision: 85909 URL: http://llvm.org/viewvc/llvm-project?rev=85909&view=rev Log: Ignore unnamed variables. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=85909&r1=85908&r2=85909&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Nov 3 12:30:27 2009 @@ -1249,6 +1249,9 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { // Get the descriptor. const DIVariable &VD = DV->getVariable(); + const char *Name = VD.getName(); + if (!Name) + return NULL; // Translate tag to proper Dwarf tag. The result variable is dropped for // now. @@ -1267,7 +1270,6 @@ // Define variable debug information entry. DIE *VariableDie = new DIE(Tag); - const char *Name = VD.getName(); AddString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); // Add source line info if available. From sabre at nondot.org Tue Nov 3 12:30:31 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 18:30:31 -0000 Subject: [llvm-commits] [llvm] r85910 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200911031830.nA3IUVTj020969@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 12:30:31 2009 New Revision: 85910 URL: http://llvm.org/viewvc/llvm-project?rev=85910&view=rev Log: mark some constant global const. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=85910&r1=85909&r2=85910&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Tue Nov 3 12:30:31 2009 @@ -28,7 +28,6 @@ using namespace llvm; -namespace { //===----------------------------------------------------------------------===// /// Typedefs @@ -40,16 +39,18 @@ /// Constants // Indentation. -unsigned TabWidth = 4; -unsigned Indent1 = TabWidth*1; -unsigned Indent2 = TabWidth*2; -unsigned Indent3 = TabWidth*3; +static const unsigned TabWidth = 4; +static const unsigned Indent1 = TabWidth*1; +static const unsigned Indent2 = TabWidth*2; +static const unsigned Indent3 = TabWidth*3; // Default help string. -const char * DefaultHelpString = "NO HELP MESSAGE PROVIDED"; +static const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED"; // Name for the "sink" option. -const char * SinkOptionName = "AutoGeneratedSinkOption"; +static const char * const SinkOptionName = "AutoGeneratedSinkOption"; + +namespace { //===----------------------------------------------------------------------===// /// Helper functions From asl at math.spbu.ru Tue Nov 3 12:46:11 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 03 Nov 2009 18:46:11 -0000 Subject: [llvm-commits] [llvm] r85914 - in /llvm/trunk/lib/Target/ARM: ARMTargetMachine.cpp NEONMoveFix.cpp Message-ID: <200911031846.nA3IkBep021543@zion.cs.uiuc.edu> Author: asl Date: Tue Nov 3 12:46:11 2009 New Revision: 85914 URL: http://llvm.org/viewvc/llvm-project?rev=85914&view=rev Log: Move subtarget check upper for NEON reg-reg fixup pass. Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp?rev=85914&r1=85913&r2=85914&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Tue Nov 3 12:46:11 2009 @@ -115,7 +115,8 @@ if (OptLevel != CodeGenOpt::None) { if (!Subtarget.isThumb1Only()) PM.add(createIfConverterPass()); - PM.add(createNEONMoveFixPass()); + if (Subtarget.hasNEON()) + PM.add(createNEONMoveFixPass()); } if (Subtarget.isThumb2()) { Modified: llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp?rev=85914&r1=85913&r2=85914&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp (original) +++ llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp Tue Nov 3 12:46:11 2009 @@ -35,7 +35,6 @@ private: const TargetRegisterInfo *TRI; const ARMBaseInstrInfo *TII; - const ARMSubtarget *Subtarget; typedef DenseMap RegMap; @@ -71,7 +70,7 @@ Domain = ARMII::DomainNEON; } - if ((Domain & ARMII::DomainNEON) && Subtarget->hasNEON()) { + if (Domain & ARMII::DomainNEON) { // Convert FCPYD to VMOVD. unsigned DestReg = MI->getOperand(0).getReg(); @@ -93,8 +92,7 @@ Modified = true; ++NumVMovs; } else { - assert((Domain & ARMII::DomainVFP || - !Subtarget->hasNEON()) && "Invalid domain!"); + assert((Domain & ARMII::DomainVFP) && "Invalid domain!"); // Do nothing. } } @@ -124,7 +122,6 @@ return false; TRI = TM.getRegisterInfo(); - Subtarget = &TM.getSubtarget(); TII = static_cast(TM.getInstrInfo()); bool Modified = false; From baldrick at free.fr Tue Nov 3 12:57:43 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 03 Nov 2009 18:57:43 -0000 Subject: [llvm-commits] [dragonegg] r85915 - /dragonegg/trunk/llvm-types.cpp Message-ID: <200911031857.nA3IvhHX021984@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 3 12:57:42 2009 New Revision: 85915 URL: http://llvm.org/viewvc/llvm-project?rev=85915&view=rev Log: In a qualified union, the smallest field needs to be chosen. This ensures that the LLVM type will be smaller than the smallest possible size achievable by the GCC type (which is of variable size), an important invariant for Ada. While there, for normal unions choose the field with the largest size, rather than the field with the largest alignment. I think the previous alignment choice was an attempt to help out the old constructor code, which had many assumptions about alignment. Modified: dragonegg/trunk/llvm-types.cpp Modified: dragonegg/trunk/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-types.cpp?rev=85915&r1=85914&r2=85915&view=diff ============================================================================== --- dragonegg/trunk/llvm-types.cpp (original) +++ dragonegg/trunk/llvm-types.cpp Tue Nov 3 12:57:42 2009 @@ -1854,13 +1854,17 @@ /// then we will add padding later on anyway to match union size. void TypeConverter::SelectUnionMember(tree type, StructTypeConversionInfo &Info) { + bool FindBiggest = TREE_CODE(type) != QUAL_UNION_TYPE; + const Type *UnionTy = 0; tree GccUnionTy = 0; tree UnionField = 0; - unsigned MaxAlignSize = 0, MaxAlign = 0; + unsigned MinAlign = ~0U; + uint64_t BestSize = FindBiggest ? 0ULL : ~0ULL; for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) { if (TREE_CODE(Field) != FIELD_DECL) continue; - assert(getFieldOffsetInBits(Field) == 0 && "Union with non-zero offset?"); + assert(DECL_FIELD_OFFSET(Field) && integer_zerop(DECL_FIELD_OFFSET(Field)) + && "Union with non-zero offset?"); // Skip fields that are known not to be present. if (TREE_CODE(type) == QUAL_UNION_TYPE && @@ -1869,29 +1873,29 @@ tree TheGccTy = TREE_TYPE(Field); - // Skip zero-length fields; ConvertType refuses to construct a type - // of size 0. - if (DECL_SIZE(Field) && - TREE_CODE(DECL_SIZE(Field)) == INTEGER_CST && - TREE_INT_CST_LOW(DECL_SIZE(Field)) == 0) + // Skip zero-length bitfields. These are only used for setting the + // alignment. + if (DECL_BIT_FIELD(Field) && DECL_SIZE(Field) && + integer_zerop(DECL_SIZE(Field))) continue; const Type *TheTy = ConvertType(TheGccTy); - unsigned Size = Info.getTypeSize(TheTy); unsigned Align = Info.getTypeAlignment(TheTy); + uint64_t Size = Info.getTypeSize(TheTy); adjustPaddingElement(GccUnionTy, TheGccTy); - // Select TheTy as union type if it is more aligned than any other. If - // more than one field achieves the maximum alignment then choose the - // biggest. - if (UnionTy == 0 || Align > MaxAlign || - (Align == MaxAlign && Size > MaxAlignSize)) { + // Select TheTy as union type if it is the biggest/smallest field (depending + // on the value of FindBiggest). If more than one field achieves this size + // then choose the least aligned. + if ((Size == BestSize && Align < MinAlign) || + (FindBiggest && Size > BestSize) || + (!FindBiggest && Size < BestSize)) { UnionTy = TheTy; UnionField = Field; GccUnionTy = TheGccTy; - MaxAlignSize = Size; - MaxAlign = Align; + BestSize = Size; + MinAlign = Align; } // Skip remaining fields if this one is known to be present. From dpatel at apple.com Tue Nov 3 13:06:07 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 03 Nov 2009 19:06:07 -0000 Subject: [llvm-commits] [llvm] r85921 - in /llvm/trunk: lib/AsmParser/LLParser.cpp test/DebugInfo/2009-11-03-InsertExtractValue.ll Message-ID: <200911031906.nA3J68oi022376@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 3 13:06:07 2009 New Revision: 85921 URL: http://llvm.org/viewvc/llvm-project?rev=85921&view=rev Log: Parse debug info attached with insertvalue and extractvalue instructions. Added: llvm/trunk/test/DebugInfo/2009-11-03-InsertExtractValue.ll Modified: llvm/trunk/lib/AsmParser/LLParser.cpp Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=85921&r1=85920&r2=85921&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Nov 3 13:06:07 2009 @@ -1137,6 +1137,8 @@ return TokError("expected ',' as start of index list"); while (EatIfPresent(lltok::comma)) { + if (Lex.getKind() == lltok::NamedOrCustomMD) + break; unsigned Idx; if (ParseUInt32(Idx)) return true; Indices.push_back(Idx); @@ -2111,6 +2113,9 @@ ParseIndexList(Indices) || ParseToken(lltok::rparen, "expected ')' in extractvalue constantexpr")) return true; + if (Lex.getKind() == lltok::NamedOrCustomMD) + if (ParseOptionalCustomMetadata()) return true; + if (!isa(Val->getType()) && !isa(Val->getType())) return Error(ID.Loc, "extractvalue operand must be array or struct"); if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(), @@ -2132,6 +2137,8 @@ ParseIndexList(Indices) || ParseToken(lltok::rparen, "expected ')' in insertvalue constantexpr")) return true; + if (Lex.getKind() == lltok::NamedOrCustomMD) + if (ParseOptionalCustomMetadata()) return true; if (!isa(Val0->getType()) && !isa(Val0->getType())) return Error(ID.Loc, "extractvalue operand must be array or struct"); if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(), @@ -3737,6 +3744,8 @@ if (ParseTypeAndValue(Val, Loc, PFS) || ParseIndexList(Indices)) return true; + if (Lex.getKind() == lltok::NamedOrCustomMD) + if (ParseOptionalCustomMetadata()) return true; if (!isa(Val->getType()) && !isa(Val->getType())) return Error(Loc, "extractvalue operand must be array or struct"); @@ -3758,6 +3767,8 @@ ParseTypeAndValue(Val1, Loc1, PFS) || ParseIndexList(Indices)) return true; + if (Lex.getKind() == lltok::NamedOrCustomMD) + if (ParseOptionalCustomMetadata()) return true; if (!isa(Val0->getType()) && !isa(Val0->getType())) return Error(Loc0, "extractvalue operand must be array or struct"); Added: llvm/trunk/test/DebugInfo/2009-11-03-InsertExtractValue.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-11-03-InsertExtractValue.ll?rev=85921&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-11-03-InsertExtractValue.ll (added) +++ llvm/trunk/test/DebugInfo/2009-11-03-InsertExtractValue.ll Tue Nov 3 13:06:07 2009 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +!0 = metadata !{i32 42} + +define <{i32, i32}> @f1() { +; CHECK: !dbg !0 + %r = insertvalue <{ i32, i32 }> zeroinitializer, i32 4, 1, !dbg !0 +; CHECK: !dbg !0 + %e = extractvalue <{ i32, i32 }> %r, 0, !dbg !0 + ret <{ i32, i32 }> %r +} From baldrick at free.fr Tue Nov 3 13:10:22 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 03 Nov 2009 19:10:22 -0000 Subject: [llvm-commits] [llvm] r85922 - /llvm/trunk/lib/Support/MemoryBuffer.cpp Message-ID: <200911031910.nA3JAM5b022573@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 3 13:10:22 2009 New Revision: 85922 URL: http://llvm.org/viewvc/llvm-project?rev=85922&view=rev Log: Make this code more robust by not thinking we are making progress if zero bytes were read. Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryBuffer.cpp?rev=85922&r1=85921&r2=85922&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Tue Nov 3 13:10:22 2009 @@ -226,7 +226,7 @@ size_t BytesLeft = FileSize; while (BytesLeft) { ssize_t NumRead = ::read(FD, BufPtr, BytesLeft); - if (NumRead != -1) { + if (NumRead > 0) { BytesLeft -= NumRead; BufPtr += NumRead; } else if (errno == EINTR) { From sabre at nondot.org Tue Nov 3 13:24:52 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 19:24:52 -0000 Subject: [llvm-commits] [llvm] r85923 - in /llvm/trunk: lib/Transforms/Scalar/SCCP.cpp test/Transforms/SCCP/ipsccp-basic.ll Message-ID: <200911031924.nA3JOqcx023129@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 13:24:51 2009 New Revision: 85923 URL: http://llvm.org/viewvc/llvm-project?rev=85923&view=rev Log: fix an IPSCCP bug I introduced when I changed IPSCCP to start working on functions that don't have local linkage. Basically, we need to be more careful about propagating argument information to functions whose results we aren't tracking. This fixes a miscompilation of LLVMCConfigurationEmitter.cpp when built with an llvm-gcc that has ipsccp enabled. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85923&r1=85922&r2=85923&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Tue Nov 3 13:24:51 2009 @@ -174,6 +174,9 @@ /// that return multiple values. DenseMap, LatticeVal> TrackedMultipleRetVals; + /// TrackingIncomingArguments - This is the set of functions that are + SmallPtrSet TrackingIncomingArguments; + /// The reason for two worklists is that overdefined is the lowest state /// on the lattice, and moving things to overdefined as fast as possible /// makes SCCP converge much faster. @@ -235,6 +238,10 @@ TrackedRetVals.insert(std::make_pair(F, LatticeVal())); } + void AddArgumentTrackedFunction(Function *F) { + TrackingIncomingArguments.insert(F); + } + /// Solve - Solve for constants and executable blocks. /// void Solve(); @@ -1190,6 +1197,27 @@ return markOverdefined(I); } + // If this is a local function that doesn't have its address taken, mark its + // entry block executable and merge in the actual arguments to the call into + // the formal arguments of the function. + if (!TrackingIncomingArguments.empty() && TrackingIncomingArguments.count(F)){ + MarkBlockExecutable(F->begin()); + + // Propagate information from this call site into the callee. + CallSite::arg_iterator CAI = CS.arg_begin(); + for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); + AI != E; ++AI, ++CAI) { + // If this argument is byval, and if the function is not readonly, there + // will be an implicit copy formed of the input aggregate. + if (AI->hasByValAttr() && !F->onlyReadsMemory()) { + markOverdefined(AI); + continue; + } + + mergeInValue(AI, getValueState(*CAI)); + } + } + // If this is a single/zero retval case, see if we're tracking the function. DenseMap::iterator TFRVI = TrackedRetVals.find(F); if (TFRVI != TrackedRetVals.end()) { @@ -1228,24 +1256,6 @@ // common path above. goto CallOverdefined; } - - // Finally, if this is the first call to the function hit, mark its entry - // block executable. - MarkBlockExecutable(F->begin()); - - // Propagate information from this call site into the callee. - CallSite::arg_iterator CAI = CS.arg_begin(); - for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); - AI != E; ++AI, ++CAI) { - // If this argument is byval, and if the function is not readonly, there - // will be an implicit copy formed of the input aggregate. - if (AI->hasByValAttr() && !F->onlyReadsMemory()) { - markOverdefined(AI); - continue; - } - - mergeInValue(AI, getValueState(*CAI)); - } } void SCCPSolver::Solve() { @@ -1656,8 +1666,10 @@ // If this function only has direct calls that we can see, we can track its // arguments and return value aggressively, and can assume it is not called // unless we see evidence to the contrary. - if (F->hasLocalLinkage() && !AddressIsTaken(F)) + if (F->hasLocalLinkage() && !AddressIsTaken(F)) { + Solver.AddArgumentTrackedFunction(F); continue; + } // Assume the function is called. Solver.MarkBlockExecutable(F->begin()); Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll?rev=85923&r1=85922&r2=85923&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll (original) +++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Tue Nov 3 13:24:51 2009 @@ -174,4 +174,24 @@ ; CHECK-NEXT: ret i32 36 } +;;======================== test8 + + +define internal {} @test8a(i32 %A, i32* %P) { + store i32 %A, i32* %P + ret {} {} +; CHECK: @test8a +; CHECK-NEXT: store i32 5, +; CHECK-NEXT: ret +} + +define void @test8b(i32* %P) { + %X = call {} @test8a(i32 5, i32* %P) + ret void +; CHECK: define void @test8b +; CHECK-NEXT: call {} @test8a +; CHECK-NEXT: ret void +} + + From gohman at apple.com Tue Nov 3 13:28:48 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 3 Nov 2009 11:28:48 -0800 Subject: [llvm-commits] [llvm] r85922 - /llvm/trunk/lib/Support/MemoryBuffer.cpp In-Reply-To: <200911031910.nA3JAM5b022573@zion.cs.uiuc.edu> References: <200911031910.nA3JAM5b022573@zion.cs.uiuc.edu> Message-ID: Hi Duncan, On Nov 3, 2009, at 11:10 AM, Duncan Sands wrote: > --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) > +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Tue Nov 3 13:10:22 2009 > @@ -226,7 +226,7 @@ > size_t BytesLeft = FileSize; > while (BytesLeft) { > ssize_t NumRead = ::read(FD, BufPtr, BytesLeft); > - if (NumRead != -1) { > + if (NumRead > 0) { > BytesLeft -= NumRead; > BufPtr += NumRead; > } else if (errno == EINTR) { Given this, the code should explicitly set errno to 0 so that it doesn't infinite loop if it reaches the end of the file and errno happens to have the value EINTR. Dan From sabre at nondot.org Tue Nov 3 13:35:13 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 19:35:13 -0000 Subject: [llvm-commits] [llvm] r85929 - in /llvm/trunk: include/llvm/Support/StandardPasses.h test/FrontendC++/integration-O2.cpp Message-ID: <200911031935.nA3JZEQC023567@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 13:35:13 2009 New Revision: 85929 URL: http://llvm.org/viewvc/llvm-project?rev=85929&view=rev Log: turn IPSCCP back on by default, try #3 or 4? Woo. Modified: llvm/trunk/include/llvm/Support/StandardPasses.h llvm/trunk/test/FrontendC++/integration-O2.cpp Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=85929&r1=85928&r2=85929&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Tue Nov 3 13:35:13 2009 @@ -99,8 +99,7 @@ if (UnitAtATime) { PM->add(createGlobalOptimizerPass()); // Optimize out global vars - PM->add(createIPConstantPropagationPass()); // IP CP -// PM->add(createIPSCCPPass()); // IP SCCP + PM->add(createIPSCCPPass()); // IP SCCP PM->add(createDeadArgEliminationPass()); // Dead argument elimination } PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE Modified: llvm/trunk/test/FrontendC++/integration-O2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/integration-O2.cpp?rev=85929&r1=85928&r2=85929&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/integration-O2.cpp (original) +++ llvm/trunk/test/FrontendC++/integration-O2.cpp Tue Nov 3 13:35:13 2009 @@ -1,5 +1,4 @@ // RUN: %llvmgxx %s -O2 -S -o - | FileCheck %s -// XFAIL: * // This test verifies that we get expected codegen out of the -O2 optimization // level from the full optimizer. From vhernandez at apple.com Tue Nov 3 14:02:36 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 03 Nov 2009 20:02:36 -0000 Subject: [llvm-commits] [llvm] r85933 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Message-ID: <200911032002.nA3K2aSe024624@zion.cs.uiuc.edu> Author: hernande Date: Tue Nov 3 14:02:35 2009 New Revision: 85933 URL: http://llvm.org/viewvc/llvm-project?rev=85933&view=rev Log: Changes (* location in pointer variables, avoiding include, and using APInt::getLimitedValue) based on feedback to r85814 Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=85933&r1=85932&r2=85933&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Tue Nov 3 14:02:35 2009 @@ -16,7 +16,6 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Module.h" -#include "llvm/ADT/APInt.h" #include "llvm/Analysis/ConstantFolding.h" using namespace llvm; @@ -26,7 +25,7 @@ /// isMalloc - Returns true if the the value is either a malloc call or a /// bitcast of the result of a malloc call. -bool llvm::isMalloc(const Value* I) { +bool llvm::isMalloc(const Value *I) { return extractMallocCall(I) || extractMallocCallFromBitCast(I); } @@ -34,7 +33,7 @@ if (!CI) return false; - const Module* M = CI->getParent()->getParent()->getParent(); + const Module *M = CI->getParent()->getParent()->getParent(); Function *MallocFunc = M->getFunction("malloc"); if (CI->getOperand(0) != MallocFunc) @@ -58,17 +57,17 @@ /// extractMallocCall - Returns the corresponding CallInst if the instruction /// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we /// ignore InvokeInst here. -const CallInst* llvm::extractMallocCall(const Value* I) { +const CallInst *llvm::extractMallocCall(const Value *I) { const CallInst *CI = dyn_cast(I); return (isMallocCall(CI)) ? CI : NULL; } -CallInst* llvm::extractMallocCall(Value* I) { +CallInst *llvm::extractMallocCall(Value *I) { CallInst *CI = dyn_cast(I); return (isMallocCall(CI)) ? CI : NULL; } -static bool isBitCastOfMallocCall(const BitCastInst* BCI) { +static bool isBitCastOfMallocCall(const BitCastInst *BCI) { if (!BCI) return false; @@ -77,13 +76,13 @@ /// extractMallocCallFromBitCast - Returns the corresponding CallInst if the /// instruction is a bitcast of the result of a malloc call. -CallInst* llvm::extractMallocCallFromBitCast(Value* I) { +CallInst *llvm::extractMallocCallFromBitCast(Value *I) { BitCastInst *BCI = dyn_cast(I); return (isBitCastOfMallocCall(BCI)) ? cast(BCI->getOperand(0)) : NULL; } -const CallInst* llvm::extractMallocCallFromBitCast(const Value* I) { +const CallInst *llvm::extractMallocCallFromBitCast(const Value *I) { const BitCastInst *BCI = dyn_cast(I); return (isBitCastOfMallocCall(BCI)) ? cast(BCI->getOperand(0)) : NULL; @@ -94,21 +93,21 @@ return isa(val) && cast(val)->isOne(); } -static Value* isArrayMallocHelper(const CallInst *CI, LLVMContext &Context, - const TargetData* TD) { +static Value *isArrayMallocHelper(const CallInst *CI, LLVMContext &Context, + const TargetData *TD) { if (!CI) return NULL; // Type must be known to determine array size. - const Type* T = getMallocAllocatedType(CI); + const Type *T = getMallocAllocatedType(CI); if (!T) return NULL; - Value* MallocArg = CI->getOperand(1); - ConstantExpr* CO = dyn_cast(MallocArg); - BinaryOperator* BO = dyn_cast(MallocArg); + Value *MallocArg = CI->getOperand(1); + ConstantExpr *CO = dyn_cast(MallocArg); + BinaryOperator *BO = dyn_cast(MallocArg); - Constant* ElementSize = ConstantExpr::getSizeOf(T); + Constant *ElementSize = ConstantExpr::getSizeOf(T); ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, MallocArg->getType()); Constant *FoldedElementSize = @@ -128,8 +127,8 @@ if (!CO && !BO) return NULL; - Value* Op0 = NULL; - Value* Op1 = NULL; + Value *Op0 = NULL; + Value *Op1 = NULL; unsigned Opcode = 0; if (CO && ((CO->getOpcode() == Instruction::Mul) || (CO->getOpcode() == Instruction::Shl))) { @@ -157,17 +156,13 @@ return Op1; } if (Opcode == Instruction::Shl) { - ConstantInt* Op1CI = dyn_cast(Op1); + ConstantInt *Op1CI = dyn_cast(Op1); if (!Op1CI) return NULL; APInt Op1Int = Op1CI->getValue(); - unsigned Op1Width = Op1Int.getBitWidth(); - // check for overflow - if (Op1Int.getActiveBits() > 64 || Op1Int.getZExtValue() > Op1Width) - return NULL; - Value* Op1Pow = ConstantInt::get(Context, - APInt(Op1Width, 0).set(Op1Int.getZExtValue())); - + uint64_t BitToSet = Op1Int.getLimitedValue(Op1Int.getBitWidth() - 1); + Value *Op1Pow = ConstantInt::get(Context, + APInt(Op1Int.getBitWidth(), 0).set(BitToSet)); if (Op0 == ElementSize || (FoldedElementSize && Op0 == FoldedElementSize)) // ArraySize << log2(ElementSize) return Op1Pow; @@ -185,10 +180,10 @@ /// isArrayMalloc - Returns the corresponding CallInst if the instruction /// is a call to malloc whose array size can be determined and the array size /// is not constant 1. Otherwise, return NULL. -CallInst* llvm::isArrayMalloc(Value* I, LLVMContext &Context, - const TargetData* TD) { +CallInst *llvm::isArrayMalloc(Value *I, LLVMContext &Context, + const TargetData *TD) { CallInst *CI = extractMallocCall(I); - Value* ArraySize = isArrayMallocHelper(CI, Context, TD); + Value *ArraySize = isArrayMallocHelper(CI, Context, TD); if (ArraySize && ArraySize != ConstantInt::get(CI->getOperand(1)->getType(), 1)) @@ -198,10 +193,10 @@ return NULL; } -const CallInst* llvm::isArrayMalloc(const Value* I, LLVMContext &Context, - const TargetData* TD) { +const CallInst *llvm::isArrayMalloc(const Value *I, LLVMContext &Context, + const TargetData *TD) { const CallInst *CI = extractMallocCall(I); - Value* ArraySize = isArrayMallocHelper(CI, Context, TD); + Value *ArraySize = isArrayMallocHelper(CI, Context, TD); if (ArraySize && ArraySize != ConstantInt::get(CI->getOperand(1)->getType(), 1)) @@ -214,10 +209,10 @@ /// getMallocType - Returns the PointerType resulting from the malloc call. /// This PointerType is the result type of the call's only bitcast use. /// If there is no unique bitcast use, then return NULL. -const PointerType* llvm::getMallocType(const CallInst* CI) { +const PointerType *llvm::getMallocType(const CallInst *CI) { assert(isMalloc(CI) && "GetMallocType and not malloc call"); - const BitCastInst* BCI = NULL; + const BitCastInst *BCI = NULL; // Determine if CallInst has a bitcast use. for (Value::use_const_iterator UI = CI->use_begin(), E = CI->use_end(); @@ -241,8 +236,8 @@ /// getMallocAllocatedType - Returns the Type allocated by malloc call. This /// Type is the result type of the call's only bitcast use. If there is no /// unique bitcast use, then return NULL. -const Type* llvm::getMallocAllocatedType(const CallInst* CI) { - const PointerType* PT = getMallocType(CI); +const Type *llvm::getMallocAllocatedType(const CallInst *CI) { + const PointerType *PT = getMallocType(CI); return PT ? PT->getElementType() : NULL; } @@ -251,8 +246,8 @@ /// then return that multiple. For non-array mallocs, the multiple is /// constant 1. Otherwise, return NULL for mallocs whose array size cannot be /// determined. -Value* llvm::getMallocArraySize(CallInst* CI, LLVMContext &Context, - const TargetData* TD) { +Value *llvm::getMallocArraySize(CallInst *CI, LLVMContext &Context, + const TargetData *TD) { return isArrayMallocHelper(CI, Context, TD); } @@ -261,12 +256,12 @@ // /// isFreeCall - Returns true if the the value is a call to the builtin free() -bool llvm::isFreeCall(const Value* I) { +bool llvm::isFreeCall(const Value *I) { const CallInst *CI = dyn_cast(I); if (!CI) return false; - const Module* M = CI->getParent()->getParent()->getParent(); + const Module *M = CI->getParent()->getParent()->getParent(); Function *FreeFunc = M->getFunction("free"); if (CI->getOperand(0) != FreeFunc) From baldrick at free.fr Tue Nov 3 14:08:31 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 03 Nov 2009 21:08:31 +0100 Subject: [llvm-commits] [llvm] r85922 - /llvm/trunk/lib/Support/MemoryBuffer.cpp In-Reply-To: References: <200911031910.nA3JAM5b022573@zion.cs.uiuc.edu> Message-ID: <4AF08DBF.7090005@free.fr> Hi Dan, >> --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) >> +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Tue Nov 3 13:10:22 2009 >> @@ -226,7 +226,7 @@ >> size_t BytesLeft = FileSize; >> while (BytesLeft) { >> ssize_t NumRead = ::read(FD, BufPtr, BytesLeft); >> - if (NumRead != -1) { >> + if (NumRead > 0) { >> BytesLeft -= NumRead; >> BufPtr += NumRead; >> } else if (errno == EINTR) { > > Given this, the code should explicitly set errno to 0 so that it doesn't > infinite loop if it reaches the end of the file and errno happens to > have the value EINTR. if errno is EINTR, isn't it correct to go around again, even if zero bytes were read? Ciao, Duncan. From asl at math.spbu.ru Tue Nov 3 14:09:19 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 3 Nov 2009 23:09:19 +0300 Subject: [llvm-commits] [llvm] r85850 - in /llvm/trunk/lib/Target/ARM: ARM.h ARMBaseInstrInfo.cpp ARMTargetMachine.cpp NEONMoveFix.cpp In-Reply-To: <1C12EC22-892A-4F26-8005-B2AD1EBEDBC8@apple.com> References: <200911030104.nA314RYX031608@zion.cs.uiuc.edu> <1C12EC22-892A-4F26-8005-B2AD1EBEDBC8@apple.com> Message-ID: > Please make sure this is run only when NEON is available. Done. Actually, there was already a check inside - I moved it upper. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From david_goodwin at apple.com Tue Nov 3 14:15:00 2009 From: david_goodwin at apple.com (David Goodwin) Date: Tue, 03 Nov 2009 20:15:00 -0000 Subject: [llvm-commits] [llvm] r85934 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200911032015.nA3KF0LW025030@zion.cs.uiuc.edu> Author: david_goodwin Date: Tue Nov 3 14:15:00 2009 New Revision: 85934 URL: http://llvm.org/viewvc/llvm-project?rev=85934&view=rev Log: . When building schedule graph use mayAlias information to avoid chaining loads/stores of spill slots with non-aliased memory ops. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=85934&r1=85933&r2=85934&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Tue Nov 3 14:15:00 2009 @@ -98,7 +98,9 @@ /// information and it can be tracked to a normal reference to a known /// object, return the Value for that object. Otherwise return null. static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI, - const MachineFrameInfo *MFI) { + const MachineFrameInfo *MFI, + bool &MayAlias) { + MayAlias = true; if (!MI->hasOneMemOperand() || !(*MI->memoperands_begin())->getValue() || (*MI->memoperands_begin())->isVolatile()) @@ -110,6 +112,7 @@ V = getUnderlyingObject(V); if (const PseudoSourceValue *PSV = dyn_cast(V)) { + MayAlias = PSV->mayAlias(MFI); // For now, ignore PseudoSourceValues which may alias LLVM IR values // because the code that uses this function has no way to cope with // such aliases. @@ -124,6 +127,23 @@ return 0; } +static bool mayUnderlyingObjectForInstrAlias(const MachineInstr *MI, + const MachineFrameInfo *MFI) { + if (!MI->hasOneMemOperand() || + !(*MI->memoperands_begin())->getValue() || + (*MI->memoperands_begin())->isVolatile()) + return true; + + const Value *V = (*MI->memoperands_begin())->getValue(); + if (!V) + return true; + + V = getUnderlyingObject(V); + if (const PseudoSourceValue *PSV = dyn_cast(V)) + return PSV->mayAlias(MFI); + return true; +} + void ScheduleDAGInstrs::StartBlock(MachineBasicBlock *BB) { if (MachineLoop *ML = MLI.getLoopFor(BB)) if (BB == ML->getLoopLatch()) { @@ -362,8 +382,9 @@ // Unknown memory accesses. Assume the worst. ChainMMO = 0; } else if (TID.mayStore()) { + bool MayAlias = true; TrueMemOrderLatency = STORE_LOAD_LATENCY; - if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) { + if (const Value *V = getUnderlyingObjectForInstr(MI, MFI, MayAlias)) { // A store to a specific PseudoSourceValue. Add precise dependencies. // Handle the def in MemDefs, if there is one. std::map::iterator I = MemDefs.find(V); @@ -383,22 +404,26 @@ /*Reg=*/0, /*isNormalMemory=*/true)); J->second.clear(); } - // Add dependencies from all the PendingLoads, since without - // memoperands we must assume they alias anything. - for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) - PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); - // Add a general dependence too, if needed. - if (Chain) - Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); - } else { + if (MayAlias) { + // Add dependencies from all the PendingLoads, since without + // memoperands we must assume they alias anything. + for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) + PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); + // Add a general dependence too, if needed. + if (Chain) + Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + } + } else if (MayAlias) { // Treat all other stores conservatively. goto new_chain; } } else if (TID.mayLoad()) { + bool MayAlias = true; TrueMemOrderLatency = 0; if (MI->isInvariantLoad(AA)) { // Invariant load, no chain dependencies needed! - } else if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) { + } else if (const Value *V = + getUnderlyingObjectForInstr(MI, MFI, MayAlias)) { // A load from a specific PseudoSourceValue. Add precise dependencies. std::map::iterator I = MemDefs.find(V); if (I != MemDefs.end()) @@ -414,16 +439,19 @@ // Treat volatile loads conservatively. Note that this includes // cases where memoperand information is unavailable. goto new_chain; - } else { - // A normal load. Depend on the general chain, as well as on + } else if (MayAlias) { + // A "MayAlias" load. Depend on the general chain, as well as on // all stores. In the absense of MachineMemOperand information, // we can't even assume that the load doesn't alias well-behaved // memory locations. if (Chain) Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); for (std::map::iterator I = MemDefs.begin(), - E = MemDefs.end(); I != E; ++I) - I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + E = MemDefs.end(); I != E; ++I) { + SUnit *DefSU = I->second; + if (mayUnderlyingObjectForInstrAlias(DefSU->getInstr(), MFI)) + DefSU->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); + } PendingLoads.push_back(SU); } } From vhernandez at apple.com Tue Nov 3 14:16:37 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 3 Nov 2009 12:16:37 -0800 Subject: [llvm-commits] [llvm] r85814 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp In-Reply-To: References: <200911021851.nA2IpTYX014735@zion.cs.uiuc.edu> Message-ID: <5AF1EA0B-5B79-43C8-8A85-8088DD84333D@apple.com> Fixed these in r85933. Victor On Nov 2, 2009, at 8:29 PM, Chris Lattner wrote: > On Nov 2, 2009, at 10:51 AM, Victor Hernandez wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=85814&view=rev >> Log: >> Set bit instead of calling pow() to compute 2 << n > > Thanks Victor, > >> +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Mon Nov 2 12:51:28 >> 2009 >> @@ -16,6 +16,7 @@ >> #include "llvm/Constants.h" >> #include "llvm/Instructions.h" >> #include "llvm/Module.h" >> +#include "llvm/ADT/APInt.h" > > You don't need this #include, please remove it. > >> @@ -156,15 +157,22 @@ >> return Op1; >> } >> if (Opcode == Instruction::Shl) { >> - ConstantInt* Op1Int = dyn_cast(Op1); >> - if (!Op1Int) return NULL; >> - Value* Op1Pow = ConstantInt::get(Op1->getType(), (uint64_t) >> - pow(2.0, (double) Op1Int- >> >getZExtValue())); >> + ConstantInt* Op1CI = dyn_cast(Op1); >> + if (!Op1CI) return NULL; >> + >> + APInt Op1Int = Op1CI->getValue(); >> + unsigned Op1Width = Op1Int.getBitWidth(); >> + // check for overflow >> + if (Op1Int.getActiveBits() > 64 || Op1Int.getZExtValue() > >> Op1Width) >> + return NULL; > > If the shift overflows, the original code is undefined. Please just > use the APInt::getLimitedValue method (with the bitwidth as the > argument) to handle this. You'll end up with much more elegant code. > > Finally, please use: > > ConstantInt *Op1CI > instead of: > ConstantInt* Op1CI > > With Op1CI and many other variables in this file. > > Thanks, > > -Chris > > > >> + Value* Op1Pow = ConstantInt::get(Context, >> + APInt(Op1Width, 0).set >> (Op1Int.getZExtValue())); >> + >> if (Op0 == ElementSize || (FoldedElementSize && Op0 == >> FoldedElementSize)) >> // ArraySize << log2(ElementSize) >> return Op1Pow; >> if (Op1Pow == ElementSize || >> - (FoldedElementSize && Op1Pow == FoldedElementSize)) >> + (FoldedElementSize && Op1Pow == FoldedElementSize)) >> // ElementSize << log2(ArraySize) >> return Op0; >> } >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091103/20d4b82b/attachment.html From baldrick at free.fr Tue Nov 3 14:16:35 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 03 Nov 2009 21:16:35 +0100 Subject: [llvm-commits] [llvm] r85923 - in /llvm/trunk: lib/Transforms/Scalar/SCCP.cpp test/Transforms/SCCP/ipsccp-basic.ll In-Reply-To: <200911031924.nA3JOqcx023129@zion.cs.uiuc.edu> References: <200911031924.nA3JOqcx023129@zion.cs.uiuc.edu> Message-ID: <4AF08FA3.2050909@free.fr> Hi Chris, > + /// TrackingIncomingArguments - This is the set of functions that are incomplete comment. Ciao, Duncan. From vhernandez at apple.com Tue Nov 3 14:39:35 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 03 Nov 2009 20:39:35 -0000 Subject: [llvm-commits] [llvm] r85936 - in /llvm/trunk/lib: Analysis/MemoryBuiltins.cpp VMCore/Instruction.cpp Message-ID: <200911032039.nA3KdZuW026026@zion.cs.uiuc.edu> Author: hernande Date: Tue Nov 3 14:39:35 2009 New Revision: 85936 URL: http://llvm.org/viewvc/llvm-project?rev=85936&view=rev Log: Changes requested (avoid getFunction(), avoid Type creation via isVoidTy(), and avoid redundant isFreeCall cases) in feedback to r85176 Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp llvm/trunk/lib/VMCore/Instruction.cpp Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=85936&r1=85935&r2=85936&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Tue Nov 3 14:39:35 2009 @@ -33,16 +33,14 @@ if (!CI) return false; - const Module *M = CI->getParent()->getParent()->getParent(); - Function *MallocFunc = M->getFunction("malloc"); - - if (CI->getOperand(0) != MallocFunc) + Function *Callee = CI->getCalledFunction(); + if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "malloc") return false; // Check malloc prototype. // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin // attribute will exist. - const FunctionType *FTy = MallocFunc->getFunctionType(); + const FunctionType *FTy = Callee->getFunctionType(); if (FTy->getNumParams() != 1) return false; if (IntegerType *ITy = dyn_cast(FTy->param_begin()->get())) { @@ -260,22 +258,19 @@ const CallInst *CI = dyn_cast(I); if (!CI) return false; - - const Module *M = CI->getParent()->getParent()->getParent(); - Function *FreeFunc = M->getFunction("free"); - - if (CI->getOperand(0) != FreeFunc) + Function *Callee = CI->getCalledFunction(); + if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "free") return false; // Check free prototype. // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin // attribute will exist. - const FunctionType *FTy = FreeFunc->getFunctionType(); - if (FTy->getReturnType() != Type::getVoidTy(M->getContext())) + const FunctionType *FTy = Callee->getFunctionType(); + if (!FTy->getReturnType()->isVoidTy()) return false; if (FTy->getNumParams() != 1) return false; - if (FTy->param_begin()->get() != Type::getInt8PtrTy(M->getContext())) + if (FTy->param_begin()->get() != Type::getInt8PtrTy(Callee->getContext())) return false; return true; Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=85936&r1=85935&r2=85936&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Tue Nov 3 14:39:35 2009 @@ -303,32 +303,6 @@ return false; } -// Code here matches isFreeCall from MemoryBuiltins, which is not in VMCore. -static bool isFreeCall(const Value* I) { - const CallInst *CI = dyn_cast(I); - if (!CI) - return false; - - const Module* M = CI->getParent()->getParent()->getParent(); - Function *FreeFunc = M->getFunction("free"); - - if (CI->getOperand(0) != FreeFunc) - return false; - - // Check free prototype. - // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin - // attribute will exist. - const FunctionType *FTy = FreeFunc->getFunctionType(); - if (FTy->getReturnType() != Type::getVoidTy(M->getContext())) - return false; - if (FTy->getNumParams() != 1) - return false; - if (FTy->param_begin()->get() != Type::getInt8PtrTy(M->getContext())) - return false; - - return true; -} - /// mayReadFromMemory - Return true if this instruction may read memory. /// bool Instruction::mayReadFromMemory() const { @@ -338,8 +312,6 @@ case Instruction::Load: return true; case Instruction::Call: - if (isFreeCall(this)) - return true; return !cast(this)->doesNotAccessMemory(); case Instruction::Invoke: return !cast(this)->doesNotAccessMemory(); @@ -357,8 +329,6 @@ case Instruction::VAArg: return true; case Instruction::Call: - if (isFreeCall(this)) - return true; return !cast(this)->onlyReadsMemory(); case Instruction::Invoke: return !cast(this)->onlyReadsMemory(); @@ -418,18 +388,16 @@ CI = dyn_cast(BCI->getOperand(0)); } - if (!CI) return false; - - const Module* M = CI->getParent()->getParent()->getParent(); - Constant *MallocFunc = M->getFunction("malloc"); - - if (CI->getOperand(0) != MallocFunc) + if (!CI) + return false; + Function *Callee = CI->getCalledFunction(); + if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "malloc") return false; // Check malloc prototype. // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin // attribute will exist. - const FunctionType *FTy = cast(MallocFunc)->getFunctionType(); + const FunctionType *FTy = Callee->getFunctionType(); if (FTy->getNumParams() != 1) return false; if (IntegerType *ITy = dyn_cast(FTy->param_begin()->get())) { From vhernandez at apple.com Tue Nov 3 14:40:11 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 3 Nov 2009 12:40:11 -0800 Subject: [llvm-commits] [llvm] r85176 - in /llvm/trunk: examples/BrainF/ include/llvm-c/ include/llvm/ include/llvm/Analysis/ include/llvm/Support/ include/llvm/Transforms/ lib/Analysis/ lib/Analysis/IPA/ lib/AsmParser/ lib/Bitcode/Writer/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/Interpreter/ lib/Target/CBackend/ lib/Target/CppBackend/ lib/Target/MSIL/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ In-Reply-To: References: <200910262343.n9QNhpYj012068@zion.cs.uiuc.edu> Message-ID: <11A96F11-9B45-470E-AA92-F277A2EA216C@apple.com> Fixed in r85936. Victor On Nov 2, 2009, at 9:36 PM, Chris Lattner wrote: > > On Oct 26, 2009, at 4:43 PM, Victor Hernandez wrote: > >> Author: hernande >> Date: Mon Oct 26 18:43:48 2009 >> New Revision: 85176 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85176&view=rev >> Log: >> Remove FreeInst. >> Remove LowerAllocations pass. >> Update some more passes to treate free calls just like they were >> treating FreeInst. > > Thanks Victor, > >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/VMCore/Instruction.cpp (original) > >> +// Code here matches isFreeCall from MallocHelper, which is not in >> VMCore. >> +static bool isFreeCall(const Value* I) { >> + const CallInst *CI = dyn_cast(I); >> + if (!CI) >> + return false; >> + >> + const Module* M = CI->getParent()->getParent()->getParent(); >> + Function *FreeFunc = M->getFunction("free"); >> + >> + if (CI->getOperand(0) != FreeFunc) >> + return false; > > Please use something like this, which would be much more efficient: > > const CallInst *CI = dyn_cast(I); > if (!CI) > return false; > Function *Callee = CI->getCalledFunction(); > if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != > "free") > return false; > > >> + >> + // Check free prototype. >> + // FIXME: workaround for PR5130, this will be obsolete when a >> nobuiltin >> + // attribute will exist. >> + const FunctionType *FTy = FreeFunc->getFunctionType(); >> + if (FTy->getReturnType() != Type::getVoidTy(M->getContext())) > > Use ->isVoidTy() instead of comparing against a newly constructed > type. > >> /// mayReadFromMemory - Return true if this instruction may read >> memory. >> /// >> bool Instruction::mayReadFromMemory() const { >> switch (getOpcode()) { >> default: return false; >> - case Instruction::Free: >> case Instruction::VAArg: >> case Instruction::Load: >> return true; >> case Instruction::Call: >> + if (isFreeCall(this)) >> + return true; >> return !cast(this)->doesNotAccessMemory(); > > This call to isFreeCall isn't needed because the existing code works > for it. > >> case Instruction::Invoke: >> return !cast(this)->doesNotAccessMemory(); >> @@ -326,11 +352,12 @@ >> bool Instruction::mayWriteToMemory() const { >> switch (getOpcode()) { >> default: return false; >> - case Instruction::Free: >> case Instruction::Store: >> case Instruction::VAArg: >> return true; >> case Instruction::Call: >> + if (isFreeCall(this)) >> + return true; >> return !cast(this)->onlyReadsMemory(); > > Likewise. I removed some other ones that are not needed. > > -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091103/b988040c/attachment.html From clattner at apple.com Tue Nov 3 14:51:20 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 3 Nov 2009 12:51:20 -0800 Subject: [llvm-commits] [llvm] r85933 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp In-Reply-To: <200911032002.nA3K2aSe024624@zion.cs.uiuc.edu> References: <200911032002.nA3K2aSe024624@zion.cs.uiuc.edu> Message-ID: thanks Victor! On Nov 3, 2009, at 12:02 PM, Victor Hernandez wrote: > Author: hernande > Date: Tue Nov 3 14:02:35 2009 > New Revision: 85933 > > URL: http://llvm.org/viewvc/llvm-project?rev=85933&view=rev > Log: > Changes (* location in pointer variables, avoiding include, and > using APInt::getLimitedValue) based on feedback to r85814 From sabre at nondot.org Tue Nov 3 14:52:57 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 20:52:57 -0000 Subject: [llvm-commits] [llvm] r85937 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911032052.nA3KqvXn026474@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 14:52:57 2009 New Revision: 85937 URL: http://llvm.org/viewvc/llvm-project?rev=85937&view=rev Log: finish half thunk thought Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85937&r1=85936&r2=85937&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Tue Nov 3 14:52:57 2009 @@ -174,7 +174,9 @@ /// that return multiple values. DenseMap, LatticeVal> TrackedMultipleRetVals; - /// TrackingIncomingArguments - This is the set of functions that are + /// TrackingIncomingArguments - This is the set of functions for whose + /// arguments we make optimistic assumptions about and try to prove as + /// constants. SmallPtrSet TrackingIncomingArguments; /// The reason for two worklists is that overdefined is the lowest state From david_goodwin at apple.com Tue Nov 3 14:57:51 2009 From: david_goodwin at apple.com (David Goodwin) Date: Tue, 03 Nov 2009 20:57:51 -0000 Subject: [llvm-commits] [llvm] r85939 - in /llvm/trunk: include/llvm/CodeGen/LatencyPriorityQueue.h include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/AggressiveAntiDepBreaker.cpp lib/CodeGen/AggressiveAntiDepBreaker.h lib/CodeGen/AntiDepBreaker.h lib/CodeGen/CriticalAntiDepBreaker.cpp lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/ExactHazardRecognizer.cpp lib/CodeGen/LatencyPriorityQueue.cpp lib/CodeGen/PostRASchedulerList.cpp lib/CodeGen/ScheduleDAG.cpp Message-ID: <200911032057.nA3KvpgC026665@zion.cs.uiuc.edu> Author: david_goodwin Date: Tue Nov 3 14:57:50 2009 New Revision: 85939 URL: http://llvm.org/viewvc/llvm-project?rev=85939&view=rev Log: Do a scheduling pass ignoring anti-dependencies to identify candidate registers that should be renamed. Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h llvm/trunk/lib/CodeGen/AntiDepBreaker.h llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h (original) +++ llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Tue Nov 3 14:57:50 2009 @@ -39,12 +39,21 @@ /// predecessor for. This is used as a tie-breaker heuristic for better /// mobility. std::vector NumNodesSolelyBlocking; - + + /// IgnoreAntiDep - Ignore anti-dependencies + bool IgnoreAntiDep; + + /// Queue - The queue. PriorityQueue, latency_sort> Queue; + public: - LatencyPriorityQueue() : Queue(latency_sort(this)) { + LatencyPriorityQueue() : IgnoreAntiDep(false), Queue(latency_sort(this)) { } - + + void setIgnoreAntiDep(bool ignore) { + IgnoreAntiDep = ignore; + } + void initNodes(std::vector &sunits) { SUnits = &sunits; NumNodesSolelyBlocking.resize(SUnits->size(), 0); @@ -63,7 +72,7 @@ unsigned getLatency(unsigned NodeNum) const { assert(NodeNum < (*SUnits).size()); - return (*SUnits)[NodeNum].getHeight(); + return (*SUnits)[NodeNum].getHeight(IgnoreAntiDep); } unsigned getNumSolelyBlockNodes(unsigned NodeNum) const { Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Tue Nov 3 14:57:50 2009 @@ -340,28 +340,34 @@ void removePred(const SDep &D); /// getDepth - Return the depth of this node, which is the length of the - /// maximum path up to any node with has no predecessors. - unsigned getDepth() const { - if (!isDepthCurrent) const_cast(this)->ComputeDepth(); + /// maximum path up to any node with has no predecessors. If IgnoreAntiDep + /// is true, ignore anti-dependence edges. + unsigned getDepth(bool IgnoreAntiDep=false) const { + if (!isDepthCurrent) + const_cast(this)->ComputeDepth(IgnoreAntiDep); return Depth; } /// getHeight - Return the height of this node, which is the length of the - /// maximum path down to any node with has no successors. - unsigned getHeight() const { - if (!isHeightCurrent) const_cast(this)->ComputeHeight(); + /// maximum path down to any node with has no successors. If IgnoreAntiDep + /// is true, ignore anti-dependence edges. + unsigned getHeight(bool IgnoreAntiDep=false) const { + if (!isHeightCurrent) + const_cast(this)->ComputeHeight(IgnoreAntiDep); return Height; } - /// setDepthToAtLeast - If NewDepth is greater than this node's depth - /// value, set it to be the new depth value. This also recursively - /// marks successor nodes dirty. - void setDepthToAtLeast(unsigned NewDepth); - - /// setDepthToAtLeast - If NewDepth is greater than this node's depth - /// value, set it to be the new height value. This also recursively - /// marks predecessor nodes dirty. - void setHeightToAtLeast(unsigned NewHeight); + /// setDepthToAtLeast - If NewDepth is greater than this node's + /// depth value, set it to be the new depth value. This also + /// recursively marks successor nodes dirty. If IgnoreAntiDep is + /// true, ignore anti-dependence edges. + void setDepthToAtLeast(unsigned NewDepth, bool IgnoreAntiDep=false); + + /// setDepthToAtLeast - If NewDepth is greater than this node's + /// depth value, set it to be the new height value. This also + /// recursively marks predecessor nodes dirty. If IgnoreAntiDep is + /// true, ignore anti-dependence edges. + void setHeightToAtLeast(unsigned NewHeight, bool IgnoreAntiDep=false); /// setDepthDirty - Set a flag in this node to indicate that its /// stored Depth value will require recomputation the next time @@ -394,8 +400,8 @@ void print(raw_ostream &O, const ScheduleDAG *G) const; private: - void ComputeDepth(); - void ComputeHeight(); + void ComputeDepth(bool IgnoreAntiDep); + void ComputeHeight(bool IgnoreAntiDep); }; //===--------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp Tue Nov 3 14:57:50 2009 @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "aggressive-antidep" +#define DEBUG_TYPE "post-RA-sched" #include "AggressiveAntiDepBreaker.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -31,7 +31,7 @@ static cl::opt AntiDepTrials("agg-antidep-trials", cl::desc("Maximum number of anti-dependency breaking passes"), - cl::init(2), cl::Hidden); + cl::init(1), cl::Hidden); AggressiveAntiDepState::AggressiveAntiDepState(MachineBasicBlock *BB) : GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) { @@ -265,18 +265,24 @@ } /// AntiDepPathStep - Return SUnit that SU has an anti-dependence on. -static void AntiDepPathStep(SUnit *SU, std::vector& Edges) { - SmallSet Dups; +static void AntiDepPathStep(SUnit *SU, AntiDepBreaker::AntiDepRegVector& Regs, + std::vector& Edges) { + AntiDepBreaker::AntiDepRegSet RegSet; + for (unsigned i = 0, e = Regs.size(); i < e; ++i) + RegSet.insert(Regs[i]); + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); P != PE; ++P) { if (P->getKind() == SDep::Anti) { unsigned Reg = P->getReg(); - if (Dups.count(Reg) == 0) { + if (RegSet.count(Reg) != 0) { Edges.push_back(&*P); - Dups.insert(Reg); + RegSet.erase(Reg); } } } + + assert(RegSet.empty() && "Expected all antidep registers to be found"); } void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx, @@ -593,6 +599,7 @@ /// unsigned AggressiveAntiDepBreaker::BreakAntiDependencies( std::vector& SUnits, + CandidateMap& Candidates, MachineBasicBlock::iterator& Begin, MachineBasicBlock::iterator& End, unsigned InsertPosIndex) { @@ -601,9 +608,15 @@ std::multimap& RegRefs = State->GetRegRefs(); + // Nothing to do if no candidates. + if (Candidates.empty()) { + DEBUG(errs() << "\n===== No anti-dependency candidates\n"); + return 0; + } + // The code below assumes that there is at least one instruction, // so just duck out immediately if the block is empty. - if (SUnits.empty()) return false; + if (SUnits.empty()) return 0; // Manage saved state to enable multiple passes... if (AntiDepTrials > 1) { @@ -618,7 +631,8 @@ // ...need a map from MI to SUnit. std::map MISUnitMap; - DEBUG(errs() << "Breaking all anti-dependencies\n"); + DEBUG(errs() << "\n===== Attempting to break " << Candidates.size() << + " anti-dependencies\n"); for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { SUnit *SU = &SUnits[i]; MISUnitMap.insert(std::pair(SU->getInstr(), SU)); @@ -655,8 +669,10 @@ std::vector Edges; SUnit *PathSU = MISUnitMap[MI]; - if (PathSU) - AntiDepPathStep(PathSU, Edges); + AntiDepBreaker::CandidateMap::iterator + citer = Candidates.find(PathSU); + if (citer != Candidates.end()) + AntiDepPathStep(PathSU, citer->second, Edges); // Ignore KILL instructions (they form a group in ScanInstruction // but don't cause any anti-dependence breaking themselves) Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Tue Nov 3 14:57:50 2009 @@ -131,6 +131,9 @@ /// dependencies may be exposed, so multiple passes are required. unsigned GetMaxTrials(); + /// NeedCandidates - Candidates required. + bool NeedCandidates() { return true; } + /// Start - Initialize anti-dep breaking for a new basic block. void StartBlock(MachineBasicBlock *BB); @@ -138,6 +141,7 @@ /// of the ScheduleDAG and break them by renaming registers. /// unsigned BreakAntiDependencies(std::vector& SUnits, + CandidateMap& Candidates, MachineBasicBlock::iterator& Begin, MachineBasicBlock::iterator& End, unsigned InsertPosIndex); Modified: llvm/trunk/lib/CodeGen/AntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AntiDepBreaker.h?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/AntiDepBreaker.h Tue Nov 3 14:57:50 2009 @@ -21,6 +21,8 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { @@ -29,12 +31,20 @@ /// anti-dependencies. class AntiDepBreaker { public: + typedef SmallSet AntiDepRegSet; + typedef SmallVector AntiDepRegVector; + typedef std::map CandidateMap; + virtual ~AntiDepBreaker(); /// GetMaxTrials - Return the maximum number of anti-dependence /// breaking attempts that will be made for a block. virtual unsigned GetMaxTrials() =0; + /// NeedCandidates - Return true if the schedule must provide + /// candidates with BreakAntiDependencies(). + virtual bool NeedCandidates() =0; + /// Start - Initialize anti-dep breaking for a new basic block. virtual void StartBlock(MachineBasicBlock *BB) =0; @@ -43,9 +53,10 @@ /// the number of anti-dependencies broken. /// virtual unsigned BreakAntiDependencies(std::vector& SUnits, - MachineBasicBlock::iterator& Begin, - MachineBasicBlock::iterator& End, - unsigned InsertPosIndex) =0; + CandidateMap& Candidates, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) =0; /// Observe - Update liveness information to account for the current /// instruction, which will not be scheduled. Modified: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (original) +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Tue Nov 3 14:57:50 2009 @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "critical-antidep" +#define DEBUG_TYPE "post-RA-sched" #include "CriticalAntiDepBreaker.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -316,6 +316,7 @@ unsigned CriticalAntiDepBreaker:: BreakAntiDependencies(std::vector& SUnits, + CandidateMap& Candidates, MachineBasicBlock::iterator& Begin, MachineBasicBlock::iterator& End, unsigned InsertPosIndex) { Modified: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Tue Nov 3 14:57:50 2009 @@ -68,6 +68,9 @@ /// only a single pass unsigned GetMaxTrials() { return 1; } + /// NeedCandidates - Candidates not needed. + bool NeedCandidates() { return false; } + /// Start - Initialize anti-dep breaking for a new basic block. void StartBlock(MachineBasicBlock *BB); @@ -75,6 +78,7 @@ /// of the ScheduleDAG and break them by renaming registers. /// unsigned BreakAntiDependencies(std::vector& SUnits, + CandidateMap& Candidates, MachineBasicBlock::iterator& Begin, MachineBasicBlock::iterator& End, unsigned InsertPosIndex); Modified: llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp (original) +++ llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp Tue Nov 3 14:57:50 2009 @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "exact-hazards" +#define DEBUG_TYPE "post-RA-sched" #include "ExactHazardRecognizer.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include "llvm/Support/Debug.h" Modified: llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp (original) +++ llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp Tue Nov 3 14:57:50 2009 @@ -55,6 +55,7 @@ SUnit *OnlyAvailablePred = 0; for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; SUnit &Pred = *I->getSUnit(); if (!Pred.isScheduled) { // We found an available, but not scheduled, predecessor. If it's the @@ -73,9 +74,11 @@ // this node is the sole unscheduled node for. unsigned NumNodesBlocking = 0; for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) + I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; if (getSingleUnscheduledPred(I->getSUnit()) == SU) ++NumNodesBlocking; + } NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking; Queue.push(SU); @@ -88,8 +91,10 @@ // the node available. void LatencyPriorityQueue::ScheduledNode(SUnit *SU) { for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) + I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; AdjustPriorityOfUnscheduledPreds(I->getSUnit()); + } } /// AdjustPriorityOfUnscheduledPreds - One of the predecessors of SU was just Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Tue Nov 3 14:57:50 2009 @@ -175,10 +175,11 @@ void FixupKills(MachineBasicBlock *MBB); private: - void ReleaseSucc(SUnit *SU, SDep *SuccEdge); - void ReleaseSuccessors(SUnit *SU); - void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); - void ListScheduleTopDown(); + void ReleaseSucc(SUnit *SU, SDep *SuccEdge, bool IgnoreAntiDep); + void ReleaseSuccessors(SUnit *SU, bool IgnoreAntiDep); + void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle, bool IgnoreAntiDep); + void ListScheduleTopDown( + AntiDepBreaker::CandidateMap *AntiDepCandidates); void StartBlockForKills(MachineBasicBlock *BB); // ToggleKillFlag - Toggle a register operand kill flag. Other @@ -320,15 +321,32 @@ BuildSchedGraph(AA); if (AntiDepBreak != NULL) { + AntiDepBreaker::CandidateMap AntiDepCandidates; + const bool NeedCandidates = AntiDepBreak->NeedCandidates(); + for (unsigned i = 0, Trials = AntiDepBreak->GetMaxTrials(); i < Trials; ++i) { - DEBUG(errs() << "********** Break Anti-Deps, Trial " << + DEBUG(errs() << "\n********** Break Anti-Deps, Trial " << i << " **********\n"); + + // If candidates are required, then schedule forward ignoring + // anti-dependencies to collect the candidate operands for + // anti-dependence breaking. The candidates will be the def + // operands for the anti-dependencies that if broken would allow + // an improved schedule + if (NeedCandidates) { + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) + SUnits[su].dumpAll(this)); + + AntiDepCandidates.clear(); + AvailableQueue.initNodes(SUnits); + ListScheduleTopDown(&AntiDepCandidates); + AvailableQueue.releaseState(); + } + unsigned Broken = - AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, - InsertPosIndex); - if (Broken == 0) - break; + AntiDepBreak->BreakAntiDependencies(SUnits, AntiDepCandidates, + Begin, InsertPos, InsertPosIndex); // We made changes. Update the dependency graph. // Theoretically we could update the graph in place: @@ -336,24 +354,26 @@ // the def's anti-dependence *and* output-dependence edges due to // that register, and add new anti-dependence and output-dependence // edges based on the next live range of the register. - SUnits.clear(); - EntrySU = SUnit(); - ExitSU = SUnit(); - BuildSchedGraph(AA); + if ((Broken != 0) || NeedCandidates) { + SUnits.clear(); + Sequence.clear(); + EntrySU = SUnit(); + ExitSU = SUnit(); + BuildSchedGraph(AA); + } NumFixedAnti += Broken; + if (Broken == 0) + break; } } DEBUG(errs() << "********** List Scheduling **********\n"); - DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(this)); AvailableQueue.initNodes(SUnits); - - ListScheduleTopDown(); - + ListScheduleTopDown(NULL); AvailableQueue.releaseState(); } @@ -552,7 +572,8 @@ /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to /// the PendingQueue if the count reaches zero. Also update its cycle bound. -void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { +void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge, + bool IgnoreAntiDep) { SUnit *SuccSU = SuccEdge->getSUnit(); #ifndef NDEBUG @@ -568,7 +589,8 @@ // Compute how many cycles it will be before this actually becomes // available. This is the max of the start time of all predecessors plus // their latencies. - SuccSU->setDepthToAtLeast(SU->getDepth() + SuccEdge->getLatency()); + SuccSU->setDepthToAtLeast(SU->getDepth(IgnoreAntiDep) + + SuccEdge->getLatency(), IgnoreAntiDep); // If all the node's predecessors are scheduled, this node is ready // to be scheduled. Ignore the special ExitSU node. @@ -577,40 +599,73 @@ } /// ReleaseSuccessors - Call ReleaseSucc on each of SU's successors. -void SchedulePostRATDList::ReleaseSuccessors(SUnit *SU) { +void SchedulePostRATDList::ReleaseSuccessors(SUnit *SU, bool IgnoreAntiDep) { for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) - ReleaseSucc(SU, &*I); + I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; + ReleaseSucc(SU, &*I, IgnoreAntiDep); + } } /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. -void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { +void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle, + bool IgnoreAntiDep) { DEBUG(errs() << "*** Scheduling [" << CurCycle << "]: "); DEBUG(SU->dump(this)); Sequence.push_back(SU); - assert(CurCycle >= SU->getDepth() && "Node scheduled above its depth!"); - SU->setDepthToAtLeast(CurCycle); + assert(CurCycle >= SU->getDepth(IgnoreAntiDep) && + "Node scheduled above its depth!"); + SU->setDepthToAtLeast(CurCycle, IgnoreAntiDep); - ReleaseSuccessors(SU); + ReleaseSuccessors(SU, IgnoreAntiDep); SU->isScheduled = true; AvailableQueue.ScheduledNode(SU); } /// ListScheduleTopDown - The main loop of list scheduling for top-down /// schedulers. -void SchedulePostRATDList::ListScheduleTopDown() { +void SchedulePostRATDList::ListScheduleTopDown( + AntiDepBreaker::CandidateMap *AntiDepCandidates) { unsigned CurCycle = 0; + const bool IgnoreAntiDep = (AntiDepCandidates != NULL); + + // We're scheduling top-down but we're visiting the regions in + // bottom-up order, so we don't know the hazards at the start of a + // region. So assume no hazards (this should usually be ok as most + // blocks are a single region). + HazardRec->Reset(); + + // If ignoring anti-dependencies, the Schedule DAG still has Anti + // dep edges, but we ignore them for scheduling purposes + AvailableQueue.setIgnoreAntiDep(IgnoreAntiDep); // Release any successors of the special Entry node. - ReleaseSuccessors(&EntrySU); + ReleaseSuccessors(&EntrySU, IgnoreAntiDep); - // All leaves to Available queue. + // Add all leaves to Available queue. If ignoring antideps we also + // adjust the predecessor count for each node to not include antidep + // edges. for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { // It is available if it has no predecessors. - if (SUnits[i].Preds.empty()) { + bool available = SUnits[i].Preds.empty(); + // If we are ignoring anti-dependencies then a node that has only + // anti-dep predecessors is available. + if (!available && IgnoreAntiDep) { + available = true; + for (SUnit::const_pred_iterator I = SUnits[i].Preds.begin(), + E = SUnits[i].Preds.end(); I != E; ++I) { + if (I->getKind() != SDep::Anti) { + available = false; + } else { + SUnits[i].NumPredsLeft -= 1; + } + } + } + + if (available) { AvailableQueue.push(&SUnits[i]); SUnits[i].isAvailable = true; } @@ -629,26 +684,25 @@ // so, add them to the available queue. unsigned MinDepth = ~0u; for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { - if (PendingQueue[i]->getDepth() <= CurCycle) { + if (PendingQueue[i]->getDepth(IgnoreAntiDep) <= CurCycle) { AvailableQueue.push(PendingQueue[i]); PendingQueue[i]->isAvailable = true; PendingQueue[i] = PendingQueue.back(); PendingQueue.pop_back(); --i; --e; - } else if (PendingQueue[i]->getDepth() < MinDepth) - MinDepth = PendingQueue[i]->getDepth(); + } else if (PendingQueue[i]->getDepth(IgnoreAntiDep) < MinDepth) + MinDepth = PendingQueue[i]->getDepth(IgnoreAntiDep); } DEBUG(errs() << "\n*** Examining Available\n"; LatencyPriorityQueue q = AvailableQueue; while (!q.empty()) { SUnit *su = q.pop(); - errs() << "Height " << su->getHeight() << ": "; + errs() << "Height " << su->getHeight(IgnoreAntiDep) << ": "; su->dump(this); }); SUnit *FoundSUnit = 0; - bool HasNoopHazards = false; while (!AvailableQueue.empty()) { SUnit *CurSUnit = AvailableQueue.pop(); @@ -672,9 +726,30 @@ NotReady.clear(); } - // If we found a node to schedule, do it now. + // If we found a node to schedule... if (FoundSUnit) { - ScheduleNodeTopDown(FoundSUnit, CurCycle); + // If we are ignoring anti-dependencies and the SUnit we are + // scheduling has an antidep predecessor that has not been + // scheduled, then we will need to break that antidep if we want + // to get this schedule when not ignoring anti-dependencies. + if (IgnoreAntiDep) { + AntiDepBreaker::AntiDepRegVector AntiDepRegs; + for (SUnit::const_pred_iterator I = FoundSUnit->Preds.begin(), + E = FoundSUnit->Preds.end(); I != E; ++I) { + if ((I->getKind() == SDep::Anti) && !I->getSUnit()->isScheduled) + AntiDepRegs.push_back(I->getReg()); + } + + if (AntiDepRegs.size() > 0) { + DEBUG(errs() << "*** AntiDep Candidate: "); + DEBUG(FoundSUnit->dump(this)); + AntiDepCandidates->insert( + AntiDepBreaker::CandidateMap::value_type(FoundSUnit, AntiDepRegs)); + } + } + + // ... schedule the node... + ScheduleNodeTopDown(FoundSUnit, CurCycle, IgnoreAntiDep); HazardRec->EmitInstruction(FoundSUnit); CycleHasInsts = true; Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?rev=85939&r1=85938&r2=85939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Tue Nov 3 14:57:50 2009 @@ -183,8 +183,8 @@ /// setDepthToAtLeast - Update this node's successors to reflect the /// fact that this node's depth just increased. /// -void SUnit::setDepthToAtLeast(unsigned NewDepth) { - if (NewDepth <= getDepth()) +void SUnit::setDepthToAtLeast(unsigned NewDepth, bool IgnoreAntiDep) { + if (NewDepth <= getDepth(IgnoreAntiDep)) return; setDepthDirty(); Depth = NewDepth; @@ -194,8 +194,8 @@ /// setHeightToAtLeast - Update this node's predecessors to reflect the /// fact that this node's height just increased. /// -void SUnit::setHeightToAtLeast(unsigned NewHeight) { - if (NewHeight <= getHeight()) +void SUnit::setHeightToAtLeast(unsigned NewHeight, bool IgnoreAntiDep) { + if (NewHeight <= getHeight(IgnoreAntiDep)) return; setHeightDirty(); Height = NewHeight; @@ -204,7 +204,7 @@ /// ComputeDepth - Calculate the maximal path from the node to the exit. /// -void SUnit::ComputeDepth() { +void SUnit::ComputeDepth(bool IgnoreAntiDep) { SmallVector WorkList; WorkList.push_back(this); do { @@ -214,6 +214,7 @@ unsigned MaxPredDepth = 0; for (SUnit::const_pred_iterator I = Cur->Preds.begin(), E = Cur->Preds.end(); I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; SUnit *PredSU = I->getSUnit(); if (PredSU->isDepthCurrent) MaxPredDepth = std::max(MaxPredDepth, @@ -237,7 +238,7 @@ /// ComputeHeight - Calculate the maximal path from the node to the entry. /// -void SUnit::ComputeHeight() { +void SUnit::ComputeHeight(bool IgnoreAntiDep) { SmallVector WorkList; WorkList.push_back(this); do { @@ -247,6 +248,7 @@ unsigned MaxSuccHeight = 0; for (SUnit::const_succ_iterator I = Cur->Succs.begin(), E = Cur->Succs.end(); I != E; ++I) { + if (IgnoreAntiDep && (I->getKind() == SDep::Anti)) continue; SUnit *SuccSU = I->getSUnit(); if (SuccSU->isHeightCurrent) MaxSuccHeight = std::max(MaxSuccHeight, @@ -346,7 +348,7 @@ AnyNotSched = true; } if (SUnits[i].isScheduled && - (isBottomUp ? SUnits[i].getHeight() : SUnits[i].getHeight()) > + (isBottomUp ? SUnits[i].getHeight() : SUnits[i].getDepth()) > unsigned(INT_MAX)) { if (!AnyNotSched) errs() << "*** Scheduling failed! ***\n"; From sabre at nondot.org Tue Nov 3 15:25:50 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 21:25:50 -0000 Subject: [llvm-commits] [llvm] r85945 - in /llvm/trunk/test/Transforms/SCCP: empty-struct.ll ipsccp-basic.ll Message-ID: <200911032125.nA3LPoRe027940@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 15:25:50 2009 New Revision: 85945 URL: http://llvm.org/viewvc/llvm-project?rev=85945&view=rev Log: merge a test into ipsccp-basic. running llvm-ld to get one pass is... bad. Removed: llvm/trunk/test/Transforms/SCCP/empty-struct.ll Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Removed: llvm/trunk/test/Transforms/SCCP/empty-struct.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/empty-struct.ll?rev=85944&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SCCP/empty-struct.ll (original) +++ llvm/trunk/test/Transforms/SCCP/empty-struct.ll (removed) @@ -1,20 +0,0 @@ -; RUN: llvm-as < %s > %t.bc -; RUN: llvm-ld %t.bc -o %t.sh -; PR2612 - - at current_foo = internal global { } zeroinitializer - -define i32 @main(...) { -entry: - %retval = alloca i32 ; [#uses=2] - store i32 0, i32* %retval - %local_foo = alloca { } ; <{ }*> [#uses=1] - load { }* @current_foo ; <{ }>:0 [#uses=1] - store { } %0, { }* %local_foo - br label %return - -return: ; preds = %entry - load i32* %retval ; :1 [#uses=1] - ret i32 %1 -} - Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll?rev=85945&r1=85944&r2=85945&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll (original) +++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Tue Nov 3 15:25:50 2009 @@ -189,9 +189,19 @@ %X = call {} @test8a(i32 5, i32* %P) ret void ; CHECK: define void @test8b -; CHECK-NEXT: call {} @test8a +; CHECK-NEXT: call { } @test8a ; CHECK-NEXT: ret void } +;;======================== test9 + at test9g = internal global { } zeroinitializer + +define void @test9() { +entry: + %local_foo = alloca { } + load { }* @current_foo + store { } %0, { }* %local_foo + ret void +} From sabre at nondot.org Tue Nov 3 15:26:26 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 21:26:26 -0000 Subject: [llvm-commits] [llvm] r85946 - /llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Message-ID: <200911032126.nA3LQRtk027980@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 15:26:26 2009 New Revision: 85946 URL: http://llvm.org/viewvc/llvm-project?rev=85946&view=rev Log: fix test Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll?rev=85946&r1=85945&r2=85946&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll (original) +++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Tue Nov 3 15:26:26 2009 @@ -200,7 +200,7 @@ define void @test9() { entry: %local_foo = alloca { } - load { }* @current_foo + load { }* @test9g store { } %0, { }* %local_foo ret void } From evan.cheng at apple.com Tue Nov 3 15:40:02 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 21:40:02 -0000 Subject: [llvm-commits] [llvm] r85947 - in /llvm/trunk: lib/CodeGen/MachineLICM.cpp test/CodeGen/ARM/remat.ll test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Message-ID: <200911032140.nA3Le2fj028599@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 15:40:02 2009 New Revision: 85947 URL: http://llvm.org/viewvc/llvm-project?rev=85947&view=rev Log: Re-apply 85799. It turns out my code isn't buggy. Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/test/CodeGen/ARM/remat.ll llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=85947&r1=85946&r2=85947&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Tue Nov 3 15:40:02 2009 @@ -56,12 +56,12 @@ // State that is updated as we process loops bool Changed; // True if a loop is changed. + bool FirstInLoop; // True if it's the first LICM in the loop. MachineLoop *CurLoop; // The current loop we are working on. MachineBasicBlock *CurPreheader; // The preheader for CurLoop. - // For each BB and opcode pair, keep a list of hoisted instructions. - DenseMap, - std::vector > CSEMap; + // For each opcode, keep a list of potentail CSE instructions. + DenseMap > CSEMap; public: static char ID; // Pass identification, replacement for typeid MachineLICM() : MachineFunctionPass(&ID) {} @@ -115,6 +115,11 @@ /// that is safe to hoist, this instruction is called to do the dirty work. /// void Hoist(MachineInstr *MI); + + /// InitCSEMap - Initialize the CSE map with instructions that are in the + /// current loop preheader that may become duplicates of instructions that + /// are hoisted out of the loop. + void InitCSEMap(MachineBasicBlock *BB); }; } // end anonymous namespace @@ -140,7 +145,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { DEBUG(errs() << "******** Machine LICM ********\n"); - Changed = false; + Changed = FirstInLoop = false; TM = &MF.getTarget(); TII = TM->getInstrInfo(); TRI = TM->getRegisterInfo(); @@ -152,8 +157,7 @@ DT = &getAnalysis(); AA = &getAnalysis(); - for (MachineLoopInfo::iterator - I = LI->begin(), E = LI->end(); I != E; ++I) { + for (MachineLoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) { CurLoop = *I; // Only visit outer-most preheader-sporting loops. @@ -170,7 +174,11 @@ if (!CurPreheader) continue; + // CSEMap is initialized for loop header when the first instruction is + // being hoisted. + FirstInLoop = true; HoistRegion(DT->getNode(CurLoop->getHeader())); + CSEMap.clear(); } return Changed; @@ -191,10 +199,7 @@ for (MachineBasicBlock::iterator MII = BB->begin(), E = BB->end(); MII != E; ) { MachineBasicBlock::iterator NextMII = MII; ++NextMII; - MachineInstr &MI = *MII; - - Hoist(&MI); - + Hoist(&*MII); MII = NextMII; } @@ -430,6 +435,27 @@ return NewMIs[0]; } +void MachineLICM::InitCSEMap(MachineBasicBlock *BB) { + for (MachineBasicBlock::iterator I = BB->begin(),E = BB->end(); I != E; ++I) { + const MachineInstr *MI = &*I; + // FIXME: For now, only hoist re-materilizable instructions. LICM will + // increase register pressure. We want to make sure it doesn't increase + // spilling. + if (TII->isTriviallyReMaterializable(MI, AA)) { + unsigned Opcode = MI->getOpcode(); + DenseMap >::iterator + CI = CSEMap.find(Opcode); + if (CI != CSEMap.end()) + CI->second.push_back(MI); + else { + std::vector CSEMIs; + CSEMIs.push_back(MI); + CSEMap.insert(std::make_pair(Opcode, CSEMIs)); + } + } + } +} + /// Hoist - When an instruction is found to use only loop invariant operands /// that are safe to hoist, this instruction is called to do the dirty work. /// @@ -454,11 +480,14 @@ errs() << "\n"; }); + // If this is the first instruction being hoisted to the preheader, + // initialize the CSE map with potential common expressions. + InitCSEMap(CurPreheader); + // Look for opportunity to CSE the hoisted instruction. - std::pair BBOpcPair = - std::make_pair(CurPreheader->getNumber(), MI->getOpcode()); - DenseMap, - std::vector >::iterator CI = CSEMap.find(BBOpcPair); + unsigned Opcode = MI->getOpcode(); + DenseMap >::iterator + CI = CSEMap.find(Opcode); bool DoneCSE = false; if (CI != CSEMap.end()) { const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo); @@ -477,15 +506,15 @@ // Otherwise, splice the instruction to the preheader. if (!DoneCSE) { - CurPreheader->splice(CurPreheader->getFirstTerminator(), - MI->getParent(), MI); + CurPreheader->splice(CurPreheader->getFirstTerminator(),MI->getParent(),MI); + // Add to the CSE map. if (CI != CSEMap.end()) CI->second.push_back(MI); else { std::vector CSEMIs; CSEMIs.push_back(MI); - CSEMap.insert(std::make_pair(BBOpcPair, CSEMIs)); + CSEMap.insert(std::make_pair(Opcode, CSEMIs)); } } Modified: llvm/trunk/test/CodeGen/ARM/remat.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/remat.ll?rev=85947&r1=85946&r2=85947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/remat.ll (original) +++ llvm/trunk/test/CodeGen/ARM/remat.ll Tue Nov 3 15:40:02 2009 @@ -1,5 +1,5 @@ ; RUN: llc < %s -mtriple=arm-apple-darwin -; RUN: llc < %s -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 4 +; RUN: llc < %s -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 5 %struct.CONTENTBOX = type { i32, i32, i32, i32, i32 } %struct.LOCBOX = type { i32, i32, i32, i32 } Modified: llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll?rev=85947&r1=85946&r2=85947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll Tue Nov 3 15:40:02 2009 @@ -1,6 +1,5 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 -stats |& \ -; RUN: grep {1 .*folded into instructions} -; Increment in loop bb.128.i adjusted to 2, to prevent loop reversal from +; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s +; Increment in loop bb.i28.i adjusted to 2, to prevent loop reversal from ; kicking in. declare fastcc void @rdft(i32, i32, double*, i32*, double*) @@ -34,6 +33,9 @@ br label %bb.i28.i bb.i28.i: ; preds = %bb.i28.i, %cond_next36.i +; CHECK: %bb.i28.i +; CHECK: addl $2 +; CHECK: addl $2 %j.0.reg2mem.0.i16.i = phi i32 [ 0, %cond_next36.i ], [ %indvar.next39.i, %bb.i28.i ] ; [#uses=2] %din_addr.1.reg2mem.0.i17.i = phi double [ 0.000000e+00, %cond_next36.i ], [ %tmp16.i25.i, %bb.i28.i ] ; [#uses=1] %tmp1.i18.i = fptosi double %din_addr.1.reg2mem.0.i17.i to i32 ; [#uses=2] From evan.cheng at apple.com Tue Nov 3 15:50:02 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 21:50:02 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85950 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200911032150.nA3Lo2Qr029092@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 15:50:02 2009 New Revision: 85950 URL: http://llvm.org/viewvc/llvm-project?rev=85950&view=rev Log: Allow user to override DARWIN_VERS from command line. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=85950&r1=85949&r2=85950&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Tue Nov 3 15:50:02 2009 @@ -116,7 +116,9 @@ NON_ARM_CONFIGFLAGS="--with-gxx-include-dir=/usr/include/c++/$LIBSTDCXX_VERSION" # LLVM LOCAL end -DARWIN_VERS=`uname -r | sed 's/\..*//'` +if [ "x$DARWIN_VERS" == "x" ]; then + DARWIN_VERS=`uname -r | sed 's/\..*//'` +fi echo DARWIN_VERS = $DARWIN_VERS # APPLE LOCAL begin ARM From sabre at nondot.org Tue Nov 3 15:50:10 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 21:50:10 -0000 Subject: [llvm-commits] [llvm] r85951 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200911032150.nA3LoAro029118@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 15:50:09 2009 New Revision: 85951 URL: http://llvm.org/viewvc/llvm-project?rev=85951&view=rev Log: fix broken link Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=85951&r1=85950&r2=85951&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Tue Nov 3 15:50:09 2009 @@ -1058,7 +1058,7 @@
                        • LLVM will not correctly compile on Solaris and/or OpenSolaris using the stock GCC 3.x.x series 'out the box', -See: Broken versions of GCC and other tools. +See: Broken versions of GCC and other tools. However, A Modern GCC Build for x86/x86-64 has been made available from the third party AuroraUX Project that has been meticulously tested for bootstrapping LLVM & Clang.
                        • From evan.cheng at apple.com Tue Nov 3 15:59:33 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 21:59:33 -0000 Subject: [llvm-commits] [llvm] r85952 - in /llvm/trunk: lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp test/CodeGen/ARM/fpconsts.ll Message-ID: <200911032159.nA3LxX2l029501@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 15:59:33 2009 New Revision: 85952 URL: http://llvm.org/viewvc/llvm-project?rev=85952&view=rev Log: fconsts / fconstd immediate should be proceeded with #. Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp llvm/trunk/test/CodeGen/ARM/fpconsts.ll Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=85952&r1=85951&r2=85952&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Tue Nov 3 15:59:33 2009 @@ -980,7 +980,7 @@ void ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum) { const ConstantFP *FP = MI->getOperand(OpNum).getFPImm(); - O << ARM::getVFPf32Imm(FP->getValueAPF()); + O << '#' << ARM::getVFPf32Imm(FP->getValueAPF()); if (VerboseAsm) { O.PadToColumn(MAI->getCommentColumn()); O << MAI->getCommentString() << ' '; @@ -990,7 +990,7 @@ void ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum) { const ConstantFP *FP = MI->getOperand(OpNum).getFPImm(); - O << ARM::getVFPf64Imm(FP->getValueAPF()); + O << '#' << ARM::getVFPf64Imm(FP->getValueAPF()); if (VerboseAsm) { O.PadToColumn(MAI->getCommentColumn()); O << MAI->getCommentString() << ' '; Modified: llvm/trunk/test/CodeGen/ARM/fpconsts.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fpconsts.ll?rev=85952&r1=85951&r2=85952&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fpconsts.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fpconsts.ll Tue Nov 3 15:59:33 2009 @@ -3,7 +3,7 @@ define arm_apcscc float @t1(float %x) nounwind readnone optsize { entry: ; CHECK: t1: -; CHECK: fconsts s1, 16 +; CHECK: fconsts s1, #16 %0 = fadd float %x, 4.000000e+00 ret float %0 } @@ -11,7 +11,7 @@ define arm_apcscc double @t2(double %x) nounwind readnone optsize { entry: ; CHECK: t2: -; CHECK: fconstd d1, 8 +; CHECK: fconstd d1, #8 %0 = fadd double %x, 3.000000e+00 ret double %0 } @@ -19,7 +19,7 @@ define arm_apcscc double @t3(double %x) nounwind readnone optsize { entry: ; CHECK: t3: -; CHECK: fconstd d1, 170 +; CHECK: fconstd d1, #170 %0 = fmul double %x, -1.300000e+01 ret double %0 } @@ -27,7 +27,7 @@ define arm_apcscc float @t4(float %x) nounwind readnone optsize { entry: ; CHECK: t4: -; CHECK: fconsts s1, 184 +; CHECK: fconsts s1, #184 %0 = fmul float %x, -2.400000e+01 ret float %0 } From nunoplopes at sapo.pt Tue Nov 3 16:07:08 2009 From: nunoplopes at sapo.pt (Nuno Lopes) Date: Tue, 03 Nov 2009 22:07:08 -0000 Subject: [llvm-commits] [llvm] r85953 - in /llvm/trunk/examples/Kaleidoscope: Chapter2/ Chapter3/ Chapter4/ Chapter5/ Chapter6/ Chapter7/ Message-ID: <200911032207.nA3M78Lg029822@zion.cs.uiuc.edu> Author: nlopes Date: Tue Nov 3 16:07:07 2009 New Revision: 85953 URL: http://llvm.org/viewvc/llvm-project?rev=85953&view=rev Log: set svn:ignore Modified: llvm/trunk/examples/Kaleidoscope/Chapter2/ (props changed) llvm/trunk/examples/Kaleidoscope/Chapter3/ (props changed) llvm/trunk/examples/Kaleidoscope/Chapter4/ (props changed) llvm/trunk/examples/Kaleidoscope/Chapter5/ (props changed) llvm/trunk/examples/Kaleidoscope/Chapter6/ (props changed) llvm/trunk/examples/Kaleidoscope/Chapter7/ (props changed) Propchange: llvm/trunk/examples/Kaleidoscope/Chapter2/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 3 16:07:07 2009 @@ -0,0 +1,8 @@ +Debug +Release +Release-Asserts +Debug+Coverage-Asserts +Debug+Coverage +Release+Coverage +Debug+Checks + Propchange: llvm/trunk/examples/Kaleidoscope/Chapter3/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 3 16:07:07 2009 @@ -0,0 +1,8 @@ +Debug +Release +Release-Asserts +Debug+Coverage-Asserts +Debug+Coverage +Release+Coverage +Debug+Checks + Propchange: llvm/trunk/examples/Kaleidoscope/Chapter4/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 3 16:07:07 2009 @@ -0,0 +1,8 @@ +Debug +Release +Release-Asserts +Debug+Coverage-Asserts +Debug+Coverage +Release+Coverage +Debug+Checks + Propchange: llvm/trunk/examples/Kaleidoscope/Chapter5/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 3 16:07:07 2009 @@ -0,0 +1,8 @@ +Debug +Release +Release-Asserts +Debug+Coverage-Asserts +Debug+Coverage +Release+Coverage +Debug+Checks + Propchange: llvm/trunk/examples/Kaleidoscope/Chapter6/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 3 16:07:07 2009 @@ -0,0 +1,8 @@ +Debug +Release +Release-Asserts +Debug+Coverage-Asserts +Debug+Coverage +Release+Coverage +Debug+Checks + Propchange: llvm/trunk/examples/Kaleidoscope/Chapter7/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 3 16:07:07 2009 @@ -0,0 +1,8 @@ +Debug +Release +Release-Asserts +Debug+Coverage-Asserts +Debug+Coverage +Release+Coverage +Debug+Checks + From grosbach at apple.com Tue Nov 3 16:07:35 2009 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 3 Nov 2009 14:07:35 -0800 Subject: [llvm-commits] [llvm] r85697 - in /llvm/trunk: lib/Target/ARM/ARMInstrNEON.td test/CodeGen/ARM/fmacs.ll test/CodeGen/ARM/fnmacs.ll test/CodeGen/Thumb2/cross-rc-coalescing-2.ll In-Reply-To: <72AADD0D-6CAF-433E-8533-A8157E28F8D9@gmail.com> References: <200910312257.n9VMvbZm030355@zion.cs.uiuc.edu> <72AADD0D-6CAF-433E-8533-A8157E28F8D9@gmail.com> Message-ID: <7098F362-DE42-4D5D-B84A-78C3ED93F2AA@apple.com> On Nov 2, 2009, at 1:53 AM, David Conrad wrote: > Thus even without modeling the special behaviour of vmla it's always > better to use it: it'll always be at least as fast as a separate vmul > +vadd. This applies to the integer versions as well. Hi David, Unfortunately, this turns out not to be the case. The NEON unit will stall adjacent instructions in the presence of vmla to preserve in- order retirement. If a RAW hazard is present, the stall is 8 (possibly 7) cycles, otherwise it is 4 cycles. It may be possible to model this with the recent post-allocation scheduler improvements, but for now it's better to just avoid the instructions when doing scalar math. Since we're using NEON vector instructions for scalar floating point math on the A8, having vmla intermingled with other NEON instructions is not uncommon in generated code. -Jim From bob.wilson at apple.com Tue Nov 3 16:11:13 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 3 Nov 2009 14:11:13 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r85950 - /llvm-gcc-4.2/trunk/build_gcc In-Reply-To: <200911032150.nA3Lo2Qr029092@zion.cs.uiuc.edu> References: <200911032150.nA3Lo2Qr029092@zion.cs.uiuc.edu> Message-ID: <53257430-5A04-4A96-88E0-5EB323584158@apple.com> This should not be necessary. Just set UNAME_RELEASE to the version number you want. On Nov 3, 2009, at 1:50 PM, Evan Cheng wrote: > Author: evancheng > Date: Tue Nov 3 15:50:02 2009 > New Revision: 85950 > > URL: http://llvm.org/viewvc/llvm-project?rev=85950&view=rev > Log: > Allow user to override DARWIN_VERS from command line. > > Modified: > llvm-gcc-4.2/trunk/build_gcc > > Modified: llvm-gcc-4.2/trunk/build_gcc > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=85950&r1=85949&r2=85950&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/build_gcc (original) > +++ llvm-gcc-4.2/trunk/build_gcc Tue Nov 3 15:50:02 2009 > @@ -116,7 +116,9 @@ > NON_ARM_CONFIGFLAGS="--with-gxx-include-dir=/usr/include/c++/ > $LIBSTDCXX_VERSION" > # LLVM LOCAL end > > -DARWIN_VERS=`uname -r | sed 's/\..*//'` > +if [ "x$DARWIN_VERS" == "x" ]; then > + DARWIN_VERS=`uname -r | sed 's/\..*//'` > +fi > echo DARWIN_VERS = $DARWIN_VERS > > # APPLE LOCAL begin ARM > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From criswell at cs.uiuc.edu Tue Nov 3 16:16:33 2009 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Nov 2009 16:16:33 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200911032216.nA3MGXMA023516@maute.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.27 -> 1.28 --- Log message: Replaced old text with newer text provided by Vikram. --- Diffs of the changes: (+2 -1) index.html | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.27 llvm-www/safecode/index.html:1.28 --- llvm-www/safecode/index.html:1.27 Tue Nov 3 09:38:56 2009 +++ llvm-www/safecode/index.html Tue Nov 3 16:15:36 2009 @@ -49,7 +49,8 @@

                          The purpose of the SAFECode project is to enable program safety without - runtime checks and garbage collection, using static analysis when + garbage collection and with minimal run-time checks using static + analysis when possible and run-time checks when necessary. SAFECode defines a code representation with minimal semantic restrictions designed to enable static enforcement of safety, using aggressive compiler techniques From isanbard at gmail.com Tue Nov 3 16:50:10 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 03 Nov 2009 22:50:10 -0000 Subject: [llvm-commits] [llvm] r85963 - /llvm/trunk/utils/buildit/build_llvm Message-ID: <200911032250.nA3MoA2p031728@zion.cs.uiuc.edu> Author: void Date: Tue Nov 3 16:50:10 2009 New Revision: 85963 URL: http://llvm.org/viewvc/llvm-project?rev=85963&view=rev Log: Use llvm-gcc on newer Darwins. Modified: llvm/trunk/utils/buildit/build_llvm Modified: llvm/trunk/utils/buildit/build_llvm URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/buildit/build_llvm?rev=85963&r1=85962&r2=85963&view=diff ============================================================================== --- llvm/trunk/utils/buildit/build_llvm (original) +++ llvm/trunk/utils/buildit/build_llvm Tue Nov 3 16:50:10 2009 @@ -123,7 +123,7 @@ PATH=$DIR/bin:$PATH # otherwise, try to use llvm-gcc if it's available -else +elif [ $DARWIN_VERS -gt 9 ]; then # If the user has set CC or CXX, respect their wishes. If not, # compile with LLVM-GCC/LLVM-G++ if available; if LLVM is not # available, fall back to usual GCC/G++ default. From evan.cheng at apple.com Tue Nov 3 17:13:34 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 23:13:34 -0000 Subject: [llvm-commits] [llvm] r85965 - in /llvm/trunk/lib/Target/ARM: ARMBaseInstrInfo.cpp ARMInstrThumb2.td Message-ID: <200911032313.nA3NDZtw032645@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 17:13:34 2009 New Revision: 85965 URL: http://llvm.org/viewvc/llvm-project?rev=85965&view=rev Log: Fix t2Int_eh_sjlj_setjmp. Immediate form of orr is a 32-bit instruction. So it should be 22 bytes instead of 20 bytes long. Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=85965&r1=85964&r2=85965&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Tue Nov 3 17:13:34 2009 @@ -448,7 +448,7 @@ case ARM::Int_eh_sjlj_setjmp: return 24; case ARM::t2Int_eh_sjlj_setjmp: - return 20; + return 22; case ARM::BR_JTr: case ARM::BR_JTm: case ARM::BR_JTadd: Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=85965&r1=85964&r2=85965&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Tue Nov 3 17:13:34 2009 @@ -1082,7 +1082,7 @@ AddrModeNone, SizeSpecial, NoItinerary, "str.w\tsp, [$src, #+8] @ eh_setjmp begin\n" "\tadr\tr12, 0f\n" - "\torr\tr12, #1\n" + "\torr.w\tr12, r12, #1\n" "\tstr.w\tr12, [$src, #+4]\n" "\tmovs\tr0, #0\n" "\tb\t1f\n" From sabre at nondot.org Tue Nov 3 17:40:48 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 03 Nov 2009 23:40:48 -0000 Subject: [llvm-commits] [llvm] r85973 - in /llvm/trunk: lib/Transforms/Scalar/SCCP.cpp test/Transforms/SCCP/ipsccp-basic.ll Message-ID: <200911032340.nA3NemmX001210@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 17:40:48 2009 New Revision: 85973 URL: http://llvm.org/viewvc/llvm-project?rev=85973&view=rev Log: reimplement multiple return value handling in IPSCCP, making it more aggressive an correct. This survives building llvm in 64-bit mode with optimizations and the built llvm passes make check. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85973&r1=85972&r2=85973&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Tue Nov 3 17:40:48 2009 @@ -159,6 +159,11 @@ SmallPtrSet BBExecutable;// The BBs that are executable. DenseMap ValueState; // The state each value is in. + /// StructValueState - This maintains ValueState for values that have + /// StructType, for example for formal arguments, calls, insertelement, etc. + /// + DenseMap, LatticeVal> StructValueState; + /// GlobalValue - If we are tracking any values for the contents of a global /// variable, we keep a mapping from the constant accessor to the element of /// the global, to the currently known value. If the value becomes @@ -173,6 +178,10 @@ /// TrackedMultipleRetVals - Same as TrackedRetVals, but used for functions /// that return multiple values. DenseMap, LatticeVal> TrackedMultipleRetVals; + + /// MRVFunctionsTracked - Each function in TrackedMultipleRetVals is + /// represented here for efficient lookup. + SmallPtrSet MRVFunctionsTracked; /// TrackingIncomingArguments - This is the set of functions for whose /// arguments we make optimistic assumptions about and try to prove as @@ -219,8 +228,8 @@ /// specified global variable if it can. This is only legal to call if /// performing Interprocedural SCCP. void TrackValueOfGlobalVariable(GlobalVariable *GV) { - const Type *ElTy = GV->getType()->getElementType(); - if (ElTy->isFirstClassType()) { + // We only track the contents of scalar globals. + if (GV->getType()->getElementType()->isSingleValueType()) { LatticeVal &IV = TrackedGlobals[GV]; if (!isa(GV->getInitializer())) IV.markConstant(GV->getInitializer()); @@ -233,6 +242,7 @@ void AddTrackedFunction(Function *F) { // Add an entry, F -> undef. if (const StructType *STy = dyn_cast(F->getReturnType())) { + MRVFunctionsTracked.insert(F); for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) TrackedMultipleRetVals.insert(std::make_pair(std::make_pair(F, i), LatticeVal())); @@ -264,6 +274,13 @@ assert(I != ValueState.end() && "V is not in valuemap!"); return I->second; } + + LatticeVal getStructLatticeValueFor(Value *V, unsigned i) const { + DenseMap, LatticeVal>::const_iterator I = + StructValueState.find(std::make_pair(V, i)); + assert(I != StructValueState.end() && "V is not in valuemap!"); + return I->second; + } /// getTrackedRetVals - Get the inferred return value map. /// @@ -278,9 +295,20 @@ } void markOverdefined(Value *V) { + assert(!isa(V->getType()) && "Should use other method"); markOverdefined(ValueState[V], V); } + /// markAnythingOverdefined - Mark the specified value overdefined. This + /// works with both scalars and structs. + void markAnythingOverdefined(Value *V) { + if (const StructType *STy = dyn_cast(V->getType())) + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + markOverdefined(getStructValueState(V, i), V); + else + markOverdefined(V); + } + private: // markConstant - Make a value be marked as "constant". If the value // is not already a constant, add it to the instruction work list so that @@ -293,10 +321,12 @@ } void markConstant(Value *V, Constant *C) { + assert(!isa(V->getType()) && "Should use other method"); markConstant(ValueState[V], V, C); } void markForcedConstant(Value *V, Constant *C) { + assert(!isa(V->getType()) && "Should use other method"); ValueState[V].markForcedConstant(C); DEBUG(errs() << "markForcedConstant: " << *C << ": " << *V << '\n'); InstWorkList.push_back(V); @@ -330,6 +360,7 @@ } void mergeInValue(Value *V, LatticeVal MergeWithV) { + assert(!isa(V->getType()) && "Should use other method"); mergeInValue(ValueState[V], V, MergeWithV); } @@ -338,8 +369,12 @@ /// value. This function handles the case when the value hasn't been seen yet /// by properly seeding constants etc. LatticeVal &getValueState(Value *V) { + assert(!isa(V->getType()) && "Should use getStructValueState"); + + // TODO: Change to do insert+find in one operation. DenseMap::iterator I = ValueState.find(V); - if (I != ValueState.end()) return I->second; // Common case, in the map + if (I != ValueState.end()) + return I->second; // Common case, already in the map. LatticeVal &LV = ValueState[V]; @@ -353,6 +388,39 @@ return LV; } + /// getStructValueState - Return the LatticeVal object that corresponds to the + /// value/field pair. This function handles the case when the value hasn't + /// been seen yet by properly seeding constants etc. + LatticeVal &getStructValueState(Value *V, unsigned i) { + assert(isa(V->getType()) && "Should use getValueState"); + assert(i < cast(V->getType())->getNumElements() && + "Invalid element #"); + + // TODO: Change to do insert+find in one operation. + DenseMap, LatticeVal>::iterator + I = StructValueState.find(std::make_pair(V, i)); + if (I != StructValueState.end()) + return I->second; // Common case, already in the map. + + LatticeVal &LV = StructValueState[std::make_pair(V, i)]; + + if (Constant *C = dyn_cast(V)) { + if (isa(C)) + ; // Undef values remain undefined. + else if (ConstantStruct *CS = dyn_cast(C)) + LV.markConstant(CS->getOperand(i)); // Constants are constant. + else if (isa(C)) { + const Type *FieldTy = cast(V->getType())->getElementType(i); + LV.markConstant(Constant::getNullValue(FieldTy)); + } else + LV.markOverdefined(); // Unknown sort of constant. + } + + // All others are underdefined by default. + return LV; + } + + /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB /// work list if it is not already executable. void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) { @@ -444,12 +512,12 @@ void visitUnreachableInst(TerminatorInst &I) { /*returns void*/ } void visitAllocaInst (Instruction &I) { markOverdefined(&I); } void visitVANextInst (Instruction &I) { markOverdefined(&I); } - void visitVAArgInst (Instruction &I) { markOverdefined(&I); } + void visitVAArgInst (Instruction &I) { markAnythingOverdefined(&I); } void visitInstruction(Instruction &I) { // If a new instruction is added to LLVM that we don't handle. errs() << "SCCP: Don't know how to handle: " << I; - markOverdefined(&I); // Just in case + markAnythingOverdefined(&I); // Just in case } }; @@ -596,6 +664,11 @@ // successors executable. // void SCCPSolver::visitPHINode(PHINode &PN) { + // If this PN returns a struct, just mark the result overdefined. + // TODO: We could do a lot better than this if code actually uses this. + if (isa(PN.getType())) + return markAnythingOverdefined(&PN); + if (getValueState(&PN).isOverdefined()) { // There may be instructions using this PHI node that are not overdefined // themselves. If so, make sure that they know that the PHI node operand @@ -617,7 +690,7 @@ // and slow us down a lot. Just mark them overdefined. if (PN.getNumIncomingValues() > 64) return markOverdefined(&PN); - + // Look at all of the executable operands of the PHI node. If any of them // are overdefined, the PHI becomes overdefined as well. If they are all // constant, and they agree with each other, the PHI becomes the identical @@ -666,28 +739,26 @@ if (I.getNumOperands() == 0) return; // ret void Function *F = I.getParent()->getParent(); + Value *ResultOp = I.getOperand(0); // If we are tracking the return value of this function, merge it in. - if (!TrackedRetVals.empty()) { + if (!TrackedRetVals.empty() && !isa(ResultOp->getType())) { DenseMap::iterator TFRVI = TrackedRetVals.find(F); if (TFRVI != TrackedRetVals.end()) { - mergeInValue(TFRVI->second, F, getValueState(I.getOperand(0))); + mergeInValue(TFRVI->second, F, getValueState(ResultOp)); return; } } // Handle functions that return multiple values. - if (!TrackedMultipleRetVals.empty() && - isa(I.getOperand(0)->getType())) { - for (unsigned i = 0, e = I.getOperand(0)->getType()->getNumContainedTypes(); - i != e; ++i) { - DenseMap, LatticeVal>::iterator - It = TrackedMultipleRetVals.find(std::make_pair(F, i)); - if (It == TrackedMultipleRetVals.end()) break; - if (Value *Val = FindInsertedValue(I.getOperand(0), i, I.getContext())) - mergeInValue(It->second, F, getValueState(Val)); - } + if (!TrackedMultipleRetVals.empty()) { + if (const StructType *STy = dyn_cast(ResultOp->getType())) + if (MRVFunctionsTracked.count(F)) + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + mergeInValue(TrackedMultipleRetVals[std::make_pair(F, i)], F, + getStructValueState(ResultOp, i)); + } } @@ -712,78 +783,62 @@ OpSt.getConstant(), I.getType())); } -void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) { - Value *Aggr = EVI.getAggregateOperand(); - - // If the operand to the extractvalue is an undef, the result is undef. - if (isa(Aggr)) - return; - // Currently only handle single-index extractvalues. +void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) { + // If this returns a struct, mark all elements over defined, we don't track + // structs in structs. + if (isa(EVI.getType())) + return markAnythingOverdefined(&EVI); + + // If this is extracting from more than one level of struct, we don't know. if (EVI.getNumIndices() != 1) return markOverdefined(&EVI); - - Function *F = 0; - if (CallInst *CI = dyn_cast(Aggr)) - F = CI->getCalledFunction(); - else if (InvokeInst *II = dyn_cast(Aggr)) - F = II->getCalledFunction(); - - // TODO: If IPSCCP resolves the callee of this function, we could propagate a - // result back! - if (F == 0 || TrackedMultipleRetVals.empty()) - return markOverdefined(&EVI); - - // See if we are tracking the result of the callee. If not tracking this - // function (for example, it is a declaration) just move to overdefined. - if (!TrackedMultipleRetVals.count(std::make_pair(F, *EVI.idx_begin()))) - return markOverdefined(&EVI); - - // Otherwise, the value will be merged in here as a result of CallSite - // handling. + + Value *AggVal = EVI.getAggregateOperand(); + unsigned i = *EVI.idx_begin(); + LatticeVal EltVal = getStructValueState(AggVal, i); + mergeInValue(getValueState(&EVI), &EVI, EltVal); } void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) { - Value *Aggr = IVI.getAggregateOperand(); - Value *Val = IVI.getInsertedValueOperand(); - - // If the operands to the insertvalue are undef, the result is undef. - if (isa(Aggr) && isa(Val)) - return; - - // Currently only handle single-index insertvalues. - if (IVI.getNumIndices() != 1) + const StructType *STy = dyn_cast(IVI.getType()); + if (STy == 0) return markOverdefined(&IVI); - - // Currently only handle insertvalue instructions that are in a single-use - // chain that builds up a return value. - for (const InsertValueInst *TmpIVI = &IVI; ; ) { - if (!TmpIVI->hasOneUse()) - return markOverdefined(&IVI); - - const Value *V = *TmpIVI->use_begin(); - if (isa(V)) - break; - TmpIVI = dyn_cast(V); - if (!TmpIVI) - return markOverdefined(&IVI); - } - - // See if we are tracking the result of the callee. - Function *F = IVI.getParent()->getParent(); - DenseMap, LatticeVal>::iterator - It = TrackedMultipleRetVals.find(std::make_pair(F, *IVI.idx_begin())); - - // Merge in the inserted member value. - if (It != TrackedMultipleRetVals.end()) - mergeInValue(It->second, F, getValueState(Val)); - - // Mark the aggregate result of the IVI overdefined; any tracking that we do - // will be done on the individual member values. - markOverdefined(&IVI); + + // If this has more than one index, we can't handle it, drive all results to + // undef. + if (IVI.getNumIndices() != 1) + return markAnythingOverdefined(&IVI); + + Value *Aggr = IVI.getAggregateOperand(); + unsigned Idx = *IVI.idx_begin(); + + // Compute the result based on what we're inserting. + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + // This passes through all values that aren't the inserted element. + if (i != Idx) { + LatticeVal EltVal = getStructValueState(Aggr, i); + mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal); + continue; + } + + Value *Val = IVI.getInsertedValueOperand(); + if (isa(Val->getType())) + // We don't track structs in structs. + markOverdefined(getStructValueState(&IVI, i), &IVI); + else { + LatticeVal InVal = getValueState(Val); + mergeInValue(getStructValueState(&IVI, i), &IVI, InVal); + } + } } void SCCPSolver::visitSelectInst(SelectInst &I) { + // If this select returns a struct, just mark the result overdefined. + // TODO: We could do a lot better than this if code actually uses this. + if (isa(I.getType())) + return markAnythingOverdefined(&I); + LatticeVal CondValue = getValueState(I.getCondition()); if (CondValue.isUndefined()) return; @@ -1011,7 +1066,7 @@ } void SCCPSolver::visitExtractElementInst(ExtractElementInst &I) { - // FIXME : SCCP does not handle vectors properly. + // TODO : SCCP does not handle vectors properly. return markOverdefined(&I); #if 0 @@ -1027,7 +1082,7 @@ } void SCCPSolver::visitInsertElementInst(InsertElementInst &I) { - // FIXME : SCCP does not handle vectors properly. + // TODO : SCCP does not handle vectors properly. return markOverdefined(&I); #if 0 LatticeVal &ValState = getValueState(I.getOperand(0)); @@ -1051,7 +1106,7 @@ } void SCCPSolver::visitShuffleVectorInst(ShuffleVectorInst &I) { - // FIXME : SCCP does not handle vectors properly. + // TODO : SCCP does not handle vectors properly. return markOverdefined(&I); #if 0 LatticeVal &V1State = getValueState(I.getOperand(0)); @@ -1105,6 +1160,10 @@ } void SCCPSolver::visitStoreInst(StoreInst &SI) { + // If this store is of a struct, ignore it. + if (isa(SI.getOperand(0)->getType())) + return; + if (TrackedGlobals.empty() || !isa(SI.getOperand(1))) return; @@ -1122,6 +1181,10 @@ // Handle load instructions. If the operand is a constant pointer to a constant // global, we can replace the load with the loaded constant value! void SCCPSolver::visitLoadInst(LoadInst &I) { + // If this load is of a struct, just mark the result overdefined. + if (isa(I.getType())) + return markAnythingOverdefined(&I); + LatticeVal PtrVal = getValueState(I.getOperand(0)); if (PtrVal.isUndefined()) return; // The pointer is not resolved yet! @@ -1196,7 +1259,7 @@ } // Otherwise, we don't know anything about this call, mark it overdefined. - return markOverdefined(I); + return markAnythingOverdefined(I); } // If this is a local function that doesn't have its address taken, mark its @@ -1216,47 +1279,33 @@ continue; } - mergeInValue(AI, getValueState(*CAI)); + if (const StructType *STy = dyn_cast(AI->getType())) { + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + mergeInValue(getStructValueState(AI, i), AI, + getStructValueState(*CAI, i)); + } else { + mergeInValue(AI, getValueState(*CAI)); + } } } // If this is a single/zero retval case, see if we're tracking the function. - DenseMap::iterator TFRVI = TrackedRetVals.find(F); - if (TFRVI != TrackedRetVals.end()) { + if (const StructType *STy = dyn_cast(F->getReturnType())) { + if (!MRVFunctionsTracked.count(F)) + goto CallOverdefined; // Not tracking this callee. + + // If we are tracking this callee, propagate the result of the function + // into this call site. + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + mergeInValue(getStructValueState(I, i), I, + TrackedMultipleRetVals[std::make_pair(F, i)]); + } else { + DenseMap::iterator TFRVI = TrackedRetVals.find(F); + if (TFRVI == TrackedRetVals.end()) + goto CallOverdefined; // Not tracking this callee. + // If so, propagate the return value of the callee into this call result. mergeInValue(I, TFRVI->second); - } else if (isa(I->getType())) { - // Check to see if we're tracking this callee, if not, handle it in the - // common path above. - DenseMap, LatticeVal>::iterator - TMRVI = TrackedMultipleRetVals.find(std::make_pair(F, 0)); - if (TMRVI == TrackedMultipleRetVals.end()) - goto CallOverdefined; - - // Need to mark as overdefined, otherwise it stays undefined which - // creates extractvalue undef, - markOverdefined(I); - - // If we are tracking this callee, propagate the return values of the call - // into this call site. We do this by walking all the uses. Single-index - // ExtractValueInst uses can be tracked; anything more complicated is - // currently handled conservatively. - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); - UI != E; ++UI) { - if (ExtractValueInst *EVI = dyn_cast(*UI)) { - if (EVI->getNumIndices() == 1) { - mergeInValue(EVI, - TrackedMultipleRetVals[std::make_pair(F, *EVI->idx_begin())]); - continue; - } - } - // The aggregate value is used in a way not handled here. Assume nothing. - markOverdefined(*UI); - } - } else { - // Otherwise we're not tracking this callee, so handle it in the - // common path above. - goto CallOverdefined; } } @@ -1297,7 +1346,7 @@ // since all of its users will have already been marked as overdefined. // Update all of the users of this instruction's value. // - if (!getValueState(I).isOverdefined()) + if (isa(I->getType()) || !getValueState(I).isOverdefined()) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) if (Instruction *I = dyn_cast(*UI)) @@ -1345,13 +1394,35 @@ // Look for instructions which produce undef values. if (I->getType()->isVoidTy()) continue; + if (const StructType *STy = dyn_cast(I->getType())) { + // Only a few things that can be structs matter for undef. Just send + // all their results to overdefined. We could be more precise than this + // but it isn't worth bothering. + if (isa(I) || isa(I)) { + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + LatticeVal &LV = getStructValueState(I, i); + if (LV.isUndefined()) + markOverdefined(LV, I); + } + } + continue; + } + LatticeVal &LV = getValueState(I); if (!LV.isUndefined()) continue; + // No instructions using structs need disambiguation. + if (isa(I->getOperand(0)->getType())) + continue; + // Get the lattice values of the first two operands for use below. LatticeVal Op0LV = getValueState(I->getOperand(0)); LatticeVal Op1LV; if (I->getNumOperands() == 2) { + // No instructions using structs need disambiguation. + if (isa(I->getOperand(1)->getType())) + continue; + // If this is a two-operand instruction, and if both operands are // undefs, the result stays undef. Op1LV = getValueState(I->getOperand(1)); @@ -1547,7 +1618,7 @@ // Mark all arguments to the function as being overdefined. for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); AI != E;++AI) - Solver.markOverdefined(AI); + Solver.markAnythingOverdefined(AI); // Solve for constants. bool ResolvedUndefs = true; @@ -1578,6 +1649,10 @@ if (Inst->getType()->isVoidTy() || isa(Inst)) continue; + // TODO: Reconstruct structs from their elements. + if (isa(Inst->getType())) + continue; + LatticeVal IV = Solver.getLatticeValueFor(Inst); if (IV.isOverdefined()) continue; @@ -1661,8 +1736,7 @@ // If this is a strong or ODR definition of this function, then we can // propagate information about its result into callsites of it. - if (!F->mayBeOverridden() && - !isa(F->getReturnType())) + if (!F->mayBeOverridden()) Solver.AddTrackedFunction(F); // If this function only has direct calls that we can see, we can track its @@ -1679,7 +1753,7 @@ // Assume nothing about the incoming arguments. for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI) - Solver.markOverdefined(AI); + Solver.markAnythingOverdefined(AI); } // Loop over global variables. We inform the solver about any internal global @@ -1712,8 +1786,11 @@ if (Solver.isBlockExecutable(F->begin())) { for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI) { - if (AI->use_empty()) continue; + if (AI->use_empty() || isa(AI->getType())) continue; + // TODO: Could use getStructLatticeValueFor to find out if the entire + // result is a constant and replace it entirely if so. + LatticeVal IV = Solver.getLatticeValueFor(AI); if (IV.isOverdefined()) continue; @@ -1752,9 +1829,12 @@ for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) { Instruction *Inst = BI++; - if (Inst->getType()->isVoidTy()) + if (Inst->getType()->isVoidTy() || isa(Inst->getType())) continue; + // TODO: Could use getStructLatticeValueFor to find out if the entire + // result is a constant and replace it entirely if so. + LatticeVal IV = Solver.getLatticeValueFor(Inst); if (IV.isOverdefined()) continue; Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll?rev=85973&r1=85972&r2=85973&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll (original) +++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Tue Nov 3 17:40:48 2009 @@ -1,5 +1,4 @@ ; RUN: opt < %s -ipsccp -S | FileCheck %s -; XFAIL: * ;;======================== test1 @@ -128,7 +127,7 @@ ; CHECK: define i64 @test5b() ; CHECK: A: ; CHECK-NEXT: %c = call i64 @test5c(%0 %a) -; CHECK-NEXT: ret i64 %c +; CHECK-NEXT: ret i64 5 define internal i64 @test5c({i64,i64} %a) { %b = extractvalue {i64,i64} %a, 0 From evan.cheng at apple.com Tue Nov 3 17:42:41 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 03 Nov 2009 23:42:41 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85974 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200911032342.nA3NgfOO001271@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 17:42:40 2009 New Revision: 85974 URL: http://llvm.org/viewvc/llvm-project?rev=85974&view=rev Log: Revert 85950. It's not necessary. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=85974&r1=85973&r2=85974&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Tue Nov 3 17:42:40 2009 @@ -116,9 +116,7 @@ NON_ARM_CONFIGFLAGS="--with-gxx-include-dir=/usr/include/c++/$LIBSTDCXX_VERSION" # LLVM LOCAL end -if [ "x$DARWIN_VERS" == "x" ]; then - DARWIN_VERS=`uname -r | sed 's/\..*//'` -fi +DARWIN_VERS=`uname -r | sed 's/\..*//'` echo DARWIN_VERS = $DARWIN_VERS # APPLE LOCAL begin ARM From bob.wilson at apple.com Tue Nov 3 17:44:32 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 03 Nov 2009 23:44:32 -0000 Subject: [llvm-commits] [llvm] r85975 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200911032344.nA3NiWK7001336@zion.cs.uiuc.edu> Author: bwilson Date: Tue Nov 3 17:44:31 2009 New Revision: 85975 URL: http://llvm.org/viewvc/llvm-project?rev=85975&view=rev Log: Fix branch folding bug for indirect branches: for a block containing only an unconditional branch (possibly from tail merging), this code is trying to redirect all of its predecessors to go directly to the branch target, but that isn't feasible for indirect branches. The other predecessors (that don't end with indirect branches) could theoretically still be handled, but that is not easily done right now. The AnalyzeBranch interface doesn't currently let us distinguish jump table branches from indirect branches, and this code is currently handling jump tables. To avoid punting on address-taken blocks, we would have to give up handling jump tables. That seems like a bad tradeoff. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=85975&r1=85974&r2=85975&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Tue Nov 3 17:44:31 2009 @@ -1050,7 +1050,8 @@ // If this branch is the only thing in its block, see if we can forward // other blocks across it. if (CurTBB && CurCond.empty() && CurFBB == 0 && - MBB->begin()->getDesc().isBranch() && CurTBB != MBB) { + MBB->begin()->getDesc().isBranch() && CurTBB != MBB && + !MBB->hasAddressTaken()) { // This block may contain just an unconditional branch. Because there can // be 'non-branch terminators' in the block, try removing the branch and // then seeing if the block is empty. From lhames at gmail.com Tue Nov 3 17:52:08 2009 From: lhames at gmail.com (Lang Hames) Date: Tue, 03 Nov 2009 23:52:08 -0000 Subject: [llvm-commits] [llvm] r85979 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ Message-ID: <200911032352.nA3Nq9hl001625@zion.cs.uiuc.edu> Author: lhames Date: Tue Nov 3 17:52:08 2009 New Revision: 85979 URL: http://llvm.org/viewvc/llvm-project?rev=85979&view=rev Log: The Indexes Patch. This introduces a new pass, SlotIndexes, which is responsible for numbering instructions for register allocation (and other clients). SlotIndexes numbering is designed to match the existing scheme, so this patch should not cause any changes in the generated code. For consistency, and to avoid naming confusion, LiveIndex has been renamed SlotIndex. The processImplicitDefs method of the LiveIntervals analysis has been moved into its own pass so that it can be run prior to SlotIndexes. This was necessary to match the existing numbering scheme. Added: llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h llvm/trunk/include/llvm/CodeGen/SlotIndexes.h llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp llvm/trunk/lib/CodeGen/SlotIndexes.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/include/llvm/CodeGen/LiveStackAnalysis.h llvm/trunk/lib/CodeGen/LiveInterval.cpp llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/LiveStackAnalysis.cpp llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h llvm/trunk/lib/CodeGen/Spiller.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/lib/CodeGen/VirtRegMap.h Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveInterval.h?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveInterval.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveInterval.h Tue Nov 3 17:52:08 2009 @@ -21,221 +21,19 @@ #ifndef LLVM_CODEGEN_LIVEINTERVAL_H #define LLVM_CODEGEN_LIVEINTERVAL_H -#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/AlignOf.h" +#include "llvm/CodeGen/SlotIndexes.h" #include #include namespace llvm { + class LiveIntervals; class MachineInstr; class MachineRegisterInfo; class TargetRegisterInfo; class raw_ostream; - - /// LiveIndex - An opaque wrapper around machine indexes. - class LiveIndex { - friend class VNInfo; - friend class LiveInterval; - friend class LiveIntervals; - friend struct DenseMapInfo; - - public: - - enum Slot { LOAD, USE, DEF, STORE, NUM }; - - private: - - unsigned index; - - static const unsigned PHI_BIT = 1 << 31; - - public: - - /// Construct a default LiveIndex pointing to a reserved index. - LiveIndex() : index(0) {} - - /// Construct an index from the given index, pointing to the given slot. - LiveIndex(LiveIndex m, Slot s) - : index((m.index / NUM) * NUM + s) {} - - /// Print this index to the given raw_ostream. - void print(raw_ostream &os) const; - - /// Compare two LiveIndex objects for equality. - bool operator==(LiveIndex other) const { - return ((index & ~PHI_BIT) == (other.index & ~PHI_BIT)); - } - /// Compare two LiveIndex objects for inequality. - bool operator!=(LiveIndex other) const { - return ((index & ~PHI_BIT) != (other.index & ~PHI_BIT)); - } - - /// Compare two LiveIndex objects. Return true if the first index - /// is strictly lower than the second. - bool operator<(LiveIndex other) const { - return ((index & ~PHI_BIT) < (other.index & ~PHI_BIT)); - } - /// Compare two LiveIndex objects. Return true if the first index - /// is lower than, or equal to, the second. - bool operator<=(LiveIndex other) const { - return ((index & ~PHI_BIT) <= (other.index & ~PHI_BIT)); - } - - /// Compare two LiveIndex objects. Return true if the first index - /// is greater than the second. - bool operator>(LiveIndex other) const { - return ((index & ~PHI_BIT) > (other.index & ~PHI_BIT)); - } - - /// Compare two LiveIndex objects. Return true if the first index - /// is greater than, or equal to, the second. - bool operator>=(LiveIndex other) const { - return ((index & ~PHI_BIT) >= (other.index & ~PHI_BIT)); - } - - /// Returns true if this index represents a load. - bool isLoad() const { - return ((index % NUM) == LOAD); - } - - /// Returns true if this index represents a use. - bool isUse() const { - return ((index % NUM) == USE); - } - - /// Returns true if this index represents a def. - bool isDef() const { - return ((index % NUM) == DEF); - } - - /// Returns true if this index represents a store. - bool isStore() const { - return ((index % NUM) == STORE); - } - - /// Returns the slot for this LiveIndex. - Slot getSlot() const { - return static_cast(index % NUM); - } - - /// Returns true if this index represents a non-PHI use/def. - bool isNonPHIIndex() const { - return ((index & PHI_BIT) == 0); - } - - /// Returns true if this index represents a PHI use/def. - bool isPHIIndex() const { - return ((index & PHI_BIT) == PHI_BIT); - } - - private: - - /// Construct an index from the given index, with its PHI kill marker set. - LiveIndex(bool phi, LiveIndex o) : index(o.index) { - if (phi) - index |= PHI_BIT; - else - index &= ~PHI_BIT; - } - - explicit LiveIndex(unsigned idx) - : index(idx & ~PHI_BIT) {} - - LiveIndex(bool phi, unsigned idx) - : index(idx & ~PHI_BIT) { - if (phi) - index |= PHI_BIT; - } - - LiveIndex(bool phi, unsigned idx, Slot slot) - : index(((idx / NUM) * NUM + slot) & ~PHI_BIT) { - if (phi) - index |= PHI_BIT; - } - - LiveIndex nextSlot_() const { - assert((index & PHI_BIT) == ((index + 1) & PHI_BIT) && - "Index out of bounds."); - return LiveIndex(index + 1); - } - - LiveIndex nextIndex_() const { - assert((index & PHI_BIT) == ((index + NUM) & PHI_BIT) && - "Index out of bounds."); - return LiveIndex(index + NUM); - } - - LiveIndex prevSlot_() const { - assert((index & PHI_BIT) == ((index - 1) & PHI_BIT) && - "Index out of bounds."); - return LiveIndex(index - 1); - } - - LiveIndex prevIndex_() const { - assert((index & PHI_BIT) == ((index - NUM) & PHI_BIT) && - "Index out of bounds."); - return LiveIndex(index - NUM); - } - - int distance(LiveIndex other) const { - return (other.index & ~PHI_BIT) - (index & ~PHI_BIT); - } - - /// Returns an unsigned number suitable as an index into a - /// vector over all instructions. - unsigned getVecIndex() const { - return (index & ~PHI_BIT) / NUM; - } - - /// Scale this index by the given factor. - LiveIndex scale(unsigned factor) const { - unsigned i = (index & ~PHI_BIT) / NUM, - o = (index % ~PHI_BIT) % NUM; - assert(index <= (~0U & ~PHI_BIT) / (factor * NUM) && - "Rescaled interval would overflow"); - return LiveIndex(i * NUM * factor, o); - } - - static LiveIndex emptyKey() { - return LiveIndex(true, 0x7fffffff); - } - - static LiveIndex tombstoneKey() { - return LiveIndex(true, 0x7ffffffe); - } - - static unsigned getHashValue(const LiveIndex &v) { - return v.index * 37; - } - - }; - - inline raw_ostream& operator<<(raw_ostream &os, LiveIndex mi) { - mi.print(os); - return os; - } - - /// Densemap specialization for LiveIndex. - template <> - struct DenseMapInfo { - static inline LiveIndex getEmptyKey() { - return LiveIndex::emptyKey(); - } - static inline LiveIndex getTombstoneKey() { - return LiveIndex::tombstoneKey(); - } - static inline unsigned getHashValue(const LiveIndex &v) { - return LiveIndex::getHashValue(v); - } - static inline bool isEqual(const LiveIndex &LHS, - const LiveIndex &RHS) { - return (LHS == RHS); - } - static inline bool isPod() { return true; } - }; - /// VNInfo - Value Number Information. /// This class holds information about a machine level values, including @@ -270,23 +68,25 @@ public: - typedef SmallVector KillSet; + typedef SmallVector KillSet; /// The ID number of this value. unsigned id; /// The index of the defining instruction (if isDefAccurate() returns true). - LiveIndex def; + SlotIndex def; KillSet kills; - VNInfo() - : flags(IS_UNUSED), id(~1U) { cr.copy = 0; } + /* + VNInfo(LiveIntervals &li_) + : defflags(IS_UNUSED), id(~1U) { cr.copy = 0; } + */ /// VNInfo constructor. /// d is presumed to point to the actual defining instr. If it doesn't /// setIsDefAccurate(false) should be called after construction. - VNInfo(unsigned i, LiveIndex d, MachineInstr *c) + VNInfo(unsigned i, SlotIndex d, MachineInstr *c) : flags(IS_DEF_ACCURATE), id(i), def(d) { cr.copy = c; } /// VNInfo construtor, copies values from orig, except for the value number. @@ -377,7 +177,7 @@ } /// Returns true if the given index is a kill of this value. - bool isKill(LiveIndex k) const { + bool isKill(SlotIndex k) const { KillSet::const_iterator i = std::lower_bound(kills.begin(), kills.end(), k); return (i != kills.end() && *i == k); @@ -385,7 +185,7 @@ /// addKill - Add a kill instruction index to the specified value /// number. - void addKill(LiveIndex k) { + void addKill(SlotIndex k) { if (kills.empty()) { kills.push_back(k); } else { @@ -397,7 +197,7 @@ /// Remove the specified kill index from this value's kills list. /// Returns true if the value was present, otherwise returns false. - bool removeKill(LiveIndex k) { + bool removeKill(SlotIndex k) { KillSet::iterator i = std::lower_bound(kills.begin(), kills.end(), k); if (i != kills.end() && *i == k) { kills.erase(i); @@ -407,7 +207,7 @@ } /// Remove all kills in the range [s, e). - void removeKills(LiveIndex s, LiveIndex e) { + void removeKills(SlotIndex s, SlotIndex e) { KillSet::iterator si = std::lower_bound(kills.begin(), kills.end(), s), se = std::upper_bound(kills.begin(), kills.end(), e); @@ -421,11 +221,11 @@ /// program, with an inclusive start point and an exclusive end point. /// These ranges are rendered as [start,end). struct LiveRange { - LiveIndex start; // Start point of the interval (inclusive) - LiveIndex end; // End point of the interval (exclusive) + SlotIndex start; // Start point of the interval (inclusive) + SlotIndex end; // End point of the interval (exclusive) VNInfo *valno; // identifier for the value contained in this interval. - LiveRange(LiveIndex S, LiveIndex E, VNInfo *V) + LiveRange(SlotIndex S, SlotIndex E, VNInfo *V) : start(S), end(E), valno(V) { assert(S < E && "Cannot create empty or backwards range"); @@ -433,13 +233,13 @@ /// contains - Return true if the index is covered by this range. /// - bool contains(LiveIndex I) const { + bool contains(SlotIndex I) const { return start <= I && I < end; } /// containsRange - Return true if the given range, [S, E), is covered by /// this range. - bool containsRange(LiveIndex S, LiveIndex E) const { + bool containsRange(SlotIndex S, SlotIndex E) const { assert((S < E) && "Backwards interval?"); return (start <= S && S < end) && (start < E && E <= end); } @@ -461,11 +261,11 @@ raw_ostream& operator<<(raw_ostream& os, const LiveRange &LR); - inline bool operator<(LiveIndex V, const LiveRange &LR) { + inline bool operator<(SlotIndex V, const LiveRange &LR) { return V < LR.start; } - inline bool operator<(const LiveRange &LR, LiveIndex V) { + inline bool operator<(const LiveRange &LR, SlotIndex V) { return LR.start < V; } @@ -522,7 +322,7 @@ /// end of the interval. If no LiveRange contains this position, but the /// position is in a hole, this method returns an iterator pointing the the /// LiveRange immediately after the hole. - iterator advanceTo(iterator I, LiveIndex Pos) { + iterator advanceTo(iterator I, SlotIndex Pos) { if (Pos >= endIndex()) return end(); while (I->end <= Pos) ++I; @@ -569,7 +369,7 @@ /// getNextValue - Create a new value number and return it. MIIdx specifies /// the instruction that defines the value number. - VNInfo *getNextValue(LiveIndex def, MachineInstr *CopyMI, + VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI, bool isDefAccurate, BumpPtrAllocator &VNInfoAllocator){ VNInfo *VNI = static_cast(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo), @@ -625,13 +425,15 @@ /// current interval, but are defined in the Clobbers interval, mark them /// used with an unknown definition value. Caller must pass in reference to /// VNInfoAllocator since it will create a new val#. - void MergeInClobberRanges(const LiveInterval &Clobbers, + void MergeInClobberRanges(LiveIntervals &li_, + const LiveInterval &Clobbers, BumpPtrAllocator &VNInfoAllocator); /// MergeInClobberRange - Same as MergeInClobberRanges except it merge in a /// single LiveRange only. - void MergeInClobberRange(LiveIndex Start, - LiveIndex End, + void MergeInClobberRange(LiveIntervals &li_, + SlotIndex Start, + SlotIndex End, BumpPtrAllocator &VNInfoAllocator); /// MergeValueInAsValue - Merge all of the live ranges of a specific val# @@ -657,56 +459,54 @@ bool empty() const { return ranges.empty(); } /// beginIndex - Return the lowest numbered slot covered by interval. - LiveIndex beginIndex() const { - if (empty()) - return LiveIndex(); + SlotIndex beginIndex() const { + assert(!empty() && "Call to beginIndex() on empty interval."); return ranges.front().start; } /// endNumber - return the maximum point of the interval of the whole, /// exclusive. - LiveIndex endIndex() const { - if (empty()) - return LiveIndex(); + SlotIndex endIndex() const { + assert(!empty() && "Call to endIndex() on empty interval."); return ranges.back().end; } - bool expiredAt(LiveIndex index) const { + bool expiredAt(SlotIndex index) const { return index >= endIndex(); } - bool liveAt(LiveIndex index) const; + bool liveAt(SlotIndex index) const; // liveBeforeAndAt - Check if the interval is live at the index and the // index just before it. If index is liveAt, check if it starts a new live // range.If it does, then check if the previous live range ends at index-1. - bool liveBeforeAndAt(LiveIndex index) const; + bool liveBeforeAndAt(SlotIndex index) const; /// getLiveRangeContaining - Return the live range that contains the /// specified index, or null if there is none. - const LiveRange *getLiveRangeContaining(LiveIndex Idx) const { + const LiveRange *getLiveRangeContaining(SlotIndex Idx) const { const_iterator I = FindLiveRangeContaining(Idx); return I == end() ? 0 : &*I; } /// getLiveRangeContaining - Return the live range that contains the /// specified index, or null if there is none. - LiveRange *getLiveRangeContaining(LiveIndex Idx) { + LiveRange *getLiveRangeContaining(SlotIndex Idx) { iterator I = FindLiveRangeContaining(Idx); return I == end() ? 0 : &*I; } /// FindLiveRangeContaining - Return an iterator to the live range that /// contains the specified index, or end() if there is none. - const_iterator FindLiveRangeContaining(LiveIndex Idx) const; + const_iterator FindLiveRangeContaining(SlotIndex Idx) const; /// FindLiveRangeContaining - Return an iterator to the live range that /// contains the specified index, or end() if there is none. - iterator FindLiveRangeContaining(LiveIndex Idx); + iterator FindLiveRangeContaining(SlotIndex Idx); /// findDefinedVNInfo - Find the by the specified /// index (register interval) or defined - VNInfo *findDefinedVNInfoForRegInt(LiveIndex Idx) const; + VNInfo *findDefinedVNInfoForRegInt(SlotIndex Idx) const; /// findDefinedVNInfo - Find the VNInfo that's defined by the specified /// register (stack inteval only). @@ -721,7 +521,7 @@ /// overlaps - Return true if the live interval overlaps a range specified /// by [Start, End). - bool overlaps(LiveIndex Start, LiveIndex End) const; + bool overlaps(SlotIndex Start, SlotIndex End) const; /// overlapsFrom - Return true if the intersection of the two live intervals /// is not empty. The specified iterator is a hint that we can begin @@ -738,18 +538,19 @@ /// join - Join two live intervals (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS intervals as specified. If /// the intervals are not joinable, this aborts. - void join(LiveInterval &Other, const int *ValNoAssignments, + void join(LiveInterval &Other, + const int *ValNoAssignments, const int *RHSValNoAssignments, SmallVector &NewVNInfo, MachineRegisterInfo *MRI); /// isInOneLiveRange - Return true if the range specified is entirely in the /// a single LiveRange of the live interval. - bool isInOneLiveRange(LiveIndex Start, LiveIndex End); + bool isInOneLiveRange(SlotIndex Start, SlotIndex End); /// removeRange - Remove the specified range from this interval. Note that /// the range must be a single LiveRange in its entirety. - void removeRange(LiveIndex Start, LiveIndex End, + void removeRange(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo = false); void removeRange(LiveRange LR, bool RemoveDeadValNo = false) { @@ -773,8 +574,8 @@ void ComputeJoinedWeight(const LiveInterval &Other); bool operator<(const LiveInterval& other) const { - const LiveIndex &thisIndex = beginIndex(); - const LiveIndex &otherIndex = other.beginIndex(); + const SlotIndex &thisIndex = beginIndex(); + const SlotIndex &otherIndex = other.beginIndex(); return (thisIndex < otherIndex || (thisIndex == otherIndex && reg < other.reg)); } @@ -785,8 +586,9 @@ private: Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From); - void extendIntervalEndTo(Ranges::iterator I, LiveIndex NewEnd); - Ranges::iterator extendIntervalStartTo(Ranges::iterator I, LiveIndex NewStr); + void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd); + Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr); + LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT }; Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Tue Nov 3 17:52:08 2009 @@ -23,12 +23,14 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include +#include namespace llvm { @@ -40,21 +42,6 @@ class TargetInstrInfo; class TargetRegisterClass; class VirtRegMap; - typedef std::pair IdxMBBPair; - - inline bool operator<(LiveIndex V, const IdxMBBPair &IM) { - return V < IM.first; - } - - inline bool operator<(const IdxMBBPair &IM, LiveIndex V) { - return IM.first < V; - } - - struct Idx2MBBCompare { - bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const { - return LHS.first < RHS.first; - } - }; class LiveIntervals : public MachineFunctionPass { MachineFunction* mf_; @@ -64,33 +51,15 @@ const TargetInstrInfo* tii_; AliasAnalysis *aa_; LiveVariables* lv_; + SlotIndexes* indexes_; /// Special pool allocator for VNInfo's (LiveInterval val#). /// BumpPtrAllocator VNInfoAllocator; - /// MBB2IdxMap - The indexes of the first and last instructions in the - /// specified basic block. - std::vector > MBB2IdxMap; - - /// Idx2MBBMap - Sorted list of pairs of index of first instruction - /// and MBB id. - std::vector Idx2MBBMap; - - /// FunctionSize - The number of instructions present in the function - uint64_t FunctionSize; - - typedef DenseMap Mi2IndexMap; - Mi2IndexMap mi2iMap_; - - typedef std::vector Index2MiMap; - Index2MiMap i2miMap_; - typedef DenseMap Reg2IntervalMap; Reg2IntervalMap r2iMap_; - DenseMap terminatorGaps; - /// phiJoinCopies - Copy instructions which are PHI joins. SmallVector phiJoinCopies; @@ -100,48 +69,10 @@ /// CloneMIs - A list of clones as result of re-materialization. std::vector CloneMIs; - typedef LiveInterval::InstrSlots InstrSlots; - public: static char ID; // Pass identification, replacement for typeid LiveIntervals() : MachineFunctionPass(&ID) {} - LiveIndex getBaseIndex(LiveIndex index) { - return LiveIndex(index, LiveIndex::LOAD); - } - LiveIndex getBoundaryIndex(LiveIndex index) { - return LiveIndex(index, - (LiveIndex::Slot)(LiveIndex::NUM - 1)); - } - LiveIndex getLoadIndex(LiveIndex index) { - return LiveIndex(index, LiveIndex::LOAD); - } - LiveIndex getUseIndex(LiveIndex index) { - return LiveIndex(index, LiveIndex::USE); - } - LiveIndex getDefIndex(LiveIndex index) { - return LiveIndex(index, LiveIndex::DEF); - } - LiveIndex getStoreIndex(LiveIndex index) { - return LiveIndex(index, LiveIndex::STORE); - } - - LiveIndex getNextSlot(LiveIndex m) const { - return m.nextSlot_(); - } - - LiveIndex getNextIndex(LiveIndex m) const { - return m.nextIndex_(); - } - - LiveIndex getPrevSlot(LiveIndex m) const { - return m.prevSlot_(); - } - - LiveIndex getPrevIndex(LiveIndex m) const { - return m.prevIndex_(); - } - static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth) { return (isDef + isUse) * powf(10.0F, (float)loopDepth); } @@ -170,111 +101,18 @@ return r2iMap_.count(reg); } - /// getMBBStartIdx - Return the base index of the first instruction in the - /// specified MachineBasicBlock. - LiveIndex getMBBStartIdx(MachineBasicBlock *MBB) const { - return getMBBStartIdx(MBB->getNumber()); - } - LiveIndex getMBBStartIdx(unsigned MBBNo) const { - assert(MBBNo < MBB2IdxMap.size() && "Invalid MBB number!"); - return MBB2IdxMap[MBBNo].first; - } - - /// getMBBEndIdx - Return the store index of the last instruction in the - /// specified MachineBasicBlock. - LiveIndex getMBBEndIdx(MachineBasicBlock *MBB) const { - return getMBBEndIdx(MBB->getNumber()); - } - LiveIndex getMBBEndIdx(unsigned MBBNo) const { - assert(MBBNo < MBB2IdxMap.size() && "Invalid MBB number!"); - return MBB2IdxMap[MBBNo].second; - } - /// getScaledIntervalSize - get the size of an interval in "units," /// where every function is composed of one thousand units. This /// measure scales properly with empty index slots in the function. double getScaledIntervalSize(LiveInterval& I) { - return (1000.0 / InstrSlots::NUM * I.getSize()) / i2miMap_.size(); + return (1000.0 * I.getSize()) / indexes_->getIndexesLength(); } /// getApproximateInstructionCount - computes an estimate of the number /// of instructions in a given LiveInterval. unsigned getApproximateInstructionCount(LiveInterval& I) { double IntervalPercentage = getScaledIntervalSize(I) / 1000.0; - return (unsigned)(IntervalPercentage * FunctionSize); - } - - /// getMBBFromIndex - given an index in any instruction of an - /// MBB return a pointer the MBB - MachineBasicBlock* getMBBFromIndex(LiveIndex index) const { - std::vector::const_iterator I = - std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), index); - // Take the pair containing the index - std::vector::const_iterator J = - ((I != Idx2MBBMap.end() && I->first > index) || - (I == Idx2MBBMap.end() && Idx2MBBMap.size()>0)) ? (I-1): I; - - assert(J != Idx2MBBMap.end() && J->first <= index && - index <= getMBBEndIdx(J->second) && - "index does not correspond to an MBB"); - return J->second; - } - - /// getInstructionIndex - returns the base index of instr - LiveIndex getInstructionIndex(const MachineInstr* instr) const { - Mi2IndexMap::const_iterator it = mi2iMap_.find(instr); - assert(it != mi2iMap_.end() && "Invalid instruction!"); - return it->second; - } - - /// getInstructionFromIndex - given an index in any slot of an - /// instruction return a pointer the instruction - MachineInstr* getInstructionFromIndex(LiveIndex index) const { - // convert index to vector index - unsigned i = index.getVecIndex(); - assert(i < i2miMap_.size() && - "index does not correspond to an instruction"); - return i2miMap_[i]; - } - - /// hasGapBeforeInstr - Return true if the previous instruction slot, - /// i.e. Index - InstrSlots::NUM, is not occupied. - bool hasGapBeforeInstr(LiveIndex Index) { - Index = getBaseIndex(getPrevIndex(Index)); - return getInstructionFromIndex(Index) == 0; - } - - /// hasGapAfterInstr - Return true if the successive instruction slot, - /// i.e. Index + InstrSlots::Num, is not occupied. - bool hasGapAfterInstr(LiveIndex Index) { - Index = getBaseIndex(getNextIndex(Index)); - return getInstructionFromIndex(Index) == 0; - } - - /// findGapBeforeInstr - Find an empty instruction slot before the - /// specified index. If "Furthest" is true, find one that's furthest - /// away from the index (but before any index that's occupied). - LiveIndex findGapBeforeInstr(LiveIndex Index, bool Furthest = false) { - Index = getBaseIndex(getPrevIndex(Index)); - if (getInstructionFromIndex(Index)) - return LiveIndex(); // No gap! - if (!Furthest) - return Index; - LiveIndex PrevIndex = getBaseIndex(getPrevIndex(Index)); - while (getInstructionFromIndex(Index)) { - Index = PrevIndex; - PrevIndex = getBaseIndex(getPrevIndex(Index)); - } - return Index; - } - - /// InsertMachineInstrInMaps - Insert the specified machine instruction - /// into the instruction index map at the given index. - void InsertMachineInstrInMaps(MachineInstr *MI, LiveIndex Index) { - i2miMap_[Index.getVecIndex()] = MI; - Mi2IndexMap::iterator it = mi2iMap_.find(MI); - assert(it == mi2iMap_.end() && "Already in map!"); - mi2iMap_[MI] = Index; + return (unsigned)(IntervalPercentage * indexes_->getFunctionSize()); } /// conflictsWithPhysRegDef - Returns true if the specified register @@ -288,19 +126,7 @@ bool CheckUse, SmallPtrSet &JoinedCopies); - /// findLiveInMBBs - Given a live range, if the value of the range - /// is live in any MBB returns true as well as the list of basic blocks - /// in which the value is live. - bool findLiveInMBBs(LiveIndex Start, LiveIndex End, - SmallVectorImpl &MBBs) const; - - /// findReachableMBBs - Return a list MBB that can be reached via any - /// branch or fallthroughs. Return true if the list is not empty. - bool findReachableMBBs(LiveIndex Start, LiveIndex End, - SmallVectorImpl &MBBs) const; - // Interval creation - LiveInterval &getOrCreateInterval(unsigned reg) { Reg2IntervalMap::iterator I = r2iMap_.find(reg); if (I == r2iMap_.end()) @@ -325,36 +151,75 @@ r2iMap_.erase(I); } + SlotIndex getZeroIndex() const { + return indexes_->getZeroIndex(); + } + + SlotIndex getInvalidIndex() const { + return indexes_->getInvalidIndex(); + } + /// isNotInMIMap - returns true if the specified machine instr has been /// removed or was never entered in the map. - bool isNotInMIMap(MachineInstr* instr) const { - return !mi2iMap_.count(instr); + bool isNotInMIMap(const MachineInstr* Instr) const { + return !indexes_->hasIndex(Instr); + } + + /// Returns the base index of the given instruction. + SlotIndex getInstructionIndex(const MachineInstr *instr) const { + return indexes_->getInstructionIndex(instr); + } + + /// Returns the instruction associated with the given index. + MachineInstr* getInstructionFromIndex(SlotIndex index) const { + return indexes_->getInstructionFromIndex(index); + } + + /// Return the first index in the given basic block. + SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const { + return indexes_->getMBBStartIdx(mbb); + } + + /// Return the last index in the given basic block. + SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const { + return indexes_->getMBBEndIdx(mbb); + } + + MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { + return indexes_->getMBBFromIndex(index); + } + + bool hasGapBeforeInstr(SlotIndex index) { + return indexes_->hasGapBeforeInstr(index); + } + + bool hasGapAfterInstr(SlotIndex index) { + return indexes_->hasGapAfterInstr(index); + } + + SlotIndex findGapBeforeInstr(SlotIndex index, bool furthest = false) { + return indexes_->findGapBeforeInstr(index, furthest); + } + + void InsertMachineInstrInMaps(MachineInstr *MI, SlotIndex Index) { + indexes_->insertMachineInstrInMaps(MI, Index); } - /// RemoveMachineInstrFromMaps - This marks the specified machine instr as - /// deleted. void RemoveMachineInstrFromMaps(MachineInstr *MI) { - // remove index -> MachineInstr and - // MachineInstr -> index mappings - Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI); - if (mi2i != mi2iMap_.end()) { - i2miMap_[mi2i->second.index/InstrSlots::NUM] = 0; - mi2iMap_.erase(mi2i); - } + indexes_->removeMachineInstrFromMaps(MI); } - /// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in - /// maps used by register allocator. void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) { - Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI); - if (mi2i == mi2iMap_.end()) - return; - i2miMap_[mi2i->second.index/InstrSlots::NUM] = NewMI; - Mi2IndexMap::iterator it = mi2iMap_.find(MI); - assert(it != mi2iMap_.end() && "Invalid instruction!"); - LiveIndex Index = it->second; - mi2iMap_.erase(it); - mi2iMap_[NewMI] = Index; + indexes_->replaceMachineInstrInMaps(MI, NewMI); + } + + bool findLiveInMBBs(SlotIndex Start, SlotIndex End, + SmallVectorImpl &MBBs) const { + return indexes_->findLiveInMBBs(Start, End, MBBs); + } + + void renumber() { + indexes_->renumber(); } BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; } @@ -417,13 +282,6 @@ /// marker to implicit_def defs and their uses. void processImplicitDefs(); - /// computeNumbering - Compute the index numbering. - void computeNumbering(); - - /// scaleNumbering - Rescale interval numbers to introduce gaps for new - /// instructions - void scaleNumbering(int factor); - /// intervalIsInOneMBB - Returns true if the specified interval is entirely /// within a single basic block. bool intervalIsInOneMBB(const LiveInterval &li) const; @@ -443,14 +301,14 @@ /// handleVirtualRegisterDef) void handleRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator MI, - LiveIndex MIIdx, + SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx); /// handleVirtualRegisterDef - update intervals for a virtual /// register def void handleVirtualRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator MI, - LiveIndex MIIdx, MachineOperand& MO, + SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx, LiveInterval& interval); @@ -458,13 +316,13 @@ /// def. void handlePhysicalRegisterDef(MachineBasicBlock* mbb, MachineBasicBlock::iterator mi, - LiveIndex MIIdx, MachineOperand& MO, + SlotIndex MIIdx, MachineOperand& MO, LiveInterval &interval, MachineInstr *CopyMI); /// handleLiveInRegister - Create interval for a livein register. void handleLiveInRegister(MachineBasicBlock* mbb, - LiveIndex MIIdx, + SlotIndex MIIdx, LiveInterval &interval, bool isAlias = false); /// getReMatImplicitUse - If the remat definition MI has one (for now, we @@ -477,7 +335,7 @@ /// which reaches the given instruction also reaches the specified use /// index. bool isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI, - LiveIndex UseIdx) const; + SlotIndex UseIdx) const; /// isReMaterializable - Returns true if the definition MI of the specified /// val# of the specified interval is re-materializable. Also returns true @@ -492,7 +350,7 @@ /// MI. If it is successul, MI is updated with the newly created MI and /// returns true. bool tryFoldMemoryOperand(MachineInstr* &MI, VirtRegMap &vrm, - MachineInstr *DefMI, LiveIndex InstrIdx, + MachineInstr *DefMI, SlotIndex InstrIdx, SmallVector &Ops, bool isSS, int FrameIndex, unsigned Reg); @@ -506,7 +364,7 @@ /// VNInfo that's after the specified index but is within the basic block. bool anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI, MachineBasicBlock *MBB, - LiveIndex Idx) const; + SlotIndex Idx) const; /// hasAllocatableSuperReg - Return true if the specified physical register /// has any super register that's allocatable. @@ -514,17 +372,17 @@ /// SRInfo - Spill / restore info. struct SRInfo { - LiveIndex index; + SlotIndex index; unsigned vreg; bool canFold; - SRInfo(LiveIndex i, unsigned vr, bool f) + SRInfo(SlotIndex i, unsigned vr, bool f) : index(i), vreg(vr), canFold(f) {} }; - bool alsoFoldARestore(int Id, LiveIndex index, unsigned vr, + bool alsoFoldARestore(int Id, SlotIndex index, unsigned vr, BitVector &RestoreMBBs, DenseMap >&RestoreIdxes); - void eraseRestoreInfo(int Id, LiveIndex index, unsigned vr, + void eraseRestoreInfo(int Id, SlotIndex index, unsigned vr, BitVector &RestoreMBBs, DenseMap >&RestoreIdxes); @@ -543,7 +401,7 @@ /// functions for addIntervalsForSpills to rewrite uses / defs for the given /// live range. bool rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, - bool TrySplit, LiveIndex index, LiveIndex end, + bool TrySplit, SlotIndex index, SlotIndex end, MachineInstr *MI, MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot, bool isLoad, bool isLoadSS, bool DefIsReMat, bool CanDelete, Modified: llvm/trunk/include/llvm/CodeGen/LiveStackAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveStackAnalysis.h?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveStackAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveStackAnalysis.h Tue Nov 3 17:52:08 2009 @@ -48,8 +48,6 @@ iterator begin() { return S2IMap.begin(); } iterator end() { return S2IMap.end(); } - void scaleNumbering(int factor); - unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); } LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC) { Added: llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h?rev=85979&view=auto ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h (added) +++ llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h Tue Nov 3 17:52:08 2009 @@ -0,0 +1,41 @@ +//===-------------- llvm/CodeGen/ProcessImplicitDefs.h ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_CODEGEN_PROCESSIMPLICITDEFS_H +#define LLVM_CODEGEN_PROCESSIMPLICITDEFS_H + +#include "llvm/CodeGen/MachineFunctionPass.h" + +namespace llvm { + + class MachineInstr; + class TargetInstrInfo; + + /// Process IMPLICIT_DEF instructions and make sure there is one implicit_def + /// for each use. Add isUndef marker to implicit_def defs and their uses. + class ProcessImplicitDefs : public MachineFunctionPass { + private: + + bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, + unsigned OpIdx, const TargetInstrInfo *tii_); + + public: + static char ID; + + ProcessImplicitDefs() : MachineFunctionPass(&ID) {} + + virtual void getAnalysisUsage(AnalysisUsage &au) const; + + virtual bool runOnMachineFunction(MachineFunction &fn); + }; + +} + +#endif // LLVM_CODEGEN_PROCESSIMPLICITDEFS_H Added: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SlotIndexes.h?rev=85979&view=auto ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h (added) +++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Tue Nov 3 17:52:08 2009 @@ -0,0 +1,775 @@ +//===- llvm/CodeGen/SlotIndexes.h - Slot indexes representation -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements SlotIndex and related classes. The purpuse of SlotIndex +// is to describe a position at which a register can become live, or cease to +// be live. +// +// SlotIndex is mostly a proxy for entries of the SlotIndexList, a class which +// is held is LiveIntervals and provides the real numbering. This allows +// LiveIntervals to perform largely transparent renumbering. The SlotIndex +// class does hold a PHI bit, which determines whether the index relates to a +// PHI use or def point, or an actual instruction. See the SlotIndex class +// description for futher information. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_SLOTINDEXES_H +#define LLVM_CODEGEN_SLOTINDEXES_H + +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Support/Allocator.h" + +namespace llvm { + + /// This class represents an entry in the slot index list held in the + /// SlotIndexes pass. It should not be used directly. See the + /// SlotIndex & SlotIndexes classes for the public interface to this + /// information. + class IndexListEntry { + friend class SlotIndex; + friend class SlotIndexes; + + private: + + IndexListEntry *next, *prev; + MachineInstr *mi; + unsigned index; + + public: + + IndexListEntry(MachineInstr *mi, unsigned index) + : mi(mi), index(index) {} + + MachineInstr* getInstr() const { return mi; } + void setInstr(MachineInstr *mi) { this->mi = mi; } + + unsigned getIndex() const { return index; } + void setIndex(unsigned index) { this->index = index; } + + IndexListEntry* getNext() { return next; } + const IndexListEntry* getNext() const { return next; } + void setNext(IndexListEntry *next) { this->next = next; } + + IndexListEntry* getPrev() { return prev; } + const IndexListEntry* getPrev() const { return prev; } + void setPrev(IndexListEntry *prev) { this->prev = prev; } + + /* + bool operator==(const IndexListEntry &other) const { + assert(getIndex() != other.getIndex() || this == &other && + "Non-equal index list entries compare equal."); + return getIndex() == other.getIndex(); + } + + bool operator!=(const IndexListEntry &other) const { + return getIndex() != other.getIndex(); + } + + bool operator<(const IndexListEntry &other) const { + return getIndex() < other.getIndex(); + } + + bool operator<=(const IndexListEntry &other) const { + return getIndex() <= other.getIndex(); + } + + bool operator>(const IndexListEntry &other) const { + return getIndex() > other.getIndex(); + } + + bool operator>=(const IndexListEntry &other) const { + return getIndex() >= other.getIndex(); + } + + int distance(const IndexListEntry &other) const { + return other.getIndex() - getIndex(); + } + */ + }; + + // Specialize PointerLikeTypeTraits for IndexListEntry. + template <> + class PointerLikeTypeTraits { + public: + static inline void* getAsVoidPointer(IndexListEntry *p) { + return p; + } + static inline IndexListEntry* getFromVoidPointer(void *p) { + return static_cast(p); + } + enum { NumLowBitsAvailable = 3 }; + }; + + /// SlotIndex - An opaque wrapper around machine indexes. + class SlotIndex { + friend class SlotIndexes; + friend class DenseMapInfo; + + private: + + // FIXME: Is there any way to statically allocate these things and have + // them 8-byte aligned? + static std::auto_ptr emptyKeyPtr, tombstoneKeyPtr; + static const unsigned PHI_BIT = 1 << 2; + + PointerIntPair lie; + + SlotIndex(IndexListEntry *entry, unsigned phiAndSlot) + : lie(entry, phiAndSlot) { + assert(entry != 0 && "Attempt to construct index with 0 pointer."); + } + + IndexListEntry& entry() const { + assert(lie.getPointer() != 0 && "Use of invalid index."); + return *lie.getPointer(); + } + + int getIndex() const { + return entry().getIndex() | getSlot(); + } + + static inline unsigned getHashValue(const SlotIndex &v) { + IndexListEntry *ptrVal = &v.entry(); + return (unsigned((intptr_t)ptrVal) >> 4) ^ + (unsigned((intptr_t)ptrVal) >> 9); + } + + public: + + // FIXME: Ugh. This is public because LiveIntervalAnalysis is still using it + // for some spill weight stuff. Fix that, then make this private. + enum Slot { LOAD, USE, DEF, STORE, NUM }; + + static inline SlotIndex getEmptyKey() { + // FIXME: How do we guarantee these numbers don't get allocated to + // legit indexes? + if (emptyKeyPtr.get() == 0) + emptyKeyPtr.reset(new IndexListEntry(0, ~0U & ~3U)); + + return SlotIndex(emptyKeyPtr.get(), 0); + } + + static inline SlotIndex getTombstoneKey() { + // FIXME: How do we guarantee these numbers don't get allocated to + // legit indexes? + if (tombstoneKeyPtr.get() == 0) + tombstoneKeyPtr.reset(new IndexListEntry(0, ~0U & ~7U)); + + return SlotIndex(tombstoneKeyPtr.get(), 0); + } + + /// Construct an invalid index. + SlotIndex() : lie(&getEmptyKey().entry(), 0) {} + + // Construct a new slot index from the given one, set the phi flag on the + // new index to the value of the phi parameter. + SlotIndex(const SlotIndex &li, bool phi) + : lie(&li.entry(), phi ? PHI_BIT & li.getSlot() : (unsigned)li.getSlot()){ + assert(lie.getPointer() != 0 && + "Attempt to construct index with 0 pointer."); + } + + // Construct a new slot index from the given one, set the phi flag on the + // new index to the value of the phi parameter, and the slot to the new slot. + SlotIndex(const SlotIndex &li, bool phi, Slot s) + : lie(&li.entry(), phi ? PHI_BIT & s : (unsigned)s) { + assert(lie.getPointer() != 0 && + "Attempt to construct index with 0 pointer."); + } + + /// Returns true if this is a valid index. Invalid indicies do + /// not point into an index table, and cannot be compared. + bool isValid() const { + return (lie.getPointer() != 0) && (lie.getPointer()->getIndex() != 0); + } + + /// Print this index to the given raw_ostream. + void print(raw_ostream &os) const; + + /// Dump this index to stderr. + void dump() const; + + /// Compare two SlotIndex objects for equality. + bool operator==(SlotIndex other) const { + return getIndex() == other.getIndex(); + } + /// Compare two SlotIndex objects for inequality. + bool operator!=(SlotIndex other) const { + return getIndex() != other.getIndex(); + } + + /// Compare two SlotIndex objects. Return true if the first index + /// is strictly lower than the second. + bool operator<(SlotIndex other) const { + return getIndex() < other.getIndex(); + } + /// Compare two SlotIndex objects. Return true if the first index + /// is lower than, or equal to, the second. + bool operator<=(SlotIndex other) const { + return getIndex() <= other.getIndex(); + } + + /// Compare two SlotIndex objects. Return true if the first index + /// is greater than the second. + bool operator>(SlotIndex other) const { + return getIndex() > other.getIndex(); + } + + /// Compare two SlotIndex objects. Return true if the first index + /// is greater than, or equal to, the second. + bool operator>=(SlotIndex other) const { + return getIndex() >= other.getIndex(); + } + + /// Return the distance from this index to the given one. + int distance(SlotIndex other) const { + return other.getIndex() - getIndex(); + } + + /// Returns the slot for this SlotIndex. + Slot getSlot() const { + return static_cast(lie.getInt() & ~PHI_BIT); + } + + /// Returns the state of the PHI bit. + bool isPHI() const { + return lie.getInt() & PHI_BIT; + } + + /// Returns the base index for associated with this index. The base index + /// is the one associated with the LOAD slot for the instruction pointed to + /// by this index. + SlotIndex getBaseIndex() const { + return getLoadIndex(); + } + + /// Returns the boundary index for associated with this index. The boundary + /// index is the one associated with the LOAD slot for the instruction + /// pointed to by this index. + SlotIndex getBoundaryIndex() const { + return getStoreIndex(); + } + + /// Returns the index of the LOAD slot for the instruction pointed to by + /// this index. + SlotIndex getLoadIndex() const { + return SlotIndex(&entry(), SlotIndex::LOAD); + } + + /// Returns the index of the USE slot for the instruction pointed to by + /// this index. + SlotIndex getUseIndex() const { + return SlotIndex(&entry(), SlotIndex::USE); + } + + /// Returns the index of the DEF slot for the instruction pointed to by + /// this index. + SlotIndex getDefIndex() const { + return SlotIndex(&entry(), SlotIndex::DEF); + } + + /// Returns the index of the STORE slot for the instruction pointed to by + /// this index. + SlotIndex getStoreIndex() const { + return SlotIndex(&entry(), SlotIndex::STORE); + } + + /// Returns the next slot in the index list. This could be either the + /// next slot for the instruction pointed to by this index or, if this + /// index is a STORE, the first slot for the next instruction. + /// WARNING: This method is considerably more expensive than the methods + /// that return specific slots (getUseIndex(), etc). If you can - please + /// use one of those methods. + SlotIndex getNextSlot() const { + Slot s = getSlot(); + if (s == SlotIndex::STORE) { + return SlotIndex(entry().getNext(), SlotIndex::LOAD); + } + return SlotIndex(&entry(), s + 1); + } + + /// Returns the next index. This is the index corresponding to the this + /// index's slot, but for the next instruction. + SlotIndex getNextIndex() const { + return SlotIndex(entry().getNext(), getSlot()); + } + + /// Returns the previous slot in the index list. This could be either the + /// previous slot for the instruction pointed to by this index or, if this + /// index is a LOAD, the last slot for the previous instruction. + /// WARNING: This method is considerably more expensive than the methods + /// that return specific slots (getUseIndex(), etc). If you can - please + /// use one of those methods. + SlotIndex getPrevSlot() const { + Slot s = getSlot(); + if (s == SlotIndex::LOAD) { + return SlotIndex(entry().getPrev(), SlotIndex::STORE); + } + return SlotIndex(&entry(), s - 1); + } + + /// Returns the previous index. This is the index corresponding to this + /// index's slot, but for the previous instruction. + SlotIndex getPrevIndex() const { + return SlotIndex(entry().getPrev(), getSlot()); + } + + }; + + /// DenseMapInfo specialization for SlotIndex. + template <> + struct DenseMapInfo { + static inline SlotIndex getEmptyKey() { + return SlotIndex::getEmptyKey(); + } + static inline SlotIndex getTombstoneKey() { + return SlotIndex::getTombstoneKey(); + } + static inline unsigned getHashValue(const SlotIndex &v) { + return SlotIndex::getHashValue(v); + } + static inline bool isEqual(const SlotIndex &LHS, const SlotIndex &RHS) { + return (LHS == RHS); + } + static inline bool isPod() { return false; } + }; + + inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) { + li.print(os); + return os; + } + + typedef std::pair IdxMBBPair; + + inline bool operator<(SlotIndex V, const IdxMBBPair &IM) { + return V < IM.first; + } + + inline bool operator<(const IdxMBBPair &IM, SlotIndex V) { + return IM.first < V; + } + + struct Idx2MBBCompare { + bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const { + return LHS.first < RHS.first; + } + }; + + /// SlotIndexes pass. + /// + /// This pass assigns indexes to each instruction. + class SlotIndexes : public MachineFunctionPass { + private: + + MachineFunction *mf; + IndexListEntry *indexListHead; + unsigned functionSize; + + typedef DenseMap Mi2IndexMap; + Mi2IndexMap mi2iMap; + + /// MBB2IdxMap - The indexes of the first and last instructions in the + /// specified basic block. + typedef DenseMap > MBB2IdxMap; + MBB2IdxMap mbb2IdxMap; + + /// Idx2MBBMap - Sorted list of pairs of index of first instruction + /// and MBB id. + std::vector idx2MBBMap; + + typedef DenseMap TerminatorGapsMap; + TerminatorGapsMap terminatorGaps; + + // IndexListEntry allocator. + BumpPtrAllocator ileAllocator; + + IndexListEntry* createEntry(MachineInstr *mi, unsigned index) { + IndexListEntry *entry = + static_cast( + ileAllocator.Allocate(sizeof(IndexListEntry), + alignof())); + + new (entry) IndexListEntry(mi, index); + + return entry; + } + + void initList() { + assert(indexListHead == 0 && "Zero entry non-null at initialisation."); + indexListHead = createEntry(0, ~0U); + indexListHead->setNext(0); + indexListHead->setPrev(indexListHead); + } + + void clearList() { + indexListHead = 0; + ileAllocator.Reset(); + } + + IndexListEntry* getTail() { + assert(indexListHead != 0 && "Call to getTail on uninitialized list."); + return indexListHead->getPrev(); + } + + const IndexListEntry* getTail() const { + assert(indexListHead != 0 && "Call to getTail on uninitialized list."); + return indexListHead->getPrev(); + } + + // Returns true if the index list is empty. + bool empty() const { return (indexListHead == getTail()); } + + IndexListEntry* front() { + assert(!empty() && "front() called on empty index list."); + return indexListHead; + } + + const IndexListEntry* front() const { + assert(!empty() && "front() called on empty index list."); + return indexListHead; + } + + IndexListEntry* back() { + assert(!empty() && "back() called on empty index list."); + return getTail()->getPrev(); + } + + const IndexListEntry* back() const { + assert(!empty() && "back() called on empty index list."); + return getTail()->getPrev(); + } + + /// Insert a new entry before itr. + void insert(IndexListEntry *itr, IndexListEntry *val) { + assert(itr != 0 && "itr should not be null."); + IndexListEntry *prev = itr->getPrev(); + val->setNext(itr); + val->setPrev(prev); + + if (itr != indexListHead) { + prev->setNext(val); + } + else { + indexListHead = val; + } + itr->setPrev(val); + } + + /// Push a new entry on to the end of the list. + void push_back(IndexListEntry *val) { + insert(getTail(), val); + } + + public: + static char ID; + + SlotIndexes() : MachineFunctionPass(&ID), indexListHead(0) {} + + virtual void getAnalysisUsage(AnalysisUsage &au) const; + virtual void releaseMemory(); + + virtual bool runOnMachineFunction(MachineFunction &fn); + + /// Dump the indexes. + void dump() const; + + /// Renumber the index list, providing space for new instructions. + void renumber(); + + /// Returns the zero index for this analysis. + SlotIndex getZeroIndex() { + assert(front()->getIndex() == 0 && "First index is not 0?"); + return SlotIndex(front(), 0); + } + + /// Returns the invalid index marker for this analysis. + SlotIndex getInvalidIndex() { + return getZeroIndex(); + } + + /// Returns the distance between the highest and lowest indexes allocated + /// so far. + unsigned getIndexesLength() const { + assert(front()->getIndex() == 0 && + "Initial index isn't zero?"); + + return back()->getIndex(); + } + + /// Returns the number of instructions in the function. + unsigned getFunctionSize() const { + return functionSize; + } + + /// Returns true if the given machine instr is mapped to an index, + /// otherwise returns false. + bool hasIndex(const MachineInstr *instr) const { + return (mi2iMap.find(instr) != mi2iMap.end()); + } + + /// Returns the base index for the given instruction. + SlotIndex getInstructionIndex(const MachineInstr *instr) const { + Mi2IndexMap::const_iterator itr = mi2iMap.find(instr); + assert(itr != mi2iMap.end() && "Instruction not found in maps."); + return itr->second; + } + + /// Returns the instruction for the given index, or null if the given + /// index has no instruction associated with it. + MachineInstr* getInstructionFromIndex(SlotIndex index) const { + return index.entry().getInstr(); + } + + /// Returns the next non-null index. + SlotIndex getNextNonNullIndex(SlotIndex index) { + SlotIndex nextNonNull = index.getNextIndex(); + + while (&nextNonNull.entry() != getTail() && + getInstructionFromIndex(nextNonNull) == 0) { + nextNonNull = nextNonNull.getNextIndex(); + } + + return nextNonNull; + } + + /// Returns the first index in the given basic block. + SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const { + MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb); + assert(itr != mbb2IdxMap.end() && "MBB not found in maps."); + return itr->second.first; + } + + /// Returns the last index in the given basic block. + SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const { + MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb); + assert(itr != mbb2IdxMap.end() && "MBB not found in maps."); + return itr->second.second; + } + + /// Returns the terminator gap for the given index. + SlotIndex getTerminatorGap(const MachineBasicBlock *mbb) { + TerminatorGapsMap::iterator itr = terminatorGaps.find(mbb); + assert(itr != terminatorGaps.end() && + "All MBBs should have terminator gaps in their indexes."); + return itr->second; + } + + /// Returns the basic block which the given index falls in. + MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { + std::vector::const_iterator I = + std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index); + // Take the pair containing the index + std::vector::const_iterator J = + ((I != idx2MBBMap.end() && I->first > index) || + (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I; + + assert(J != idx2MBBMap.end() && J->first <= index && + index <= getMBBEndIdx(J->second) && + "index does not correspond to an MBB"); + return J->second; + } + + bool findLiveInMBBs(SlotIndex start, SlotIndex end, + SmallVectorImpl &mbbs) const { + std::vector::const_iterator itr = + std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); + bool resVal = false; + + while (itr != idx2MBBMap.end()) { + if (itr->first >= end) + break; + mbbs.push_back(itr->second); + resVal = true; + ++itr; + } + return resVal; + } + + /// Return a list of MBBs that can be reach via any branches or + /// fall-throughs. + bool findReachableMBBs(SlotIndex start, SlotIndex end, + SmallVectorImpl &mbbs) const { + std::vector::const_iterator itr = + std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); + + bool resVal = false; + while (itr != idx2MBBMap.end()) { + if (itr->first > end) + break; + MachineBasicBlock *mbb = itr->second; + if (getMBBEndIdx(mbb) > end) + break; + for (MachineBasicBlock::succ_iterator si = mbb->succ_begin(), + se = mbb->succ_end(); si != se; ++si) + mbbs.push_back(*si); + resVal = true; + ++itr; + } + return resVal; + } + + /// Returns the MBB covering the given range, or null if the range covers + /// more than one basic block. + MachineBasicBlock* getMBBCoveringRange(SlotIndex start, SlotIndex end) const { + + assert(start < end && "Backwards ranges not allowed."); + + std::vector::const_iterator itr = + std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); + + if (itr == idx2MBBMap.end()) { + itr = prior(itr); + return itr->second; + } + + // Check that we don't cross the boundary into this block. + if (itr->first < end) + return 0; + + itr = prior(itr); + + if (itr->first <= start) + return itr->second; + + return 0; + } + + /// Returns true if there is a gap in the numbering before the given index. + bool hasGapBeforeInstr(SlotIndex index) { + index = index.getBaseIndex(); + SlotIndex prevIndex = index.getPrevIndex(); + + if (prevIndex == getZeroIndex()) + return false; + + if (getInstructionFromIndex(prevIndex) == 0) + return true; + + if (prevIndex.distance(index) >= 2 * SlotIndex::NUM) + return true; + + return false; + } + + /// Returns true if there is a gap in the numbering after the given index. + bool hasGapAfterInstr(SlotIndex index) const { + // Not implemented yet. + assert(false && + "SlotIndexes::hasGapAfterInstr(SlotIndex) not implemented yet."); + return false; + } + + /// findGapBeforeInstr - Find an empty instruction slot before the + /// specified index. If "Furthest" is true, find one that's furthest + /// away from the index (but before any index that's occupied). + // FIXME: This whole method should go away in future. It should + // always be possible to insert code between existing indices. + SlotIndex findGapBeforeInstr(SlotIndex index, bool furthest = false) { + if (index == getZeroIndex()) + return getInvalidIndex(); + + index = index.getBaseIndex(); + SlotIndex prevIndex = index.getPrevIndex(); + + if (prevIndex == getZeroIndex()) + return getInvalidIndex(); + + // Try to reuse existing index objects with null-instrs. + if (getInstructionFromIndex(prevIndex) == 0) { + if (furthest) { + while (getInstructionFromIndex(prevIndex) == 0 && + prevIndex != getZeroIndex()) { + prevIndex = prevIndex.getPrevIndex(); + } + + prevIndex = prevIndex.getNextIndex(); + } + + assert(getInstructionFromIndex(prevIndex) == 0 && "Index list is broken."); + + return prevIndex; + } + + int dist = prevIndex.distance(index); + + // Double check that the spacing between this instruction and + // the last is sane. + assert(dist >= SlotIndex::NUM && + "Distance between indexes too small."); + + // If there's no gap return an invalid index. + if (dist < 2*SlotIndex::NUM) { + return getInvalidIndex(); + } + + // Otherwise insert new index entries into the list using the + // gap in the numbering. + IndexListEntry *newEntry = + createEntry(0, prevIndex.entry().getIndex() + SlotIndex::NUM); + + insert(&index.entry(), newEntry); + + // And return a pointer to the entry at the start of the gap. + return index.getPrevIndex(); + } + + /// Insert the given machine instruction into the mapping at the given + /// index. + void insertMachineInstrInMaps(MachineInstr *mi, SlotIndex index) { + index = index.getBaseIndex(); + IndexListEntry *miEntry = &index.entry(); + assert(miEntry->getInstr() == 0 && "Index already in use."); + miEntry->setInstr(mi); + + assert(mi2iMap.find(mi) == mi2iMap.end() && + "MachineInstr already has an index."); + + mi2iMap.insert(std::make_pair(mi, index)); + } + + /// Remove the given machine instruction from the mapping. + void removeMachineInstrFromMaps(MachineInstr *mi) { + // remove index -> MachineInstr and + // MachineInstr -> index mappings + Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi); + if (mi2iItr != mi2iMap.end()) { + IndexListEntry *miEntry(&mi2iItr->second.entry()); + assert(miEntry->getInstr() == mi && "Instruction indexes broken."); + // FIXME: Eventually we want to actually delete these indexes. + miEntry->setInstr(0); + mi2iMap.erase(mi2iItr); + } + } + + /// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in + /// maps used by register allocator. + void replaceMachineInstrInMaps(MachineInstr *mi, MachineInstr *newMI) { + Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi); + if (mi2iItr == mi2iMap.end()) + return; + SlotIndex replaceBaseIndex = mi2iItr->second; + IndexListEntry *miEntry(&replaceBaseIndex.entry()); + assert(miEntry->getInstr() == mi && + "Mismatched instruction in index tables."); + miEntry->setInstr(newMI); + mi2iMap.erase(mi2iItr); + mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex)); + } + + }; + + +} + +#endif // LLVM_CODEGEN_LIVEINDEX_H Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveInterval.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveInterval.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveInterval.cpp Tue Nov 3 17:52:08 2009 @@ -19,6 +19,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" @@ -28,11 +29,6 @@ #include using namespace llvm; -// Print a LiveIndex to a raw_ostream. -void LiveIndex::print(raw_ostream &os) const { - os << (index & ~PHI_BIT); -} - // An example for liveAt(): // // this = [1,4), liveAt(0) will return false. The instruction defining this @@ -40,7 +36,7 @@ // variable it represents. This is because slot 1 is used (def slot) and spans // up to slot 3 (store slot). // -bool LiveInterval::liveAt(LiveIndex I) const { +bool LiveInterval::liveAt(SlotIndex I) const { Ranges::const_iterator r = std::upper_bound(ranges.begin(), ranges.end(), I); if (r == ranges.begin()) @@ -53,7 +49,7 @@ // liveBeforeAndAt - Check if the interval is live at the index and the index // just before it. If index is liveAt, check if it starts a new live range. // If it does, then check if the previous live range ends at index-1. -bool LiveInterval::liveBeforeAndAt(LiveIndex I) const { +bool LiveInterval::liveBeforeAndAt(SlotIndex I) const { Ranges::const_iterator r = std::upper_bound(ranges.begin(), ranges.end(), I); if (r == ranges.begin()) @@ -131,7 +127,7 @@ /// overlaps - Return true if the live interval overlaps a range specified /// by [Start, End). -bool LiveInterval::overlaps(LiveIndex Start, LiveIndex End) const { +bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const { assert(Start < End && "Invalid range"); const_iterator I = begin(); const_iterator E = end(); @@ -149,10 +145,10 @@ /// specified by I to end at the specified endpoint. To do this, we should /// merge and eliminate all ranges that this will overlap with. The iterator is /// not invalidated. -void LiveInterval::extendIntervalEndTo(Ranges::iterator I, LiveIndex NewEnd) { +void LiveInterval::extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd) { assert(I != ranges.end() && "Not a valid interval!"); VNInfo *ValNo = I->valno; - LiveIndex OldEnd = I->end; + SlotIndex OldEnd = I->end; // Search for the first interval that we can't merge with. Ranges::iterator MergeTo = next(I); @@ -167,7 +163,7 @@ ranges.erase(next(I), MergeTo); // Update kill info. - ValNo->removeKills(OldEnd, I->end.prevSlot_()); + ValNo->removeKills(OldEnd, I->end.getPrevSlot()); // If the newly formed range now touches the range after it and if they have // the same value number, merge the two ranges into one range. @@ -183,7 +179,7 @@ /// specified by I to start at the specified endpoint. To do this, we should /// merge and eliminate all ranges that this will overlap with. LiveInterval::Ranges::iterator -LiveInterval::extendIntervalStartTo(Ranges::iterator I, LiveIndex NewStart) { +LiveInterval::extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStart) { assert(I != ranges.end() && "Not a valid interval!"); VNInfo *ValNo = I->valno; @@ -216,7 +212,7 @@ LiveInterval::iterator LiveInterval::addRangeFrom(LiveRange LR, iterator From) { - LiveIndex Start = LR.start, End = LR.end; + SlotIndex Start = LR.start, End = LR.end; iterator it = std::upper_bound(From, ranges.end(), Start); // If the inserted interval starts in the middle or right at the end of @@ -268,7 +264,7 @@ /// isInOneLiveRange - Return true if the range specified is entirely in /// a single LiveRange of the live interval. -bool LiveInterval::isInOneLiveRange(LiveIndex Start, LiveIndex End) { +bool LiveInterval::isInOneLiveRange(SlotIndex Start, SlotIndex End) { Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); if (I == ranges.begin()) return false; @@ -279,7 +275,7 @@ /// removeRange - Remove the specified range from this interval. Note that /// the range must be in a single LiveRange in its entirety. -void LiveInterval::removeRange(LiveIndex Start, LiveIndex End, +void LiveInterval::removeRange(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo) { // Find the LiveRange containing this span. Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); @@ -331,7 +327,7 @@ } // Otherwise, we are splitting the LiveRange into two pieces. - LiveIndex OldEnd = I->end; + SlotIndex OldEnd = I->end; I->end = Start; // Trim the old interval. // Insert the new one. @@ -362,36 +358,11 @@ ValNo->setIsUnused(true); } } - -/// scaleNumbering - Renumber VNI and ranges to provide gaps for new -/// instructions. - -void LiveInterval::scaleNumbering(unsigned factor) { - // Scale ranges. - for (iterator RI = begin(), RE = end(); RI != RE; ++RI) { - RI->start = RI->start.scale(factor); - RI->end = RI->end.scale(factor); - } - - // Scale VNI info. - for (vni_iterator VNI = vni_begin(), VNIE = vni_end(); VNI != VNIE; ++VNI) { - VNInfo *vni = *VNI; - - if (vni->isDefAccurate()) - vni->def = vni->def.scale(factor); - - for (unsigned i = 0; i < vni->kills.size(); ++i) { - if (!vni->kills[i].isPHIIndex()) - vni->kills[i] = vni->kills[i].scale(factor); - } - } -} - /// getLiveRangeContaining - Return the live range that contains the /// specified index, or null if there is none. LiveInterval::const_iterator -LiveInterval::FindLiveRangeContaining(LiveIndex Idx) const { +LiveInterval::FindLiveRangeContaining(SlotIndex Idx) const { const_iterator It = std::upper_bound(begin(), end(), Idx); if (It != ranges.begin()) { --It; @@ -403,7 +374,7 @@ } LiveInterval::iterator -LiveInterval::FindLiveRangeContaining(LiveIndex Idx) { +LiveInterval::FindLiveRangeContaining(SlotIndex Idx) { iterator It = std::upper_bound(begin(), end(), Idx); if (It != begin()) { --It; @@ -416,7 +387,7 @@ /// findDefinedVNInfo - Find the VNInfo defined by the specified /// index (register interval). -VNInfo *LiveInterval::findDefinedVNInfoForRegInt(LiveIndex Idx) const { +VNInfo *LiveInterval::findDefinedVNInfoForRegInt(SlotIndex Idx) const { for (LiveInterval::const_vni_iterator i = vni_begin(), e = vni_end(); i != e; ++i) { if ((*i)->def == Idx) @@ -440,7 +411,8 @@ /// join - Join two live intervals (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS intervals as specified. If /// the intervals are not joinable, this aborts. -void LiveInterval::join(LiveInterval &Other, const int *LHSValNoAssignments, +void LiveInterval::join(LiveInterval &Other, + const int *LHSValNoAssignments, const int *RHSValNoAssignments, SmallVector &NewVNInfo, MachineRegisterInfo *MRI) { @@ -554,14 +526,15 @@ /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the /// current interval, it will replace the value numbers of the overlaped /// live ranges with the specified value number. -void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS, - const VNInfo *RHSValNo, VNInfo *LHSValNo) { +void LiveInterval::MergeValueInAsValue( + const LiveInterval &RHS, + const VNInfo *RHSValNo, VNInfo *LHSValNo) { SmallVector ReplacedValNos; iterator IP = begin(); for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { if (I->valno != RHSValNo) continue; - LiveIndex Start = I->start, End = I->end; + SlotIndex Start = I->start, End = I->end; IP = std::upper_bound(IP, end(), Start); // If the start of this range overlaps with an existing liverange, trim it. if (IP != begin() && IP[-1].end > Start) { @@ -621,7 +594,8 @@ /// MergeInClobberRanges - For any live ranges that are not defined in the /// current interval, but are defined in the Clobbers interval, mark them /// used with an unknown definition value. -void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, +void LiveInterval::MergeInClobberRanges(LiveIntervals &li_, + const LiveInterval &Clobbers, BumpPtrAllocator &VNInfoAllocator) { if (Clobbers.empty()) return; @@ -638,20 +612,20 @@ ClobberValNo = UnusedValNo; else { UnusedValNo = ClobberValNo = - getNextValue(LiveIndex(), 0, false, VNInfoAllocator); + getNextValue(li_.getInvalidIndex(), 0, false, VNInfoAllocator); ValNoMaps.insert(std::make_pair(I->valno, ClobberValNo)); } bool Done = false; - LiveIndex Start = I->start, End = I->end; + SlotIndex Start = I->start, End = I->end; // If a clobber range starts before an existing range and ends after // it, the clobber range will need to be split into multiple ranges. // Loop until the entire clobber range is handled. while (!Done) { Done = true; IP = std::upper_bound(IP, end(), Start); - LiveIndex SubRangeStart = Start; - LiveIndex SubRangeEnd = End; + SlotIndex SubRangeStart = Start; + SlotIndex SubRangeEnd = End; // If the start of this range overlaps with an existing liverange, trim it. if (IP != begin() && IP[-1].end > SubRangeStart) { @@ -687,13 +661,14 @@ } } -void LiveInterval::MergeInClobberRange(LiveIndex Start, - LiveIndex End, +void LiveInterval::MergeInClobberRange(LiveIntervals &li_, + SlotIndex Start, + SlotIndex End, BumpPtrAllocator &VNInfoAllocator) { // Find a value # to use for the clobber ranges. If there is already a value# // for unknown values, use it. VNInfo *ClobberValNo = - getNextValue(LiveIndex(), 0, false, VNInfoAllocator); + getNextValue(li_.getInvalidIndex(), 0, false, VNInfoAllocator); iterator IP = begin(); IP = std::upper_bound(IP, end(), Start); @@ -881,8 +856,6 @@ OS << "-("; for (unsigned j = 0; j != ee; ++j) { OS << vni->kills[j]; - if (vni->kills[j].isPHIIndex()) - OS << "*"; if (j != ee-1) OS << " "; } Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Tue Nov 3 17:52:08 2009 @@ -28,6 +28,7 @@ #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/ProcessImplicitDefs.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -80,6 +81,10 @@ } AU.addRequiredID(TwoAddressInstructionPassID); + AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + AU.addRequiredTransitive(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -89,12 +94,7 @@ E = r2iMap_.end(); I != E; ++I) delete I->second; - MBB2IdxMap.clear(); - Idx2MBBMap.clear(); - mi2iMap_.clear(); - i2miMap_.clear(); r2iMap_.clear(); - terminatorGaps.clear(); phiJoinCopies.clear(); // Release VNInfo memroy regions after all VNInfo objects are dtor'd. @@ -106,422 +106,6 @@ } } -static bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, - unsigned OpIdx, const TargetInstrInfo *tii_){ - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg) - return true; - - if (OpIdx == 2 && MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) - return true; - if (OpIdx == 1 && MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) - return true; - return false; -} - -/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure -/// there is one implicit_def for each use. Add isUndef marker to -/// implicit_def defs and their uses. -void LiveIntervals::processImplicitDefs() { - SmallSet ImpDefRegs; - SmallVector ImpDefMIs; - MachineBasicBlock *Entry = mf_->begin(); - SmallPtrSet Visited; - for (df_ext_iterator > - DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); - DFI != E; ++DFI) { - MachineBasicBlock *MBB = *DFI; - for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); - I != E; ) { - MachineInstr *MI = &*I; - ++I; - if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) { - unsigned Reg = MI->getOperand(0).getReg(); - ImpDefRegs.insert(Reg); - if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS) - ImpDefRegs.insert(*SS); - } - ImpDefMIs.push_back(MI); - continue; - } - - if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { - MachineOperand &MO = MI->getOperand(2); - if (ImpDefRegs.count(MO.getReg())) { - // %reg1032 = INSERT_SUBREG %reg1032, undef, 2 - // This is an identity copy, eliminate it now. - if (MO.isKill()) { - LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); - vi.removeKill(MI); - } - MI->eraseFromParent(); - continue; - } - } - - bool ChangedToImpDef = false; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand& MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isUse() || MO.isUndef()) - continue; - unsigned Reg = MO.getReg(); - if (!Reg) - continue; - if (!ImpDefRegs.count(Reg)) - continue; - // Use is a copy, just turn it into an implicit_def. - if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) { - bool isKill = MO.isKill(); - MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); - for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) - MI->RemoveOperand(j); - if (isKill) { - ImpDefRegs.erase(Reg); - LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); - vi.removeKill(MI); - } - ChangedToImpDef = true; - break; - } - - MO.setIsUndef(); - if (MO.isKill() || MI->isRegTiedToDefOperand(i)) { - // Make sure other uses of - for (unsigned j = i+1; j != e; ++j) { - MachineOperand &MOJ = MI->getOperand(j); - if (MOJ.isReg() && MOJ.isUse() && MOJ.getReg() == Reg) - MOJ.setIsUndef(); - } - ImpDefRegs.erase(Reg); - } - } - - if (ChangedToImpDef) { - // Backtrack to process this new implicit_def. - --I; - } else { - for (unsigned i = 0; i != MI->getNumOperands(); ++i) { - MachineOperand& MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isDef()) - continue; - ImpDefRegs.erase(MO.getReg()); - } - } - } - - // Any outstanding liveout implicit_def's? - for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) { - MachineInstr *MI = ImpDefMIs[i]; - unsigned Reg = MI->getOperand(0).getReg(); - if (TargetRegisterInfo::isPhysicalRegister(Reg) || - !ImpDefRegs.count(Reg)) { - // Delete all "local" implicit_def's. That include those which define - // physical registers since they cannot be liveout. - MI->eraseFromParent(); - continue; - } - - // If there are multiple defs of the same register and at least one - // is not an implicit_def, do not insert implicit_def's before the - // uses. - bool Skip = false; - for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg), - DE = mri_->def_end(); DI != DE; ++DI) { - if (DI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) { - Skip = true; - break; - } - } - if (Skip) - continue; - - // The only implicit_def which we want to keep are those that are live - // out of its block. - MI->eraseFromParent(); - - for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), - UE = mri_->use_end(); UI != UE; ) { - MachineOperand &RMO = UI.getOperand(); - MachineInstr *RMI = &*UI; - ++UI; - MachineBasicBlock *RMBB = RMI->getParent(); - if (RMBB == MBB) - continue; - - // Turn a copy use into an implicit_def. - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg) { - RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); - for (int j = RMI->getNumOperands() - 1, ee = 0; j > ee; --j) - RMI->RemoveOperand(j); - continue; - } - - const TargetRegisterClass* RC = mri_->getRegClass(Reg); - unsigned NewVReg = mri_->createVirtualRegister(RC); - RMO.setReg(NewVReg); - RMO.setIsUndef(); - RMO.setIsKill(); - } - } - ImpDefRegs.clear(); - ImpDefMIs.clear(); - } -} - - -void LiveIntervals::computeNumbering() { - Index2MiMap OldI2MI = i2miMap_; - std::vector OldI2MBB = Idx2MBBMap; - - Idx2MBBMap.clear(); - MBB2IdxMap.clear(); - mi2iMap_.clear(); - i2miMap_.clear(); - terminatorGaps.clear(); - phiJoinCopies.clear(); - - FunctionSize = 0; - - // Number MachineInstrs and MachineBasicBlocks. - // Initialize MBB indexes to a sentinal. - MBB2IdxMap.resize(mf_->getNumBlockIDs(), - std::make_pair(LiveIndex(),LiveIndex())); - - LiveIndex MIIndex; - for (MachineFunction::iterator MBB = mf_->begin(), E = mf_->end(); - MBB != E; ++MBB) { - LiveIndex StartIdx = MIIndex; - - // Insert an empty slot at the beginning of each block. - MIIndex = getNextIndex(MIIndex); - i2miMap_.push_back(0); - - for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); - I != E; ++I) { - - if (I == MBB->getFirstTerminator()) { - // Leave a gap for before terminators, this is where we will point - // PHI kills. - LiveIndex tGap(true, MIIndex); - bool inserted = - terminatorGaps.insert(std::make_pair(&*MBB, tGap)).second; - assert(inserted && - "Multiple 'first' terminators encountered during numbering."); - inserted = inserted; // Avoid compiler warning if assertions turned off. - i2miMap_.push_back(0); - - MIIndex = getNextIndex(MIIndex); - } - - bool inserted = mi2iMap_.insert(std::make_pair(I, MIIndex)).second; - assert(inserted && "multiple MachineInstr -> index mappings"); - inserted = true; - i2miMap_.push_back(I); - MIIndex = getNextIndex(MIIndex); - FunctionSize++; - - // Insert max(1, numdefs) empty slots after every instruction. - unsigned Slots = I->getDesc().getNumDefs(); - if (Slots == 0) - Slots = 1; - while (Slots--) { - MIIndex = getNextIndex(MIIndex); - i2miMap_.push_back(0); - } - - } - - if (MBB->getFirstTerminator() == MBB->end()) { - // Leave a gap for before terminators, this is where we will point - // PHI kills. - LiveIndex tGap(true, MIIndex); - bool inserted = - terminatorGaps.insert(std::make_pair(&*MBB, tGap)).second; - assert(inserted && - "Multiple 'first' terminators encountered during numbering."); - inserted = inserted; // Avoid compiler warning if assertions turned off. - i2miMap_.push_back(0); - - MIIndex = getNextIndex(MIIndex); - } - - // Set the MBB2IdxMap entry for this MBB. - MBB2IdxMap[MBB->getNumber()] = std::make_pair(StartIdx, getPrevSlot(MIIndex)); - Idx2MBBMap.push_back(std::make_pair(StartIdx, MBB)); - } - - std::sort(Idx2MBBMap.begin(), Idx2MBBMap.end(), Idx2MBBCompare()); - - if (!OldI2MI.empty()) - for (iterator OI = begin(), OE = end(); OI != OE; ++OI) { - for (LiveInterval::iterator LI = OI->second->begin(), - LE = OI->second->end(); LI != LE; ++LI) { - - // Remap the start index of the live range to the corresponding new - // number, or our best guess at what it _should_ correspond to if the - // original instruction has been erased. This is either the following - // instruction or its predecessor. - unsigned index = LI->start.getVecIndex(); - LiveIndex::Slot offset = LI->start.getSlot(); - if (LI->start.isLoad()) { - std::vector::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), LI->start); - // Take the pair containing the index - std::vector::const_iterator J = - (I == OldI2MBB.end() && OldI2MBB.size()>0) ? (I-1): I; - - LI->start = getMBBStartIdx(J->second); - } else { - LI->start = LiveIndex( - LiveIndex(mi2iMap_[OldI2MI[index]]), - (LiveIndex::Slot)offset); - } - - // Remap the ending index in the same way that we remapped the start, - // except for the final step where we always map to the immediately - // following instruction. - index = (getPrevSlot(LI->end)).getVecIndex(); - offset = LI->end.getSlot(); - if (LI->end.isLoad()) { - // VReg dies at end of block. - std::vector::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), LI->end); - --I; - - LI->end = getNextSlot(getMBBEndIdx(I->second)); - } else { - unsigned idx = index; - while (index < OldI2MI.size() && !OldI2MI[index]) ++index; - - if (index != OldI2MI.size()) - LI->end = - LiveIndex(mi2iMap_[OldI2MI[index]], - (idx == index ? offset : LiveIndex::LOAD)); - else - LI->end = - LiveIndex(LiveIndex::NUM * i2miMap_.size()); - } - } - - for (LiveInterval::vni_iterator VNI = OI->second->vni_begin(), - VNE = OI->second->vni_end(); VNI != VNE; ++VNI) { - VNInfo* vni = *VNI; - - // Remap the VNInfo def index, which works the same as the - // start indices above. VN's with special sentinel defs - // don't need to be remapped. - if (vni->isDefAccurate() && !vni->isUnused()) { - unsigned index = vni->def.getVecIndex(); - LiveIndex::Slot offset = vni->def.getSlot(); - if (vni->def.isLoad()) { - std::vector::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->def); - // Take the pair containing the index - std::vector::const_iterator J = - (I == OldI2MBB.end() && OldI2MBB.size()>0) ? (I-1): I; - - vni->def = getMBBStartIdx(J->second); - } else { - vni->def = LiveIndex(mi2iMap_[OldI2MI[index]], offset); - } - } - - // Remap the VNInfo kill indices, which works the same as - // the end indices above. - for (size_t i = 0; i < vni->kills.size(); ++i) { - unsigned index = getPrevSlot(vni->kills[i]).getVecIndex(); - LiveIndex::Slot offset = vni->kills[i].getSlot(); - - if (vni->kills[i].isLoad()) { - assert("Value killed at a load slot."); - /*std::vector::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->kills[i]); - --I; - - vni->kills[i] = getMBBEndIdx(I->second);*/ - } else { - if (vni->kills[i].isPHIIndex()) { - std::vector::const_iterator I = - std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->kills[i]); - --I; - vni->kills[i] = terminatorGaps[I->second]; - } else { - assert(OldI2MI[index] != 0 && - "Kill refers to instruction not present in index maps."); - vni->kills[i] = LiveIndex(mi2iMap_[OldI2MI[index]], offset); - } - - /* - unsigned idx = index; - while (index < OldI2MI.size() && !OldI2MI[index]) ++index; - - if (index != OldI2MI.size()) - vni->kills[i] = mi2iMap_[OldI2MI[index]] + - (idx == index ? offset : 0); - else - vni->kills[i] = InstrSlots::NUM * i2miMap_.size(); - */ - } - } - } - } -} - -void LiveIntervals::scaleNumbering(int factor) { - // Need to - // * scale MBB begin and end points - // * scale all ranges. - // * Update VNI structures. - // * Scale instruction numberings - - // Scale the MBB indices. - Idx2MBBMap.clear(); - for (MachineFunction::iterator MBB = mf_->begin(), MBBE = mf_->end(); - MBB != MBBE; ++MBB) { - std::pair &mbbIndices = MBB2IdxMap[MBB->getNumber()]; - mbbIndices.first = mbbIndices.first.scale(factor); - mbbIndices.second = mbbIndices.second.scale(factor); - Idx2MBBMap.push_back(std::make_pair(mbbIndices.first, MBB)); - } - std::sort(Idx2MBBMap.begin(), Idx2MBBMap.end(), Idx2MBBCompare()); - - // Scale terminator gaps. - for (DenseMap::iterator - TGI = terminatorGaps.begin(), TGE = terminatorGaps.end(); - TGI != TGE; ++TGI) { - terminatorGaps[TGI->first] = TGI->second.scale(factor); - } - - // Scale the intervals. - for (iterator LI = begin(), LE = end(); LI != LE; ++LI) { - LI->second->scaleNumbering(factor); - } - - // Scale MachineInstrs. - Mi2IndexMap oldmi2iMap = mi2iMap_; - LiveIndex highestSlot; - for (Mi2IndexMap::iterator MI = oldmi2iMap.begin(), ME = oldmi2iMap.end(); - MI != ME; ++MI) { - LiveIndex newSlot = MI->second.scale(factor); - mi2iMap_[MI->first] = newSlot; - highestSlot = std::max(highestSlot, newSlot); - } - - unsigned highestVIndex = highestSlot.getVecIndex(); - i2miMap_.clear(); - i2miMap_.resize(highestVIndex + 1); - for (Mi2IndexMap::iterator MI = mi2iMap_.begin(), ME = mi2iMap_.end(); - MI != ME; ++MI) { - i2miMap_[MI->second.getVecIndex()] = const_cast(MI->first); - } - -} - - /// runOnMachineFunction - Register allocate the whole function /// bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { @@ -532,10 +116,9 @@ tii_ = tm_->getInstrInfo(); aa_ = &getAnalysis(); lv_ = &getAnalysis(); + indexes_ = &getAnalysis(); allocatableRegs_ = tri_->getAllocatableSet(fn); - processImplicitDefs(); - computeNumbering(); computeIntervals(); performEarlyCoalescing(); @@ -579,12 +162,13 @@ VirtRegMap &vrm, unsigned reg) { for (LiveInterval::Ranges::const_iterator I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { - for (LiveIndex index = getBaseIndex(I->start), - end = getNextIndex(getBaseIndex(getPrevSlot(I->end))); index != end; - index = getNextIndex(index)) { + for (SlotIndex index = I->start.getBaseIndex(), + end = I->end.getPrevSlot().getBaseIndex().getNextIndex(); + index != end; + index = index.getNextIndex()) { // skip deleted instructions while (index != end && !getInstructionFromIndex(index)) - index = getNextIndex(index); + index = index.getNextIndex(); if (index == end) break; MachineInstr *MI = getInstructionFromIndex(index); @@ -620,16 +204,17 @@ SmallPtrSet &JoinedCopies) { for (LiveInterval::Ranges::const_iterator I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { - for (LiveIndex index = getBaseIndex(I->start), - end = getNextIndex(getBaseIndex(getPrevSlot(I->end))); index != end; - index = getNextIndex(index)) { + for (SlotIndex index = I->start.getBaseIndex(), + end = I->end.getPrevSlot().getBaseIndex().getNextIndex(); + index != end; + index = index.getNextIndex()) { // Skip deleted instructions. MachineInstr *MI = 0; while (index != end) { MI = getInstructionFromIndex(index); if (MI) break; - index = getNextIndex(index); + index = index.getNextIndex(); } if (index == end) break; @@ -664,7 +249,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, MachineBasicBlock::iterator mi, - LiveIndex MIIdx, + SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx, LiveInterval &interval) { @@ -680,11 +265,11 @@ LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); if (interval.empty()) { // Get the Idx of the defining instructions. - LiveIndex defIndex = getDefIndex(MIIdx); + SlotIndex defIndex = MIIdx.getDefIndex(); // Earlyclobbers move back one, so that they overlap the live range // of inputs. if (MO.isEarlyClobber()) - defIndex = getUseIndex(MIIdx); + defIndex = MIIdx.getUseIndex(); VNInfo *ValNo; MachineInstr *CopyMI = NULL; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; @@ -704,16 +289,11 @@ // will be a single kill, in MBB, which comes after the definition. if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) { // FIXME: what about dead vars? - LiveIndex killIdx; + SlotIndex killIdx; if (vi.Kills[0] != mi) - killIdx = getNextSlot(getUseIndex(getInstructionIndex(vi.Kills[0]))); - else if (MO.isEarlyClobber()) - // Earlyclobbers that die in this instruction move up one extra, to - // compensate for having the starting point moved back one. This - // gets them to overlap the live range of other outputs. - killIdx = getNextSlot(getNextSlot(defIndex)); + killIdx = getInstructionIndex(vi.Kills[0]).getDefIndex(); else - killIdx = getNextSlot(defIndex); + killIdx = defIndex.getStoreIndex(); // If the kill happens after the definition, we have an intra-block // live range. @@ -732,7 +312,8 @@ // of the defining block, potentially live across some blocks, then is // live into some number of blocks, but gets killed. Start by adding a // range that goes from this definition to the end of the defining block. - LiveRange NewLR(defIndex, getNextSlot(getMBBEndIdx(mbb)), ValNo); + LiveRange NewLR(defIndex, getMBBEndIdx(mbb).getNextIndex().getLoadIndex(), + ValNo); DEBUG(errs() << " +" << NewLR); interval.addRange(NewLR); @@ -741,9 +322,10 @@ // live interval. for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(), E = vi.AliveBlocks.end(); I != E; ++I) { - LiveRange LR(getMBBStartIdx(*I), - getNextSlot(getMBBEndIdx(*I)), // MBB ends at -1. - ValNo); + LiveRange LR( + getMBBStartIdx(mf_->getBlockNumbered(*I)), + getMBBEndIdx(mf_->getBlockNumbered(*I)).getNextIndex().getLoadIndex(), + ValNo); interval.addRange(LR); DEBUG(errs() << " +" << LR); } @@ -752,8 +334,8 @@ // block to the 'use' slot of the killing instruction. for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) { MachineInstr *Kill = vi.Kills[i]; - LiveIndex killIdx = - getNextSlot(getUseIndex(getInstructionIndex(Kill))); + SlotIndex killIdx = + getInstructionIndex(Kill).getDefIndex(); LiveRange LR(getMBBStartIdx(Kill->getParent()), killIdx, ValNo); interval.addRange(LR); ValNo->addKill(killIdx); @@ -772,13 +354,13 @@ // need to take the LiveRegion that defines this register and split it // into two values. assert(interval.containsOneValue()); - LiveIndex DefIndex = getDefIndex(interval.getValNumInfo(0)->def); - LiveIndex RedefIndex = getDefIndex(MIIdx); + SlotIndex DefIndex = interval.getValNumInfo(0)->def.getDefIndex(); + SlotIndex RedefIndex = MIIdx.getDefIndex(); if (MO.isEarlyClobber()) - RedefIndex = getUseIndex(MIIdx); + RedefIndex = MIIdx.getUseIndex(); const LiveRange *OldLR = - interval.getLiveRangeContaining(getPrevSlot(RedefIndex)); + interval.getLiveRangeContaining(RedefIndex.getUseIndex()); VNInfo *OldValNo = OldLR->valno; // Delete the initial value, which should be short and continuous, @@ -811,10 +393,8 @@ // If this redefinition is dead, we need to add a dummy unit live // range covering the def slot. if (MO.isDead()) - interval.addRange( - LiveRange(RedefIndex, MO.isEarlyClobber() ? - getNextSlot(getNextSlot(RedefIndex)) : - getNextSlot(RedefIndex), OldValNo)); + interval.addRange(LiveRange(RedefIndex, RedefIndex.getStoreIndex(), + OldValNo)); DEBUG({ errs() << " RESULT: "; @@ -829,9 +409,8 @@ VNInfo *VNI = interval.getValNumInfo(0); MachineInstr *Killer = vi.Kills[0]; phiJoinCopies.push_back(Killer); - LiveIndex Start = getMBBStartIdx(Killer->getParent()); - LiveIndex End = - getNextSlot(getUseIndex(getInstructionIndex(Killer))); + SlotIndex Start = getMBBStartIdx(Killer->getParent()); + SlotIndex End = getInstructionIndex(Killer).getDefIndex(); DEBUG({ errs() << " Removing [" << Start << "," << End << "] from: "; interval.print(errs(), tri_); @@ -841,7 +420,7 @@ assert(interval.ranges.size() == 1 && "Newly discovered PHI interval has >1 ranges."); MachineBasicBlock *killMBB = getMBBFromIndex(interval.endIndex()); - VNI->addKill(terminatorGaps[killMBB]); + VNI->addKill(indexes_->getTerminatorGap(killMBB)); VNI->setHasPHIKill(true); DEBUG({ errs() << " RESULT: "; @@ -851,8 +430,8 @@ // Replace the interval with one of a NEW value number. Note that this // value number isn't actually defined by an instruction, weird huh? :) LiveRange LR(Start, End, - interval.getNextValue(LiveIndex(mbb->getNumber()), - 0, false, VNInfoAllocator)); + interval.getNextValue(SlotIndex(getMBBStartIdx(mbb), true), + 0, false, VNInfoAllocator)); LR.valno->setIsPHIDef(true); DEBUG(errs() << " replace range with " << LR); interval.addRange(LR); @@ -866,9 +445,9 @@ // In the case of PHI elimination, each variable definition is only // live until the end of the block. We've already taken care of the // rest of the live range. - LiveIndex defIndex = getDefIndex(MIIdx); + SlotIndex defIndex = MIIdx.getDefIndex(); if (MO.isEarlyClobber()) - defIndex = getUseIndex(MIIdx); + defIndex = MIIdx.getUseIndex(); VNInfo *ValNo; MachineInstr *CopyMI = NULL; @@ -880,10 +459,10 @@ CopyMI = mi; ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator); - LiveIndex killIndex = getNextSlot(getMBBEndIdx(mbb)); + SlotIndex killIndex = getMBBEndIdx(mbb).getNextIndex().getLoadIndex(); LiveRange LR(defIndex, killIndex, ValNo); interval.addRange(LR); - ValNo->addKill(terminatorGaps[mbb]); + ValNo->addKill(indexes_->getTerminatorGap(mbb)); ValNo->setHasPHIKill(true); DEBUG(errs() << " +" << LR); } @@ -894,7 +473,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator mi, - LiveIndex MIIdx, + SlotIndex MIIdx, MachineOperand& MO, LiveInterval &interval, MachineInstr *CopyMI) { @@ -905,12 +484,12 @@ printRegName(interval.reg, tri_); }); - LiveIndex baseIndex = MIIdx; - LiveIndex start = getDefIndex(baseIndex); + SlotIndex baseIndex = MIIdx; + SlotIndex start = baseIndex.getDefIndex(); // Earlyclobbers move back one. if (MO.isEarlyClobber()) - start = getUseIndex(MIIdx); - LiveIndex end = start; + start = MIIdx.getUseIndex(); + SlotIndex end = start; // If it is not used after definition, it is considered dead at // the instruction defining it. Hence its interval is: @@ -919,53 +498,51 @@ // advance below compensates. if (MO.isDead()) { DEBUG(errs() << " dead"); - if (MO.isEarlyClobber()) - end = getNextSlot(getNextSlot(start)); - else - end = getNextSlot(start); + end = start.getStoreIndex(); goto exit; } // If it is not dead on definition, it must be killed by a // subsequent instruction. Hence its interval is: // [defSlot(def), useSlot(kill)+1) - baseIndex = getNextIndex(baseIndex); + baseIndex = baseIndex.getNextIndex(); while (++mi != MBB->end()) { - while (baseIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(baseIndex) == 0) - baseIndex = getNextIndex(baseIndex); + + if (getInstructionFromIndex(baseIndex) == 0) + baseIndex = indexes_->getNextNonNullIndex(baseIndex); + if (mi->killsRegister(interval.reg, tri_)) { DEBUG(errs() << " killed"); - end = getNextSlot(getUseIndex(baseIndex)); + end = baseIndex.getDefIndex(); goto exit; } else { int DefIdx = mi->findRegisterDefOperandIdx(interval.reg, false, tri_); if (DefIdx != -1) { if (mi->isRegTiedToUseOperand(DefIdx)) { // Two-address instruction. - end = getDefIndex(baseIndex); - if (mi->getOperand(DefIdx).isEarlyClobber()) - end = getUseIndex(baseIndex); + end = baseIndex.getDefIndex(); + assert(!mi->getOperand(DefIdx).isEarlyClobber() && + "Two address instruction is an early clobber?"); } else { // Another instruction redefines the register before it is ever read. // Then the register is essentially dead at the instruction that defines // it. Hence its interval is: // [defSlot(def), defSlot(def)+1) DEBUG(errs() << " dead"); - end = getNextSlot(start); + end = start.getStoreIndex(); } goto exit; } } - baseIndex = getNextIndex(baseIndex); + baseIndex = baseIndex.getNextIndex(); } // The only case we should have a dead physreg here without a killing or // instruction where we know it's dead is if it is live-in to the function // and never used. Another possible case is the implicit use of the // physical register has been deleted by two-address pass. - end = getNextSlot(start); + end = start.getStoreIndex(); exit: assert(start < end && "did not find end of interval?"); @@ -985,7 +562,7 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator MI, - LiveIndex MIIdx, + SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx) { if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) @@ -1012,7 +589,7 @@ } void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, - LiveIndex MIIdx, + SlotIndex MIIdx, LiveInterval &interval, bool isAlias) { DEBUG({ errs() << "\t\tlivein register: "; @@ -1022,18 +599,18 @@ // Look for kills, if it reaches a def before it's killed, then it shouldn't // be considered a livein. MachineBasicBlock::iterator mi = MBB->begin(); - LiveIndex baseIndex = MIIdx; - LiveIndex start = baseIndex; - while (baseIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(baseIndex) == 0) - baseIndex = getNextIndex(baseIndex); - LiveIndex end = baseIndex; + SlotIndex baseIndex = MIIdx; + SlotIndex start = baseIndex; + if (getInstructionFromIndex(baseIndex) == 0) + baseIndex = indexes_->getNextNonNullIndex(baseIndex); + + SlotIndex end = baseIndex; bool SeenDefUse = false; while (mi != MBB->end()) { if (mi->killsRegister(interval.reg, tri_)) { DEBUG(errs() << " killed"); - end = getNextSlot(getUseIndex(baseIndex)); + end = baseIndex.getDefIndex(); SeenDefUse = true; break; } else if (mi->modifiesRegister(interval.reg, tri_)) { @@ -1042,17 +619,14 @@ // it. Hence its interval is: // [defSlot(def), defSlot(def)+1) DEBUG(errs() << " dead"); - end = getNextSlot(getDefIndex(start)); + end = start.getStoreIndex(); SeenDefUse = true; break; } - baseIndex = getNextIndex(baseIndex); ++mi; if (mi != MBB->end()) { - while (baseIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(baseIndex) == 0) - baseIndex = getNextIndex(baseIndex); + baseIndex = indexes_->getNextNonNullIndex(baseIndex); } } @@ -1060,7 +634,7 @@ if (!SeenDefUse) { if (isAlias) { DEBUG(errs() << " dead"); - end = getNextSlot(getDefIndex(MIIdx)); + end = MIIdx.getStoreIndex(); } else { DEBUG(errs() << " live through"); end = baseIndex; @@ -1068,7 +642,7 @@ } VNInfo *vni = - interval.getNextValue(LiveIndex(MBB->getNumber()), + interval.getNextValue(SlotIndex(getMBBStartIdx(MBB), true), 0, false, VNInfoAllocator); vni->setIsPHIDef(true); LiveRange LR(start, end, vni); @@ -1139,11 +713,11 @@ MachineInstr *PHICopy = OtherCopies[i]; DEBUG(errs() << "Moving: " << *PHICopy); - LiveIndex MIIndex = getInstructionIndex(PHICopy); - LiveIndex DefIndex = getDefIndex(MIIndex); + SlotIndex MIIndex = getInstructionIndex(PHICopy); + SlotIndex DefIndex = MIIndex.getDefIndex(); LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex); - LiveIndex StartIndex = SLR->start; - LiveIndex EndIndex = SLR->end; + SlotIndex StartIndex = SLR->start; + SlotIndex EndIndex = SLR->end; // Delete val# defined by the now identity copy and add the range from // beginning of the mbb to the end of the range. @@ -1169,11 +743,11 @@ MachineInstr *PHICopy = IdentCopies[i]; DEBUG(errs() << "Coalescing: " << *PHICopy); - LiveIndex MIIndex = getInstructionIndex(PHICopy); - LiveIndex DefIndex = getDefIndex(MIIndex); + SlotIndex MIIndex = getInstructionIndex(PHICopy); + SlotIndex DefIndex = MIIndex.getDefIndex(); LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex); - LiveIndex StartIndex = SLR->start; - LiveIndex EndIndex = SLR->end; + SlotIndex StartIndex = SLR->start; + SlotIndex EndIndex = SLR->end; // Delete val# defined by the now identity copy and add the range from // beginning of the mbb to the end of the range. @@ -1186,9 +760,9 @@ } // Remove the phi join and update the phi block liveness. - LiveIndex MIIndex = getInstructionIndex(Join); - LiveIndex UseIndex = getUseIndex(MIIndex); - LiveIndex DefIndex = getDefIndex(MIIndex); + SlotIndex MIIndex = getInstructionIndex(Join); + SlotIndex UseIndex = MIIndex.getUseIndex(); + SlotIndex DefIndex = MIIndex.getDefIndex(); LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex); LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex); DLR->valno->setCopy(0); @@ -1218,7 +792,7 @@ MBBI != E; ++MBBI) { MachineBasicBlock *MBB = MBBI; // Track the index of the current machine instr. - LiveIndex MIIndex = getMBBStartIdx(MBB); + SlotIndex MIIndex = getMBBStartIdx(MBB); DEBUG(errs() << ((Value*)MBB->getBasicBlock())->getName() << ":\n"); MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end(); @@ -1235,9 +809,8 @@ } // Skip over empty initial indices. - while (MIIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(MIIndex) == 0) - MIIndex = getNextIndex(MIIndex); + if (getInstructionFromIndex(MIIndex) == 0) + MIIndex = indexes_->getNextNonNullIndex(MIIndex); for (; MI != miEnd; ++MI) { DEBUG(errs() << MIIndex << "\t" << *MI); @@ -1254,19 +827,9 @@ else if (MO.isUndef()) UndefUses.push_back(MO.getReg()); } - - // Skip over the empty slots after each instruction. - unsigned Slots = MI->getDesc().getNumDefs(); - if (Slots == 0) - Slots = 1; - - while (Slots--) - MIIndex = getNextIndex(MIIndex); - // Skip over empty indices. - while (MIIndex.getVecIndex() < i2miMap_.size() && - getInstructionFromIndex(MIIndex) == 0) - MIIndex = getNextIndex(MIIndex); + // Move to the next instr slot. + MIIndex = indexes_->getNextNonNullIndex(MIIndex); } } @@ -1279,45 +842,6 @@ } } -bool LiveIntervals::findLiveInMBBs( - LiveIndex Start, LiveIndex End, - SmallVectorImpl &MBBs) const { - std::vector::const_iterator I = - std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), Start); - - bool ResVal = false; - while (I != Idx2MBBMap.end()) { - if (I->first >= End) - break; - MBBs.push_back(I->second); - ResVal = true; - ++I; - } - return ResVal; -} - -bool LiveIntervals::findReachableMBBs( - LiveIndex Start, LiveIndex End, - SmallVectorImpl &MBBs) const { - std::vector::const_iterator I = - std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), Start); - - bool ResVal = false; - while (I != Idx2MBBMap.end()) { - if (I->first > End) - break; - MachineBasicBlock *MBB = I->second; - if (getMBBEndIdx(MBB) > End) - break; - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) - MBBs.push_back(*SI); - ResVal = true; - ++I; - } - return ResVal; -} - LiveInterval* LiveIntervals::createInterval(unsigned reg) { float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ? HUGE_VALF : 0.0F; return new LiveInterval(reg, Weight); @@ -1389,8 +913,8 @@ /// isValNoAvailableAt - Return true if the val# of the specified interval /// which reaches the given instruction also reaches the specified use index. bool LiveIntervals::isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI, - LiveIndex UseIdx) const { - LiveIndex Index = getInstructionIndex(MI); + SlotIndex UseIdx) const { + SlotIndex Index = getInstructionIndex(MI); VNInfo *ValNo = li.FindLiveRangeContaining(Index)->valno; LiveInterval::const_iterator UI = li.FindLiveRangeContaining(UseIdx); return UI != li.end() && UI->valno == ValNo; @@ -1417,7 +941,7 @@ for (MachineRegisterInfo::use_iterator ri = mri_->use_begin(li.reg), re = mri_->use_end(); ri != re; ++ri) { MachineInstr *UseMI = &*ri; - LiveIndex UseIdx = getInstructionIndex(UseMI); + SlotIndex UseIdx = getInstructionIndex(UseMI); if (li.FindLiveRangeContaining(UseIdx)->valno != ValNo) continue; if (!isValNoAvailableAt(ImpLi, MI, UseIdx)) @@ -1502,7 +1026,7 @@ /// returns true. bool LiveIntervals::tryFoldMemoryOperand(MachineInstr* &MI, VirtRegMap &vrm, MachineInstr *DefMI, - LiveIndex InstrIdx, + SlotIndex InstrIdx, SmallVector &Ops, bool isSS, int Slot, unsigned Reg) { // If it is an implicit def instruction, just delete it. @@ -1540,9 +1064,7 @@ vrm.transferSpillPts(MI, fmi); vrm.transferRestorePts(MI, fmi); vrm.transferEmergencySpills(MI, fmi); - mi2iMap_.erase(MI); - i2miMap_[InstrIdx.getVecIndex()] = fmi; - mi2iMap_[fmi] = InstrIdx; + ReplaceMachineInstrInMaps(MI, fmi); MI = MBB.insert(MBB.erase(MI), fmi); ++numFolds; return true; @@ -1570,19 +1092,21 @@ } bool LiveIntervals::intervalIsInOneMBB(const LiveInterval &li) const { - SmallPtrSet MBBs; - for (LiveInterval::Ranges::const_iterator - I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { - std::vector::const_iterator II = - std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), I->start); - if (II == Idx2MBBMap.end()) - continue; - if (I->end > II->first) // crossing a MBB. - return false; - MBBs.insert(II->second); - if (MBBs.size() > 1) + LiveInterval::Ranges::const_iterator itr = li.ranges.begin(); + + MachineBasicBlock *mbb = indexes_->getMBBCoveringRange(itr->start, itr->end); + + if (mbb == 0) + return false; + + for (++itr; itr != li.ranges.end(); ++itr) { + MachineBasicBlock *mbb2 = + indexes_->getMBBCoveringRange(itr->start, itr->end); + + if (mbb2 != mbb) return false; } + return true; } @@ -1614,7 +1138,7 @@ /// for addIntervalsForSpills to rewrite uses / defs for the given live range. bool LiveIntervals:: rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, - bool TrySplit, LiveIndex index, LiveIndex end, + bool TrySplit, SlotIndex index, SlotIndex end, MachineInstr *MI, MachineInstr *ReMatOrigDefMI, MachineInstr *ReMatDefMI, unsigned Slot, int LdSlot, @@ -1791,14 +1315,13 @@ if (HasUse) { if (CreatedNewVReg) { - LiveRange LR(getLoadIndex(index), getNextSlot(getUseIndex(index)), - nI.getNextValue(LiveIndex(), 0, false, - VNInfoAllocator)); + LiveRange LR(index.getLoadIndex(), index.getDefIndex(), + nI.getNextValue(SlotIndex(), 0, false, VNInfoAllocator)); DEBUG(errs() << " +" << LR); nI.addRange(LR); } else { // Extend the split live interval to this def / use. - LiveIndex End = getNextSlot(getUseIndex(index)); + SlotIndex End = index.getDefIndex(); LiveRange LR(nI.ranges[nI.ranges.size()-1].end, End, nI.getValNumInfo(nI.getNumValNums()-1)); DEBUG(errs() << " +" << LR); @@ -1806,9 +1329,8 @@ } } if (HasDef) { - LiveRange LR(getDefIndex(index), getStoreIndex(index), - nI.getNextValue(LiveIndex(), 0, false, - VNInfoAllocator)); + LiveRange LR(index.getDefIndex(), index.getStoreIndex(), + nI.getNextValue(SlotIndex(), 0, false, VNInfoAllocator)); DEBUG(errs() << " +" << LR); nI.addRange(LR); } @@ -1824,13 +1346,13 @@ bool LiveIntervals::anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI, MachineBasicBlock *MBB, - LiveIndex Idx) const { - LiveIndex End = getMBBEndIdx(MBB); + SlotIndex Idx) const { + SlotIndex End = getMBBEndIdx(MBB); for (unsigned j = 0, ee = VNI->kills.size(); j != ee; ++j) { - if (VNI->kills[j].isPHIIndex()) + if (VNI->kills[j].isPHI()) continue; - LiveIndex KillIdx = VNI->kills[j]; + SlotIndex KillIdx = VNI->kills[j]; if (KillIdx > Idx && KillIdx < End) return true; } @@ -1841,11 +1363,11 @@ /// during spilling. namespace { struct RewriteInfo { - LiveIndex Index; + SlotIndex Index; MachineInstr *MI; bool HasUse; bool HasDef; - RewriteInfo(LiveIndex i, MachineInstr *mi, bool u, bool d) + RewriteInfo(SlotIndex i, MachineInstr *mi, bool u, bool d) : Index(i), MI(mi), HasUse(u), HasDef(d) {} }; @@ -1874,8 +1396,8 @@ std::vector &NewLIs) { bool AllCanFold = true; unsigned NewVReg = 0; - LiveIndex start = getBaseIndex(I->start); - LiveIndex end = getNextIndex(getBaseIndex(getPrevSlot(I->end))); + SlotIndex start = I->start.getBaseIndex(); + SlotIndex end = I->end.getPrevSlot().getBaseIndex().getNextIndex(); // First collect all the def / use in this live range that will be rewritten. // Make sure they are sorted according to instruction index. @@ -1886,7 +1408,7 @@ MachineOperand &O = ri.getOperand(); ++ri; assert(!O.isImplicit() && "Spilling register that's used as implicit use?"); - LiveIndex index = getInstructionIndex(MI); + SlotIndex index = getInstructionIndex(MI); if (index < start || index >= end) continue; @@ -1910,7 +1432,7 @@ for (unsigned i = 0, e = RewriteMIs.size(); i != e; ) { RewriteInfo &rwi = RewriteMIs[i]; ++i; - LiveIndex index = rwi.Index; + SlotIndex index = rwi.Index; bool MIHasUse = rwi.HasUse; bool MIHasDef = rwi.HasDef; MachineInstr *MI = rwi.MI; @@ -1993,12 +1515,12 @@ if (MI != ReMatOrigDefMI || !CanDelete) { bool HasKill = false; if (!HasUse) - HasKill = anyKillInMBBAfterIdx(li, I->valno, MBB, getDefIndex(index)); + HasKill = anyKillInMBBAfterIdx(li, I->valno, MBB, index.getDefIndex()); else { // If this is a two-address code, then this index starts a new VNInfo. - const VNInfo *VNI = li.findDefinedVNInfoForRegInt(getDefIndex(index)); + const VNInfo *VNI = li.findDefinedVNInfoForRegInt(index.getDefIndex()); if (VNI) - HasKill = anyKillInMBBAfterIdx(li, VNI, MBB, getDefIndex(index)); + HasKill = anyKillInMBBAfterIdx(li, VNI, MBB, index.getDefIndex()); } DenseMap >::iterator SII = SpillIdxes.find(MBBId); @@ -2071,7 +1593,7 @@ } } -bool LiveIntervals::alsoFoldARestore(int Id, LiveIndex index, +bool LiveIntervals::alsoFoldARestore(int Id, SlotIndex index, unsigned vr, BitVector &RestoreMBBs, DenseMap > &RestoreIdxes) { if (!RestoreMBBs[Id]) @@ -2085,7 +1607,7 @@ return false; } -void LiveIntervals::eraseRestoreInfo(int Id, LiveIndex index, +void LiveIntervals::eraseRestoreInfo(int Id, SlotIndex index, unsigned vr, BitVector &RestoreMBBs, DenseMap > &RestoreIdxes) { if (!RestoreMBBs[Id]) @@ -2093,7 +1615,7 @@ std::vector &Restores = RestoreIdxes[Id]; for (unsigned i = 0, e = Restores.size(); i != e; ++i) if (Restores[i].index == index && Restores[i].vreg) - Restores[i].index = LiveIndex(); + Restores[i].index = SlotIndex(); } /// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being @@ -2192,18 +1714,18 @@ } // Fill in the new live interval. - LiveIndex index = getInstructionIndex(MI); + SlotIndex index = getInstructionIndex(MI); if (HasUse) { - LiveRange LR(getLoadIndex(index), getUseIndex(index), - nI.getNextValue(LiveIndex(), 0, false, + LiveRange LR(index.getLoadIndex(), index.getUseIndex(), + nI.getNextValue(SlotIndex(), 0, false, getVNInfoAllocator())); DEBUG(errs() << " +" << LR); nI.addRange(LR); vrm.addRestorePoint(NewVReg, MI); } if (HasDef) { - LiveRange LR(getDefIndex(index), getStoreIndex(index), - nI.getNextValue(LiveIndex(), 0, false, + LiveRange LR(index.getDefIndex(), index.getStoreIndex(), + nI.getNextValue(SlotIndex(), 0, false, getVNInfoAllocator())); DEBUG(errs() << " +" << LR); nI.addRange(LR); @@ -2267,8 +1789,8 @@ if (vrm.getPreSplitReg(li.reg)) { vrm.setIsSplitFromReg(li.reg, 0); // Unset the split kill marker on the last use. - LiveIndex KillIdx = vrm.getKillPoint(li.reg); - if (KillIdx != LiveIndex()) { + SlotIndex KillIdx = vrm.getKillPoint(li.reg); + if (KillIdx != SlotIndex()) { MachineInstr *KillMI = getInstructionFromIndex(KillIdx); assert(KillMI && "Last use disappeared?"); int KillOp = KillMI->findRegisterUseOperandIdx(li.reg, true); @@ -2394,7 +1916,7 @@ while (Id != -1) { std::vector &spills = SpillIdxes[Id]; for (unsigned i = 0, e = spills.size(); i != e; ++i) { - LiveIndex index = spills[i].index; + SlotIndex index = spills[i].index; unsigned VReg = spills[i].vreg; LiveInterval &nI = getOrCreateInterval(VReg); bool isReMat = vrm.isReMaterialized(VReg); @@ -2432,16 +1954,16 @@ if (FoundUse) { // Also folded uses, do not issue a load. eraseRestoreInfo(Id, index, VReg, RestoreMBBs, RestoreIdxes); - nI.removeRange(getLoadIndex(index), getNextSlot(getUseIndex(index))); + nI.removeRange(index.getLoadIndex(), index.getDefIndex()); } - nI.removeRange(getDefIndex(index), getStoreIndex(index)); + nI.removeRange(index.getDefIndex(), index.getStoreIndex()); } } // Otherwise tell the spiller to issue a spill. if (!Folded) { LiveRange *LR = &nI.ranges[nI.ranges.size()-1]; - bool isKill = LR->end == getStoreIndex(index); + bool isKill = LR->end == index.getStoreIndex(); if (!MI->registerDefIsDead(nI.reg)) // No need to spill a dead def. vrm.addSpillPoint(VReg, isKill, MI); @@ -2457,8 +1979,8 @@ while (Id != -1) { std::vector &restores = RestoreIdxes[Id]; for (unsigned i = 0, e = restores.size(); i != e; ++i) { - LiveIndex index = restores[i].index; - if (index == LiveIndex()) + SlotIndex index = restores[i].index; + if (index == SlotIndex()) continue; unsigned VReg = restores[i].vreg; LiveInterval &nI = getOrCreateInterval(VReg); @@ -2513,7 +2035,7 @@ // If folding is not possible / failed, then tell the spiller to issue a // load / rematerialization for us. if (Folded) - nI.removeRange(getLoadIndex(index), getNextSlot(getUseIndex(index))); + nI.removeRange(index.getLoadIndex(), index.getDefIndex()); else vrm.addRestorePoint(VReg, MI); } @@ -2526,10 +2048,10 @@ for (unsigned i = 0, e = NewLIs.size(); i != e; ++i) { LiveInterval *LI = NewLIs[i]; if (!LI->empty()) { - LI->weight /= InstrSlots::NUM * getApproximateInstructionCount(*LI); + LI->weight /= SlotIndex::NUM * getApproximateInstructionCount(*LI); if (!AddedKill.count(LI)) { LiveRange *LR = &LI->ranges[LI->ranges.size()-1]; - LiveIndex LastUseIdx = getBaseIndex(LR->end); + SlotIndex LastUseIdx = LR->end.getBaseIndex(); MachineInstr *LastUse = getInstructionFromIndex(LastUseIdx); int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg, false); assert(UseIdx != -1); @@ -2580,7 +2102,7 @@ E = mri_->reg_end(); I != E; ++I) { MachineOperand &O = I.getOperand(); MachineInstr *MI = O.getParent(); - LiveIndex Index = getInstructionIndex(MI); + SlotIndex Index = getInstructionIndex(MI); if (pli.liveAt(Index)) ++NumConflicts; } @@ -2623,15 +2145,15 @@ if (SeenMIs.count(MI)) continue; SeenMIs.insert(MI); - LiveIndex Index = getInstructionIndex(MI); + SlotIndex Index = getInstructionIndex(MI); for (unsigned i = 0, e = PRegs.size(); i != e; ++i) { unsigned PReg = PRegs[i]; LiveInterval &pli = getInterval(PReg); if (!pli.liveAt(Index)) continue; vrm.addEmergencySpill(PReg, MI); - LiveIndex StartIdx = getLoadIndex(Index); - LiveIndex EndIdx = getNextSlot(getStoreIndex(Index)); + SlotIndex StartIdx = Index.getLoadIndex(); + SlotIndex EndIdx = Index.getNextIndex().getBaseIndex(); if (pli.isInOneLiveRange(StartIdx, EndIdx)) { pli.removeRange(StartIdx, EndIdx); Cut = true; @@ -2651,7 +2173,8 @@ continue; LiveInterval &spli = getInterval(*AS); if (spli.liveAt(Index)) - spli.removeRange(getLoadIndex(Index), getNextSlot(getStoreIndex(Index))); + spli.removeRange(Index.getLoadIndex(), + Index.getNextIndex().getBaseIndex()); } } } @@ -2662,13 +2185,13 @@ MachineInstr* startInst) { LiveInterval& Interval = getOrCreateInterval(reg); VNInfo* VN = Interval.getNextValue( - LiveIndex(getInstructionIndex(startInst), LiveIndex::DEF), + SlotIndex(getInstructionIndex(startInst).getDefIndex()), startInst, true, getVNInfoAllocator()); VN->setHasPHIKill(true); - VN->kills.push_back(terminatorGaps[startInst->getParent()]); + VN->kills.push_back(indexes_->getTerminatorGap(startInst->getParent())); LiveRange LR( - LiveIndex(getInstructionIndex(startInst), LiveIndex::DEF), - getNextSlot(getMBBEndIdx(startInst->getParent())), VN); + SlotIndex(getInstructionIndex(startInst).getDefIndex()), + getMBBEndIdx(startInst->getParent()).getNextIndex().getBaseIndex(), VN); Interval.addRange(LR); return LR; Modified: llvm/trunk/lib/CodeGen/LiveStackAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveStackAnalysis.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveStackAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveStackAnalysis.cpp Tue Nov 3 17:52:08 2009 @@ -27,15 +27,10 @@ char LiveStacks::ID = 0; static RegisterPass X("livestacks", "Live Stack Slot Analysis"); -void LiveStacks::scaleNumbering(int factor) { - // Scale the intervals. - for (iterator LI = begin(), LE = end(); LI != LE; ++LI) { - LI->second.scaleNumbering(factor); - } -} - void LiveStacks::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); + AU.addPreserved(); + AU.addRequiredTransitive(); MachineFunctionPass::getAnalysisUsage(AU); } Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Tue Nov 3 17:52:08 2009 @@ -57,6 +57,7 @@ const TargetRegisterInfo* TRI; MachineFrameInfo *MFI; MachineRegisterInfo *MRI; + SlotIndexes *SIs; LiveIntervals *LIs; LiveStacks *LSs; VirtRegMap *VRM; @@ -68,7 +69,7 @@ MachineBasicBlock *BarrierMBB; // Barrier - Current barrier index. - LiveIndex BarrierIdx; + SlotIndex BarrierIdx; // CurrLI - Current live interval being split. LiveInterval *CurrLI; @@ -83,16 +84,19 @@ DenseMap IntervalSSMap; // Def2SpillMap - A map from a def instruction index to spill index. - DenseMap Def2SpillMap; + DenseMap Def2SpillMap; public: static char ID; - PreAllocSplitting() : MachineFunctionPass(&ID) {} + PreAllocSplitting() + : MachineFunctionPass(&ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); @@ -129,23 +133,23 @@ private: MachineBasicBlock::iterator findNextEmptySlot(MachineBasicBlock*, MachineInstr*, - LiveIndex&); + SlotIndex&); MachineBasicBlock::iterator findSpillPoint(MachineBasicBlock*, MachineInstr*, MachineInstr*, - SmallPtrSet&, LiveIndex&); + SmallPtrSet&, SlotIndex&); MachineBasicBlock::iterator - findRestorePoint(MachineBasicBlock*, MachineInstr*, LiveIndex, - SmallPtrSet&, LiveIndex&); + findRestorePoint(MachineBasicBlock*, MachineInstr*, SlotIndex, + SmallPtrSet&, SlotIndex&); int CreateSpillStackSlot(unsigned, const TargetRegisterClass *); bool IsAvailableInStack(MachineBasicBlock*, unsigned, - LiveIndex, LiveIndex, - LiveIndex&, int&) const; + SlotIndex, SlotIndex, + SlotIndex&, int&) const; - void UpdateSpillSlotInterval(VNInfo*, LiveIndex, LiveIndex); + void UpdateSpillSlotInterval(VNInfo*, SlotIndex, SlotIndex); bool SplitRegLiveInterval(LiveInterval*); @@ -157,7 +161,7 @@ bool Rematerialize(unsigned vreg, VNInfo* ValNo, MachineInstr* DefMI, MachineBasicBlock::iterator RestorePt, - LiveIndex RestoreIdx, + SlotIndex RestoreIdx, SmallPtrSet& RefsInMBB); MachineInstr* FoldSpill(unsigned vreg, const TargetRegisterClass* RC, MachineInstr* DefMI, @@ -209,12 +213,12 @@ /// instruction index map. If there isn't one, return end(). MachineBasicBlock::iterator PreAllocSplitting::findNextEmptySlot(MachineBasicBlock *MBB, MachineInstr *MI, - LiveIndex &SpotIndex) { + SlotIndex &SpotIndex) { MachineBasicBlock::iterator MII = MI; if (++MII != MBB->end()) { - LiveIndex Index = + SlotIndex Index = LIs->findGapBeforeInstr(LIs->getInstructionIndex(MII)); - if (Index != LiveIndex()) { + if (Index != SlotIndex()) { SpotIndex = Index; return MII; } @@ -230,7 +234,7 @@ PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI, MachineInstr *DefMI, SmallPtrSet &RefsInMBB, - LiveIndex &SpillIndex) { + SlotIndex &SpillIndex) { MachineBasicBlock::iterator Pt = MBB->begin(); MachineBasicBlock::iterator MII = MI; @@ -243,7 +247,7 @@ if (MII == EndPt || RefsInMBB.count(MII)) return Pt; while (MII != EndPt && !RefsInMBB.count(MII)) { - LiveIndex Index = LIs->getInstructionIndex(MII); + SlotIndex Index = LIs->getInstructionIndex(MII); // We can't insert the spill between the barrier (a call), and its // corresponding call frame setup. @@ -276,9 +280,9 @@ /// found. MachineBasicBlock::iterator PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI, - LiveIndex LastIdx, + SlotIndex LastIdx, SmallPtrSet &RefsInMBB, - LiveIndex &RestoreIndex) { + SlotIndex &RestoreIndex) { // FIXME: Allow spill to be inserted to the beginning of the mbb. Update mbb // begin index accordingly. MachineBasicBlock::iterator Pt = MBB->end(); @@ -299,10 +303,10 @@ // FIXME: Limit the number of instructions to examine to reduce // compile time? while (MII != EndPt) { - LiveIndex Index = LIs->getInstructionIndex(MII); + SlotIndex Index = LIs->getInstructionIndex(MII); if (Index > LastIdx) break; - LiveIndex Gap = LIs->findGapBeforeInstr(Index); + SlotIndex Gap = LIs->findGapBeforeInstr(Index); // We can't insert a restore between the barrier (a call) and its // corresponding call frame teardown. @@ -311,7 +315,7 @@ if (MII == EndPt || RefsInMBB.count(MII)) return Pt; ++MII; } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode()); - } else if (Gap != LiveIndex()) { + } else if (Gap != SlotIndex()) { Pt = MII; RestoreIndex = Gap; } @@ -344,7 +348,7 @@ if (CurrSLI->hasAtLeastOneValue()) CurrSValNo = CurrSLI->getValNumInfo(0); else - CurrSValNo = CurrSLI->getNextValue(LiveIndex(), 0, false, + CurrSValNo = CurrSLI->getNextValue(SlotIndex(), 0, false, LSs->getVNInfoAllocator()); return SS; } @@ -353,9 +357,9 @@ /// slot at the specified index. bool PreAllocSplitting::IsAvailableInStack(MachineBasicBlock *DefMBB, - unsigned Reg, LiveIndex DefIndex, - LiveIndex RestoreIndex, - LiveIndex &SpillIndex, + unsigned Reg, SlotIndex DefIndex, + SlotIndex RestoreIndex, + SlotIndex &SpillIndex, int& SS) const { if (!DefMBB) return false; @@ -363,7 +367,7 @@ DenseMap::iterator I = IntervalSSMap.find(Reg); if (I == IntervalSSMap.end()) return false; - DenseMap::iterator + DenseMap::iterator II = Def2SpillMap.find(DefIndex); if (II == Def2SpillMap.end()) return false; @@ -384,8 +388,8 @@ /// interval being split, and the spill and restore indicies, update the live /// interval of the spill stack slot. void -PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, LiveIndex SpillIndex, - LiveIndex RestoreIndex) { +PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, SlotIndex SpillIndex, + SlotIndex RestoreIndex) { assert(LIs->getMBBFromIndex(RestoreIndex) == BarrierMBB && "Expect restore in the barrier mbb"); @@ -398,8 +402,8 @@ } SmallPtrSet Processed; - LiveIndex EndIdx = LIs->getMBBEndIdx(MBB); - LiveRange SLR(SpillIndex, LIs->getNextSlot(EndIdx), CurrSValNo); + SlotIndex EndIdx = LIs->getMBBEndIdx(MBB); + LiveRange SLR(SpillIndex, EndIdx.getNextSlot(), CurrSValNo); CurrSLI->addRange(SLR); Processed.insert(MBB); @@ -418,7 +422,7 @@ WorkList.pop_back(); if (Processed.count(MBB)) continue; - LiveIndex Idx = LIs->getMBBStartIdx(MBB); + SlotIndex Idx = LIs->getMBBStartIdx(MBB); LR = CurrLI->getLiveRangeContaining(Idx); if (LR && LR->valno == ValNo) { EndIdx = LIs->getMBBEndIdx(MBB); @@ -428,7 +432,7 @@ CurrSLI->addRange(SLR); } else if (LR->end > EndIdx) { // Live range extends beyond end of mbb, process successors. - LiveRange SLR(Idx, LIs->getNextIndex(EndIdx), CurrSValNo); + LiveRange SLR(Idx, EndIdx.getNextIndex(), CurrSValNo); CurrSLI->addRange(SLR); for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), SE = MBB->succ_end(); SI != SE; ++SI) @@ -491,12 +495,12 @@ } // Once we've found it, extend its VNInfo to our instruction. - LiveIndex DefIndex = LIs->getInstructionIndex(Walker); - DefIndex = LIs->getDefIndex(DefIndex); - LiveIndex EndIndex = LIs->getMBBEndIdx(MBB); + SlotIndex DefIndex = LIs->getInstructionIndex(Walker); + DefIndex = DefIndex.getDefIndex(); + SlotIndex EndIndex = LIs->getMBBEndIdx(MBB); RetVNI = NewVNs[Walker]; - LI->addRange(LiveRange(DefIndex, LIs->getNextSlot(EndIndex), RetVNI)); + LI->addRange(LiveRange(DefIndex, EndIndex.getNextSlot(), RetVNI)); } else if (!ContainsDefs && ContainsUses) { SmallPtrSet& BlockUses = Uses[MBB]; @@ -528,12 +532,12 @@ IsTopLevel, IsIntraBlock); } - LiveIndex UseIndex = LIs->getInstructionIndex(Walker); - UseIndex = LIs->getUseIndex(UseIndex); - LiveIndex EndIndex; + SlotIndex UseIndex = LIs->getInstructionIndex(Walker); + UseIndex = UseIndex.getUseIndex(); + SlotIndex EndIndex; if (IsIntraBlock) { EndIndex = LIs->getInstructionIndex(UseI); - EndIndex = LIs->getUseIndex(EndIndex); + EndIndex = EndIndex.getUseIndex(); } else EndIndex = LIs->getMBBEndIdx(MBB); @@ -542,7 +546,7 @@ RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); - LI->addRange(LiveRange(UseIndex, LIs->getNextSlot(EndIndex), RetVNI)); + LI->addRange(LiveRange(UseIndex, EndIndex.getNextSlot(), RetVNI)); // FIXME: Need to set kills properly for inter-block stuff. if (RetVNI->isKill(UseIndex)) RetVNI->removeKill(UseIndex); @@ -588,13 +592,12 @@ IsTopLevel, IsIntraBlock); } - LiveIndex StartIndex = LIs->getInstructionIndex(Walker); - StartIndex = foundDef ? LIs->getDefIndex(StartIndex) : - LIs->getUseIndex(StartIndex); - LiveIndex EndIndex; + SlotIndex StartIndex = LIs->getInstructionIndex(Walker); + StartIndex = foundDef ? StartIndex.getDefIndex() : StartIndex.getUseIndex(); + SlotIndex EndIndex; if (IsIntraBlock) { EndIndex = LIs->getInstructionIndex(UseI); - EndIndex = LIs->getUseIndex(EndIndex); + EndIndex = EndIndex.getUseIndex(); } else EndIndex = LIs->getMBBEndIdx(MBB); @@ -604,7 +607,7 @@ RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); - LI->addRange(LiveRange(StartIndex, LIs->getNextSlot(EndIndex), RetVNI)); + LI->addRange(LiveRange(StartIndex, EndIndex.getNextSlot(), RetVNI)); if (foundUse && RetVNI->isKill(StartIndex)) RetVNI->removeKill(StartIndex); @@ -640,9 +643,9 @@ // assume that we are not intrablock here. if (Phis.count(MBB)) return Phis[MBB]; - LiveIndex StartIndex = LIs->getMBBStartIdx(MBB); + SlotIndex StartIndex = LIs->getMBBStartIdx(MBB); VNInfo *RetVNI = Phis[MBB] = - LI->getNextValue(LiveIndex(), /*FIXME*/ 0, false, + LI->getNextValue(SlotIndex(), /*FIXME*/ 0, false, LIs->getVNInfoAllocator()); if (!IsIntraBlock) LiveOut[MBB] = RetVNI; @@ -685,19 +688,19 @@ for (DenseMap::iterator I = IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) { I->second->setHasPHIKill(true); - LiveIndex KillIndex = LIs->getMBBEndIdx(I->first); + SlotIndex KillIndex = LIs->getMBBEndIdx(I->first); if (!I->second->isKill(KillIndex)) I->second->addKill(KillIndex); } } - LiveIndex EndIndex; + SlotIndex EndIndex; if (IsIntraBlock) { EndIndex = LIs->getInstructionIndex(UseI); - EndIndex = LIs->getUseIndex(EndIndex); + EndIndex = EndIndex.getUseIndex(); } else EndIndex = LIs->getMBBEndIdx(MBB); - LI->addRange(LiveRange(StartIndex, LIs->getNextSlot(EndIndex), RetVNI)); + LI->addRange(LiveRange(StartIndex, EndIndex.getNextSlot(), RetVNI)); if (IsIntraBlock) RetVNI->addKill(EndIndex); @@ -733,8 +736,8 @@ DE = MRI->def_end(); DI != DE; ++DI) { Defs[(*DI).getParent()].insert(&*DI); - LiveIndex DefIdx = LIs->getInstructionIndex(&*DI); - DefIdx = LIs->getDefIndex(DefIdx); + SlotIndex DefIdx = LIs->getInstructionIndex(&*DI); + DefIdx = DefIdx.getDefIndex(); assert(DI->getOpcode() != TargetInstrInfo::PHI && "Following NewVN isPHIDef flag incorrect. Fix me!"); @@ -769,13 +772,13 @@ // Add ranges for dead defs for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(LI->reg), DE = MRI->def_end(); DI != DE; ++DI) { - LiveIndex DefIdx = LIs->getInstructionIndex(&*DI); - DefIdx = LIs->getDefIndex(DefIdx); + SlotIndex DefIdx = LIs->getInstructionIndex(&*DI); + DefIdx = DefIdx.getDefIndex(); if (LI->liveAt(DefIdx)) continue; VNInfo* DeadVN = NewVNs[&*DI]; - LI->addRange(LiveRange(DefIdx, LIs->getNextSlot(DefIdx), DeadVN)); + LI->addRange(LiveRange(DefIdx, DefIdx.getNextSlot(), DeadVN)); DeadVN->addKill(DefIdx); } @@ -784,8 +787,8 @@ VI != VE; ++VI) { VNInfo* VNI = *VI; for (unsigned i = 0, e = VNI->kills.size(); i != e; ++i) { - LiveIndex KillIdx = VNI->kills[i]; - if (KillIdx.isPHIIndex()) + SlotIndex KillIdx = VNI->kills[i]; + if (KillIdx.isPHI()) continue; MachineInstr *KillMI = LIs->getInstructionFromIndex(KillIdx); if (KillMI) { @@ -826,14 +829,14 @@ // Locate two-address redefinitions for (VNInfo::KillSet::iterator KI = OldVN->kills.begin(), KE = OldVN->kills.end(); KI != KE; ++KI) { - assert(!KI->isPHIIndex() && + assert(!KI->isPHI() && "VN previously reported having no PHI kills."); MachineInstr* MI = LIs->getInstructionFromIndex(*KI); unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg); if (DefIdx == ~0U) continue; if (MI->isRegTiedToUseOperand(DefIdx)) { VNInfo* NextVN = - CurrLI->findDefinedVNInfoForRegInt(LIs->getDefIndex(*KI)); + CurrLI->findDefinedVNInfoForRegInt(KI->getDefIndex()); if (NextVN == OldVN) continue; Stack.push_back(NextVN); } @@ -865,10 +868,10 @@ for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(CurrLI->reg), E = MRI->reg_end(); I != E; ++I) { MachineOperand& MO = I.getOperand(); - LiveIndex InstrIdx = LIs->getInstructionIndex(&*I); + SlotIndex InstrIdx = LIs->getInstructionIndex(&*I); - if ((MO.isUse() && NewLI.liveAt(LIs->getUseIndex(InstrIdx))) || - (MO.isDef() && NewLI.liveAt(LIs->getDefIndex(InstrIdx)))) + if ((MO.isUse() && NewLI.liveAt(InstrIdx.getUseIndex())) || + (MO.isDef() && NewLI.liveAt(InstrIdx.getDefIndex()))) OpsToChange.push_back(std::make_pair(&*I, I.getOperandNo())); } @@ -893,12 +896,12 @@ bool PreAllocSplitting::Rematerialize(unsigned VReg, VNInfo* ValNo, MachineInstr* DefMI, MachineBasicBlock::iterator RestorePt, - LiveIndex RestoreIdx, + SlotIndex RestoreIdx, SmallPtrSet& RefsInMBB) { MachineBasicBlock& MBB = *RestorePt->getParent(); MachineBasicBlock::iterator KillPt = BarrierMBB->end(); - LiveIndex KillIdx; + SlotIndex KillIdx; if (!ValNo->isDefAccurate() || DefMI->getParent() == BarrierMBB) KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, KillIdx); else @@ -911,8 +914,8 @@ LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); ReconstructLiveInterval(CurrLI); - LiveIndex RematIdx = LIs->getInstructionIndex(prior(RestorePt)); - RematIdx = LIs->getDefIndex(RematIdx); + SlotIndex RematIdx = LIs->getInstructionIndex(prior(RestorePt)); + RematIdx = RematIdx.getDefIndex(); RenumberValno(CurrLI->findDefinedVNInfoForRegInt(RematIdx)); ++NumSplits; @@ -968,7 +971,7 @@ if (CurrSLI->hasAtLeastOneValue()) CurrSValNo = CurrSLI->getValNumInfo(0); else - CurrSValNo = CurrSLI->getNextValue(LiveIndex(), 0, false, + CurrSValNo = CurrSLI->getNextValue(SlotIndex(), 0, false, LSs->getVNInfoAllocator()); } @@ -1052,11 +1055,14 @@ /// so it would not cross the barrier that's being processed. Shrink wrap /// (minimize) the live interval to the last uses. bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { + DEBUG(errs() << "Pre-alloc splitting " << LI->reg << " for " << *Barrier + << " result: "); + CurrLI = LI; // Find live range where current interval cross the barrier. LiveInterval::iterator LR = - CurrLI->FindLiveRangeContaining(LIs->getUseIndex(BarrierIdx)); + CurrLI->FindLiveRangeContaining(BarrierIdx.getUseIndex()); VNInfo *ValNo = LR->valno; assert(!ValNo->isUnused() && "Val# is defined by a dead def?"); @@ -1065,8 +1071,10 @@ ? LIs->getInstructionFromIndex(ValNo->def) : NULL; // If this would create a new join point, do not split. - if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier->getParent())) + if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier->getParent())) { + DEBUG(errs() << "FAILED (would create a new join point).\n"); return false; + } // Find all references in the barrier mbb. SmallPtrSet RefsInMBB; @@ -1078,21 +1086,25 @@ } // Find a point to restore the value after the barrier. - LiveIndex RestoreIndex; + SlotIndex RestoreIndex; MachineBasicBlock::iterator RestorePt = findRestorePoint(BarrierMBB, Barrier, LR->end, RefsInMBB, RestoreIndex); - if (RestorePt == BarrierMBB->end()) + if (RestorePt == BarrierMBB->end()) { + DEBUG(errs() << "FAILED (could not find a suitable restore point).\n"); return false; + } if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI)) if (Rematerialize(LI->reg, ValNo, DefMI, RestorePt, - RestoreIndex, RefsInMBB)) - return true; + RestoreIndex, RefsInMBB)) { + DEBUG(errs() << "success (remat).\n"); + return true; + } // Add a spill either before the barrier or after the definition. MachineBasicBlock *DefMBB = DefMI ? DefMI->getParent() : NULL; const TargetRegisterClass *RC = MRI->getRegClass(CurrLI->reg); - LiveIndex SpillIndex; + SlotIndex SpillIndex; MachineInstr *SpillMI = NULL; int SS = -1; if (!ValNo->isDefAccurate()) { @@ -1103,8 +1115,10 @@ } else { MachineBasicBlock::iterator SpillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, SpillIndex); - if (SpillPt == BarrierMBB->begin()) + if (SpillPt == BarrierMBB->begin()) { + DEBUG(errs() << "FAILED (could not find a suitable spill point).\n"); return false; // No gap to insert spill. + } // Add spill. SS = CreateSpillStackSlot(CurrLI->reg, RC); @@ -1116,8 +1130,10 @@ RestoreIndex, SpillIndex, SS)) { // If it's already split, just restore the value. There is no need to spill // the def again. - if (!DefMI) + if (!DefMI) { + DEBUG(errs() << "FAILED (def is dead).\n"); return false; // Def is dead. Do nothing. + } if ((SpillMI = FoldSpill(LI->reg, RC, DefMI, Barrier, BarrierMBB, SS, RefsInMBB))) { @@ -1129,12 +1145,16 @@ // Add spill after the def and the last use before the barrier. SpillPt = findSpillPoint(BarrierMBB, Barrier, DefMI, RefsInMBB, SpillIndex); - if (SpillPt == DefMBB->begin()) + if (SpillPt == DefMBB->begin()) { + DEBUG(errs() << "FAILED (could not find a suitable spill point).\n"); return false; // No gap to insert spill. + } } else { SpillPt = findNextEmptySlot(DefMBB, DefMI, SpillIndex); - if (SpillPt == DefMBB->end()) + if (SpillPt == DefMBB->end()) { + DEBUG(errs() << "FAILED (could not find a suitable spill point).\n"); return false; // No gap to insert spill. + } } // Add spill. SS = CreateSpillStackSlot(CurrLI->reg, RC); @@ -1162,18 +1182,19 @@ } // Update spill stack slot live interval. - UpdateSpillSlotInterval(ValNo, LIs->getNextSlot(LIs->getUseIndex(SpillIndex)), - LIs->getDefIndex(RestoreIndex)); + UpdateSpillSlotInterval(ValNo, SpillIndex.getUseIndex().getNextSlot(), + RestoreIndex.getDefIndex()); ReconstructLiveInterval(CurrLI); if (!FoldedRestore) { - LiveIndex RestoreIdx = LIs->getInstructionIndex(prior(RestorePt)); - RestoreIdx = LIs->getDefIndex(RestoreIdx); + SlotIndex RestoreIdx = LIs->getInstructionIndex(prior(RestorePt)); + RestoreIdx = RestoreIdx.getDefIndex(); RenumberValno(CurrLI->findDefinedVNInfoForRegInt(RestoreIdx)); } ++NumSplits; + DEBUG(errs() << "success.\n"); return true; } @@ -1254,8 +1275,8 @@ // reaching definition (VNInfo). for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg), UE = MRI->use_end(); UI != UE; ++UI) { - LiveIndex index = LIs->getInstructionIndex(&*UI); - index = LIs->getUseIndex(index); + SlotIndex index = LIs->getInstructionIndex(&*UI); + index = index.getUseIndex(); const LiveRange* LR = (*LI)->getLiveRangeContaining(index); VNUseCount[LR->valno].insert(&*UI); @@ -1404,7 +1425,7 @@ if (LR->valno->hasPHIKill()) return false; - LiveIndex MBBEnd = LIs->getMBBEndIdx(BarrierMBB); + SlotIndex MBBEnd = LIs->getMBBEndIdx(BarrierMBB); if (LR->end < MBBEnd) return false; @@ -1467,6 +1488,7 @@ TII = TM->getInstrInfo(); MFI = MF.getFrameInfo(); MRI = &MF.getRegInfo(); + SIs = &getAnalysis(); LIs = &getAnalysis(); LSs = &getAnalysis(); VRM = &getAnalysis(); Added: llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp?rev=85979&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp (added) +++ llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp Tue Nov 3 17:52:08 2009 @@ -0,0 +1,231 @@ +//===---------------------- ProcessImplicitDefs.cpp -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "processimplicitdefs" + +#include "llvm/CodeGen/ProcessImplicitDefs.h" + +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/Debug.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" + + +using namespace llvm; + +char ProcessImplicitDefs::ID = 0; +static RegisterPass X("processimpdefs", + "Process Implicit Definitions."); + +void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + AU.addPreserved(); + AU.addPreserved(); + AU.addRequired(); + AU.addPreservedID(MachineLoopInfoID); + AU.addPreservedID(MachineDominatorsID); + AU.addPreservedID(TwoAddressInstructionPassID); + AU.addPreservedID(PHIEliminationID); + MachineFunctionPass::getAnalysisUsage(AU); +} + +bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, + unsigned Reg, unsigned OpIdx, + const TargetInstrInfo *tii_) { + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && + Reg == SrcReg) + return true; + + if (OpIdx == 2 && MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) + return true; + if (OpIdx == 1 && MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) + return true; + return false; +} + +/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure +/// there is one implicit_def for each use. Add isUndef marker to +/// implicit_def defs and their uses. +bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { + + DEBUG(errs() << "********** PROCESS IMPLICIT DEFS **********\n" + << "********** Function: " + << ((Value*)fn.getFunction())->getName() << '\n'); + + bool Changed = false; + + const TargetInstrInfo *tii_ = fn.getTarget().getInstrInfo(); + const TargetRegisterInfo *tri_ = fn.getTarget().getRegisterInfo(); + MachineRegisterInfo *mri_ = &fn.getRegInfo(); + + LiveVariables *lv_ = &getAnalysis(); + + SmallSet ImpDefRegs; + SmallVector ImpDefMIs; + MachineBasicBlock *Entry = fn.begin(); + SmallPtrSet Visited; + + for (df_ext_iterator > + DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); + DFI != E; ++DFI) { + MachineBasicBlock *MBB = *DFI; + for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); + I != E; ) { + MachineInstr *MI = &*I; + ++I; + if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) { + unsigned Reg = MI->getOperand(0).getReg(); + ImpDefRegs.insert(Reg); + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { + for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS) + ImpDefRegs.insert(*SS); + } + ImpDefMIs.push_back(MI); + continue; + } + + if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { + MachineOperand &MO = MI->getOperand(2); + if (ImpDefRegs.count(MO.getReg())) { + // %reg1032 = INSERT_SUBREG %reg1032, undef, 2 + // This is an identity copy, eliminate it now. + if (MO.isKill()) { + LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); + vi.removeKill(MI); + } + MI->eraseFromParent(); + Changed = true; + continue; + } + } + + bool ChangedToImpDef = false; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand& MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isUse() || MO.isUndef()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (!ImpDefRegs.count(Reg)) + continue; + // Use is a copy, just turn it into an implicit_def. + if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) { + bool isKill = MO.isKill(); + MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); + for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) + MI->RemoveOperand(j); + if (isKill) { + ImpDefRegs.erase(Reg); + LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); + vi.removeKill(MI); + } + ChangedToImpDef = true; + Changed = true; + break; + } + + Changed = true; + MO.setIsUndef(); + if (MO.isKill() || MI->isRegTiedToDefOperand(i)) { + // Make sure other uses of + for (unsigned j = i+1; j != e; ++j) { + MachineOperand &MOJ = MI->getOperand(j); + if (MOJ.isReg() && MOJ.isUse() && MOJ.getReg() == Reg) + MOJ.setIsUndef(); + } + ImpDefRegs.erase(Reg); + } + } + + if (ChangedToImpDef) { + // Backtrack to process this new implicit_def. + --I; + } else { + for (unsigned i = 0; i != MI->getNumOperands(); ++i) { + MachineOperand& MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) + continue; + ImpDefRegs.erase(MO.getReg()); + } + } + } + + // Any outstanding liveout implicit_def's? + for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) { + MachineInstr *MI = ImpDefMIs[i]; + unsigned Reg = MI->getOperand(0).getReg(); + if (TargetRegisterInfo::isPhysicalRegister(Reg) || + !ImpDefRegs.count(Reg)) { + // Delete all "local" implicit_def's. That include those which define + // physical registers since they cannot be liveout. + MI->eraseFromParent(); + Changed = true; + continue; + } + + // If there are multiple defs of the same register and at least one + // is not an implicit_def, do not insert implicit_def's before the + // uses. + bool Skip = false; + for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg), + DE = mri_->def_end(); DI != DE; ++DI) { + if (DI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) { + Skip = true; + break; + } + } + if (Skip) + continue; + + // The only implicit_def which we want to keep are those that are live + // out of its block. + MI->eraseFromParent(); + Changed = true; + + for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), + UE = mri_->use_end(); UI != UE; ) { + MachineOperand &RMO = UI.getOperand(); + MachineInstr *RMI = &*UI; + ++UI; + MachineBasicBlock *RMBB = RMI->getParent(); + if (RMBB == MBB) + continue; + + // Turn a copy use into an implicit_def. + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && + Reg == SrcReg) { + RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); + for (int j = RMI->getNumOperands() - 1, ee = 0; j > ee; --j) + RMI->RemoveOperand(j); + continue; + } + + const TargetRegisterClass* RC = mri_->getRegClass(Reg); + unsigned NewVReg = mri_->createVirtualRegister(RC); + RMO.setReg(NewVReg); + RMO.setIsUndef(); + RMO.setIsKill(); + } + } + ImpDefRegs.clear(); + ImpDefMIs.clear(); + } + + return Changed; +} + Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Tue Nov 3 17:52:08 2009 @@ -145,6 +145,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); + AU.addPreserved(); if (StrongPHIElim) AU.addRequiredID(StrongPHIEliminationID); // Make sure PassManager knows which analyses to make available @@ -175,11 +176,11 @@ /// processActiveIntervals - expire old intervals and move non-overlapping /// ones to the inactive list. - void processActiveIntervals(LiveIndex CurPoint); + void processActiveIntervals(SlotIndex CurPoint); /// processInactiveIntervals - expire old intervals and move overlapping /// ones to the active list. - void processInactiveIntervals(LiveIndex CurPoint); + void processInactiveIntervals(SlotIndex CurPoint); /// hasNextReloadInterval - Return the next liveinterval that's being /// defined by a reload from the same SS as the specified one. @@ -365,7 +366,7 @@ return Reg; VNInfo *vni = cur.begin()->valno; - if ((vni->def == LiveIndex()) || + if ((vni->def == SlotIndex()) || vni->isUnused() || !vni->isDefAccurate()) return Reg; MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def); @@ -402,7 +403,7 @@ if (!O.isKill()) continue; MachineInstr *MI = &*I; - if (SrcLI.liveAt(li_->getDefIndex(li_->getInstructionIndex(MI)))) + if (SrcLI.liveAt(li_->getInstructionIndex(MI).getDefIndex())) O.setIsKill(false); } } @@ -479,10 +480,17 @@ for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) { if (TargetRegisterInfo::isPhysicalRegister(i->second->reg)) { - mri_->setPhysRegUsed(i->second->reg); - fixed_.push_back(std::make_pair(i->second, i->second->begin())); - } else - unhandled_.push(i->second); + if (!i->second->empty()) { + mri_->setPhysRegUsed(i->second->reg); + fixed_.push_back(std::make_pair(i->second, i->second->begin())); + } + } else { + if (i->second->empty()) { + assignRegOrStackSlotAtInterval(i->second); + } + else + unhandled_.push(i->second); + } } } @@ -502,13 +510,13 @@ ++NumIters; DEBUG(errs() << "\n*** CURRENT ***: " << *cur << '\n'); - if (!cur->empty()) { - processActiveIntervals(cur->beginIndex()); - processInactiveIntervals(cur->beginIndex()); + assert(!cur->empty() && "Empty interval in unhandled set."); - assert(TargetRegisterInfo::isVirtualRegister(cur->reg) && - "Can only allocate virtual registers!"); - } + processActiveIntervals(cur->beginIndex()); + processInactiveIntervals(cur->beginIndex()); + + assert(TargetRegisterInfo::isVirtualRegister(cur->reg) && + "Can only allocate virtual registers!"); // Allocating a virtual register. try to find a free // physical register or spill an interval (possibly this one) in order to @@ -585,7 +593,7 @@ /// processActiveIntervals - expire old intervals and move non-overlapping ones /// to the inactive list. -void RALinScan::processActiveIntervals(LiveIndex CurPoint) +void RALinScan::processActiveIntervals(SlotIndex CurPoint) { DEBUG(errs() << "\tprocessing active intervals:\n"); @@ -631,7 +639,7 @@ /// processInactiveIntervals - expire old intervals and move overlapping /// ones to the active list. -void RALinScan::processInactiveIntervals(LiveIndex CurPoint) +void RALinScan::processInactiveIntervals(SlotIndex CurPoint) { DEBUG(errs() << "\tprocessing inactive intervals:\n"); @@ -712,7 +720,7 @@ return IP.end(); } -static void RevertVectorIteratorsTo(RALinScan::IntervalPtrs &V, LiveIndex Point){ +static void RevertVectorIteratorsTo(RALinScan::IntervalPtrs &V, SlotIndex Point){ for (unsigned i = 0, e = V.size(); i != e; ++i) { RALinScan::IntervalPtr &IP = V[i]; LiveInterval::iterator I = std::upper_bound(IP.first->begin(), @@ -738,7 +746,7 @@ if (SI.hasAtLeastOneValue()) VNI = SI.getValNumInfo(0); else - VNI = SI.getNextValue(LiveIndex(), 0, false, + VNI = SI.getNextValue(SlotIndex(), 0, false, ls_->getVNInfoAllocator()); LiveInterval &RI = li_->getInterval(cur->reg); @@ -906,7 +914,7 @@ backUpRegUses(); std::vector > SpillWeightsToAdd; - LiveIndex StartPosition = cur->beginIndex(); + SlotIndex StartPosition = cur->beginIndex(); const TargetRegisterClass *RCLeader = RelatedRegClasses.getLeaderValue(RC); // If start of this live interval is defined by a move instruction and its @@ -916,7 +924,7 @@ // one, e.g. X86::mov32to32_. These move instructions are not coalescable. if (!vrm_->getRegAllocPref(cur->reg) && cur->hasAtLeastOneValue()) { VNInfo *vni = cur->begin()->valno; - if ((vni->def != LiveIndex()) && !vni->isUnused() && + if ((vni->def != SlotIndex()) && !vni->isUnused() && vni->isDefAccurate()) { MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def); unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; @@ -1118,6 +1126,7 @@ DowngradedRegs.clear(); assignRegOrStackSlotAtInterval(cur); } else { + assert(false && "Ran out of registers during register allocation!"); llvm_report_error("Ran out of registers during register allocation!"); } return; @@ -1172,7 +1181,7 @@ LiveInterval *ReloadLi = added[i]; if (ReloadLi->weight == HUGE_VALF && li_->getApproximateInstructionCount(*ReloadLi) == 0) { - LiveIndex ReloadIdx = ReloadLi->beginIndex(); + SlotIndex ReloadIdx = ReloadLi->beginIndex(); MachineBasicBlock *ReloadMBB = li_->getMBBFromIndex(ReloadIdx); int ReloadSS = vrm_->getStackSlot(ReloadLi->reg); if (LastReloadMBB == ReloadMBB && LastReloadSS == ReloadSS) { @@ -1242,7 +1251,7 @@ spilled.insert(sli->reg); } - LiveIndex earliestStart = earliestStartInterval->beginIndex(); + SlotIndex earliestStart = earliestStartInterval->beginIndex(); DEBUG(errs() << "\t\trolling back to: " << earliestStart << '\n'); @@ -1323,7 +1332,7 @@ LiveInterval *ReloadLi = added[i]; if (ReloadLi->weight == HUGE_VALF && li_->getApproximateInstructionCount(*ReloadLi) == 0) { - LiveIndex ReloadIdx = ReloadLi->beginIndex(); + SlotIndex ReloadIdx = ReloadLi->beginIndex(); MachineBasicBlock *ReloadMBB = li_->getMBBFromIndex(ReloadIdx); int ReloadSS = vrm_->getStackSlot(ReloadLi->reg); if (LastReloadMBB == ReloadMBB && LastReloadSS == ReloadSS) { Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Tue Nov 3 17:52:08 2009 @@ -85,6 +85,8 @@ /// PBQP analysis usage. virtual void getAnalysisUsage(AnalysisUsage &au) const { + au.addRequired(); + au.addPreserved(); au.addRequired(); //au.addRequiredID(SplitCriticalEdgesID); au.addRequired(); @@ -684,7 +686,7 @@ vni = stackInterval.getValNumInfo(0); else vni = stackInterval.getNextValue( - LiveIndex(), 0, false, lss->getVNInfoAllocator()); + SlotIndex(), 0, false, lss->getVNInfoAllocator()); LiveInterval &rhsInterval = lis->getInterval(spilled->reg); stackInterval.MergeRangesInAsValue(rhsInterval, vni); @@ -832,7 +834,7 @@ tm = &mf->getTarget(); tri = tm->getRegisterInfo(); tii = tm->getInstrInfo(); - mri = &mf->getRegInfo(); + mri = &mf->getRegInfo(); lis = &getAnalysis(); lss = &getAnalysis(); Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Tue Nov 3 17:52:08 2009 @@ -76,6 +76,7 @@ AU.addRequired(); AU.addRequired(); AU.addPreserved(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addPreservedID(MachineDominatorsID); @@ -105,7 +106,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB, MachineInstr *CopyMI) { - LiveIndex CopyIdx = li_->getDefIndex(li_->getInstructionIndex(CopyMI)); + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getDefIndex(); // BValNo is a value number in B that is defined by a copy from A. 'B3' in // the example above. @@ -120,7 +121,7 @@ assert(BValNo->def == CopyIdx && "Copy doesn't define the value?"); // AValNo is the value number in A that defines the copy, A3 in the example. - LiveIndex CopyUseIdx = li_->getUseIndex(CopyIdx); + SlotIndex CopyUseIdx = CopyIdx.getUseIndex(); LiveInterval::iterator ALR = IntA.FindLiveRangeContaining(CopyUseIdx); assert(ALR != IntA.end() && "Live range not found!"); VNInfo *AValNo = ALR->valno; @@ -158,13 +159,13 @@ // Get the LiveRange in IntB that this value number starts with. LiveInterval::iterator ValLR = - IntB.FindLiveRangeContaining(li_->getPrevSlot(AValNo->def)); + IntB.FindLiveRangeContaining(AValNo->def.getPrevSlot()); assert(ValLR != IntB.end() && "Live range not found!"); // Make sure that the end of the live range is inside the same block as // CopyMI. MachineInstr *ValLREndInst = - li_->getInstructionFromIndex(li_->getPrevSlot(ValLR->end)); + li_->getInstructionFromIndex(ValLR->end.getPrevSlot()); if (!ValLREndInst || ValLREndInst->getParent() != CopyMI->getParent()) return false; @@ -193,7 +194,7 @@ IntB.print(errs(), tri_); }); - LiveIndex FillerStart = ValLR->end, FillerEnd = BLR->start; + SlotIndex FillerStart = ValLR->end, FillerEnd = BLR->start; // We are about to delete CopyMI, so need to remove it as the 'instruction // that defines this value #'. Update the the valnum with the new defining // instruction #. @@ -306,8 +307,8 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, LiveInterval &IntB, MachineInstr *CopyMI) { - LiveIndex CopyIdx = - li_->getDefIndex(li_->getInstructionIndex(CopyMI)); + SlotIndex CopyIdx = + li_->getInstructionIndex(CopyMI).getDefIndex(); // FIXME: For now, only eliminate the copy by commuting its def when the // source register is a virtual register. We want to guard against cases @@ -330,7 +331,7 @@ // AValNo is the value number in A that defines the copy, A3 in the example. LiveInterval::iterator ALR = - IntA.FindLiveRangeContaining(li_->getPrevSlot(CopyIdx)); + IntA.FindLiveRangeContaining(CopyIdx.getUseIndex()); // assert(ALR != IntA.end() && "Live range not found!"); VNInfo *AValNo = ALR->valno; @@ -376,7 +377,7 @@ for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg), UE = mri_->use_end(); UI != UE; ++UI) { MachineInstr *UseMI = &*UI; - LiveIndex UseIdx = li_->getInstructionIndex(UseMI); + SlotIndex UseIdx = li_->getInstructionIndex(UseMI); LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx); if (ULR == IntA.end()) continue; @@ -401,7 +402,7 @@ bool BHasPHIKill = BValNo->hasPHIKill(); SmallVector BDeadValNos; VNInfo::KillSet BKills; - std::map BExtend; + std::map BExtend; // If ALR and BLR overlaps and end of BLR extends beyond end of ALR, e.g. // A = or A, B @@ -428,7 +429,7 @@ ++UI; if (JoinedCopies.count(UseMI)) continue; - LiveIndex UseIdx= li_->getUseIndex(li_->getInstructionIndex(UseMI)); + SlotIndex UseIdx = li_->getInstructionIndex(UseMI).getUseIndex(); LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx); if (ULR == IntA.end() || ULR->valno != AValNo) continue; @@ -439,7 +440,7 @@ if (Extended) UseMO.setIsKill(false); else - BKills.push_back(li_->getNextSlot(UseIdx)); + BKills.push_back(UseIdx.getDefIndex()); } unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) @@ -448,7 +449,7 @@ // This copy will become a noop. If it's defining a new val#, // remove that val# as well. However this live range is being // extended to the end of the existing live range defined by the copy. - LiveIndex DefIdx = li_->getDefIndex(UseIdx); + SlotIndex DefIdx = UseIdx.getDefIndex(); const LiveRange *DLR = IntB.getLiveRangeContaining(DefIdx); BHasPHIKill |= DLR->valno->hasPHIKill(); assert(DLR->valno->def == DefIdx); @@ -495,8 +496,8 @@ for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end(); AI != AE; ++AI) { if (AI->valno != AValNo) continue; - LiveIndex End = AI->end; - std::map::iterator + SlotIndex End = AI->end; + std::map::iterator EI = BExtend.find(End); if (EI != BExtend.end()) End = EI->second; @@ -507,7 +508,7 @@ if (BHasSubRegs) { for (const unsigned *SR = tri_->getSubRegisters(IntB.reg); *SR; ++SR) { LiveInterval &SRLI = li_->getInterval(*SR); - SRLI.MergeInClobberRange(AI->start, End, li_->getVNInfoAllocator()); + SRLI.MergeInClobberRange(*li_, AI->start, End, li_->getVNInfoAllocator()); } } } @@ -551,7 +552,7 @@ /// from a physical register live interval as well as from the live intervals /// of its sub-registers. static void removeRange(LiveInterval &li, - LiveIndex Start, LiveIndex End, + SlotIndex Start, SlotIndex End, LiveIntervals *li_, const TargetRegisterInfo *tri_) { li.removeRange(Start, End, true); if (TargetRegisterInfo::isPhysicalRegister(li.reg)) { @@ -559,8 +560,9 @@ if (!li_->hasInterval(*SR)) continue; LiveInterval &sli = li_->getInterval(*SR); - LiveIndex RemoveStart = Start; - LiveIndex RemoveEnd = Start; + SlotIndex RemoveStart = Start; + SlotIndex RemoveEnd = Start; + while (RemoveEnd != End) { LiveInterval::iterator LR = sli.FindLiveRangeContaining(RemoveStart); if (LR == sli.end()) @@ -577,14 +579,14 @@ /// as the copy instruction, trim the live interval to the last use and return /// true. bool -SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(LiveIndex CopyIdx, +SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(SlotIndex CopyIdx, MachineBasicBlock *CopyMBB, LiveInterval &li, const LiveRange *LR) { - LiveIndex MBBStart = li_->getMBBStartIdx(CopyMBB); - LiveIndex LastUseIdx; + SlotIndex MBBStart = li_->getMBBStartIdx(CopyMBB); + SlotIndex LastUseIdx; MachineOperand *LastUse = - lastRegisterUse(LR->start, li_->getPrevSlot(CopyIdx), li.reg, LastUseIdx); + lastRegisterUse(LR->start, CopyIdx.getPrevSlot(), li.reg, LastUseIdx); if (LastUse) { MachineInstr *LastUseMI = LastUse->getParent(); if (!isSameOrFallThroughBB(LastUseMI->getParent(), CopyMBB, tii_)) { @@ -603,8 +605,8 @@ // There are uses before the copy, just shorten the live range to the end // of last use. LastUse->setIsKill(); - removeRange(li, li_->getDefIndex(LastUseIdx), LR->end, li_, tri_); - LR->valno->addKill(li_->getNextSlot(LastUseIdx)); + removeRange(li, LastUseIdx.getDefIndex(), LR->end, li_, tri_); + LR->valno->addKill(LastUseIdx.getDefIndex()); unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; if (tii_->isMoveInstr(*LastUseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) && DstReg == li.reg) { @@ -617,7 +619,7 @@ // Is it livein? if (LR->start <= MBBStart && LR->end > MBBStart) { - if (LR->start == LiveIndex()) { + if (LR->start == li_->getZeroIndex()) { assert(TargetRegisterInfo::isPhysicalRegister(li.reg)); // Live-in to the function but dead. Remove it from entry live-in set. mf_->begin()->removeLiveIn(li.reg); @@ -634,7 +636,7 @@ unsigned DstReg, unsigned DstSubIdx, MachineInstr *CopyMI) { - LiveIndex CopyIdx = li_->getUseIndex(li_->getInstructionIndex(CopyMI)); + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getUseIndex(); LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx); assert(SrcLR != SrcInt.end() && "Live range not found!"); VNInfo *ValNo = SrcLR->valno; @@ -683,7 +685,7 @@ return false; } - LiveIndex DefIdx = li_->getDefIndex(CopyIdx); + SlotIndex DefIdx = CopyIdx.getDefIndex(); const LiveRange *DLR= li_->getInterval(DstReg).getLiveRangeContaining(DefIdx); DLR->valno->setCopy(0); // Don't forget to update sub-register intervals. @@ -716,7 +718,7 @@ // should mark it dead: if (DefMI->getParent() == MBB) { DefMI->addRegisterDead(SrcInt.reg, tri_); - SrcLR->end = li_->getNextSlot(SrcLR->start); + SrcLR->end = SrcLR->start.getNextSlot(); } } @@ -815,8 +817,8 @@ (TargetRegisterInfo::isVirtualRegister(CopyDstReg) || allocatableRegs_[CopyDstReg])) { LiveInterval &LI = li_->getInterval(CopyDstReg); - LiveIndex DefIdx = - li_->getDefIndex(li_->getInstructionIndex(UseMI)); + SlotIndex DefIdx = + li_->getInstructionIndex(UseMI).getDefIndex(); if (const LiveRange *DLR = LI.getLiveRangeContaining(DefIdx)) { if (DLR->valno->def == DefIdx) DLR->valno->setCopy(UseMI); @@ -835,12 +837,12 @@ if (!UseMO.isKill()) continue; MachineInstr *UseMI = UseMO.getParent(); - LiveIndex UseIdx = - li_->getUseIndex(li_->getInstructionIndex(UseMI)); + SlotIndex UseIdx = + li_->getInstructionIndex(UseMI).getUseIndex(); const LiveRange *LR = LI.getLiveRangeContaining(UseIdx); if (!LR || - (!LR->valno->isKill(li_->getNextSlot(UseIdx)) && - LR->valno->def != li_->getNextSlot(UseIdx))) { + (!LR->valno->isKill(UseIdx.getDefIndex()) && + LR->valno->def != UseIdx.getDefIndex())) { // Interesting problem. After coalescing reg1027's def and kill are both // at the same point: %reg1027,0.000000e+00 = [56,814:0) 0 at 70-(814) // @@ -881,16 +883,16 @@ /// Return true if live interval is removed. bool SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li, MachineInstr *CopyMI) { - LiveIndex CopyIdx = li_->getInstructionIndex(CopyMI); + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI); LiveInterval::iterator MLR = - li.FindLiveRangeContaining(li_->getDefIndex(CopyIdx)); + li.FindLiveRangeContaining(CopyIdx.getDefIndex()); if (MLR == li.end()) return false; // Already removed by ShortenDeadCopySrcLiveRange. - LiveIndex RemoveStart = MLR->start; - LiveIndex RemoveEnd = MLR->end; - LiveIndex DefIdx = li_->getDefIndex(CopyIdx); + SlotIndex RemoveStart = MLR->start; + SlotIndex RemoveEnd = MLR->end; + SlotIndex DefIdx = CopyIdx.getDefIndex(); // Remove the liverange that's defined by this. - if (RemoveStart == DefIdx && RemoveEnd == li_->getNextSlot(DefIdx)) { + if (RemoveStart == DefIdx && RemoveEnd == DefIdx.getStoreIndex()) { removeRange(li, RemoveStart, RemoveEnd, li_, tri_); return removeIntervalIfEmpty(li, li_, tri_); } @@ -901,7 +903,7 @@ /// the val# it defines. If the live interval becomes empty, remove it as well. bool SimpleRegisterCoalescing::RemoveDeadDef(LiveInterval &li, MachineInstr *DefMI) { - LiveIndex DefIdx = li_->getDefIndex(li_->getInstructionIndex(DefMI)); + SlotIndex DefIdx = li_->getInstructionIndex(DefMI).getDefIndex(); LiveInterval::iterator MLR = li.FindLiveRangeContaining(DefIdx); if (DefIdx != MLR->valno->def) return false; @@ -912,10 +914,10 @@ /// PropagateDeadness - Propagate the dead marker to the instruction which /// defines the val#. static void PropagateDeadness(LiveInterval &li, MachineInstr *CopyMI, - LiveIndex &LRStart, LiveIntervals *li_, + SlotIndex &LRStart, LiveIntervals *li_, const TargetRegisterInfo* tri_) { MachineInstr *DefMI = - li_->getInstructionFromIndex(li_->getDefIndex(LRStart)); + li_->getInstructionFromIndex(LRStart.getDefIndex()); if (DefMI && DefMI != CopyMI) { int DeadIdx = DefMI->findRegisterDefOperandIdx(li.reg, false); if (DeadIdx != -1) @@ -923,7 +925,7 @@ else DefMI->addOperand(MachineOperand::CreateReg(li.reg, /*def*/true, /*implicit*/true, /*kill*/false, /*dead*/true)); - LRStart = li_->getNextSlot(LRStart); + LRStart = LRStart.getNextSlot(); } } @@ -934,8 +936,8 @@ bool SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li, MachineInstr *CopyMI) { - LiveIndex CopyIdx = li_->getInstructionIndex(CopyMI); - if (CopyIdx == LiveIndex()) { + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI); + if (CopyIdx == SlotIndex()) { // FIXME: special case: function live in. It can be a general case if the // first instruction index starts at > 0 value. assert(TargetRegisterInfo::isPhysicalRegister(li.reg)); @@ -948,13 +950,13 @@ } LiveInterval::iterator LR = - li.FindLiveRangeContaining(li_->getPrevSlot(CopyIdx)); + li.FindLiveRangeContaining(CopyIdx.getPrevIndex().getStoreIndex()); if (LR == li.end()) // Livein but defined by a phi. return false; - LiveIndex RemoveStart = LR->start; - LiveIndex RemoveEnd = li_->getNextSlot(li_->getDefIndex(CopyIdx)); + SlotIndex RemoveStart = LR->start; + SlotIndex RemoveEnd = CopyIdx.getStoreIndex(); if (LR->end > RemoveEnd) // More uses past this copy? Nothing to do. return false; @@ -974,7 +976,7 @@ // If the live range starts in another mbb and the copy mbb is not a fall // through mbb, then we can only cut the range from the beginning of the // copy mbb. - RemoveStart = li_->getNextSlot(li_->getMBBStartIdx(CopyMBB)); + RemoveStart = li_->getMBBStartIdx(CopyMBB).getNextIndex().getBaseIndex(); if (LR->valno->def == RemoveStart) { // If the def MI defines the val# and this copy is the only kill of the @@ -1030,14 +1032,14 @@ // If the virtual register live interval extends into a loop, turn down // aggressiveness. - LiveIndex CopyIdx = - li_->getDefIndex(li_->getInstructionIndex(CopyMI)); + SlotIndex CopyIdx = + li_->getInstructionIndex(CopyMI).getDefIndex(); const MachineLoop *L = loopInfo->getLoopFor(CopyMBB); if (!L) { // Let's see if the virtual register live interval extends into the loop. LiveInterval::iterator DLR = DstInt.FindLiveRangeContaining(CopyIdx); assert(DLR != DstInt.end() && "Live range not found!"); - DLR = DstInt.FindLiveRangeContaining(li_->getNextSlot(DLR->end)); + DLR = DstInt.FindLiveRangeContaining(DLR->end.getNextSlot()); if (DLR != DstInt.end()) { CopyMBB = li_->getMBBFromIndex(DLR->start); L = loopInfo->getLoopFor(CopyMBB); @@ -1047,7 +1049,7 @@ if (!L || Length <= Threshold) return true; - LiveIndex UseIdx = li_->getUseIndex(CopyIdx); + SlotIndex UseIdx = CopyIdx.getUseIndex(); LiveInterval::iterator SLR = SrcInt.FindLiveRangeContaining(UseIdx); MachineBasicBlock *SMBB = li_->getMBBFromIndex(SLR->start); if (loopInfo->getLoopFor(SMBB) != L) { @@ -1060,7 +1062,7 @@ if (SuccMBB == CopyMBB) continue; if (DstInt.overlaps(li_->getMBBStartIdx(SuccMBB), - li_->getNextSlot(li_->getMBBEndIdx(SuccMBB)))) + li_->getMBBEndIdx(SuccMBB).getNextIndex().getBaseIndex())) return false; } } @@ -1091,12 +1093,12 @@ // If the virtual register live interval is defined or cross a loop, turn // down aggressiveness. - LiveIndex CopyIdx = - li_->getDefIndex(li_->getInstructionIndex(CopyMI)); - LiveIndex UseIdx = li_->getUseIndex(CopyIdx); + SlotIndex CopyIdx = + li_->getInstructionIndex(CopyMI).getDefIndex(); + SlotIndex UseIdx = CopyIdx.getUseIndex(); LiveInterval::iterator SLR = SrcInt.FindLiveRangeContaining(UseIdx); assert(SLR != SrcInt.end() && "Live range not found!"); - SLR = SrcInt.FindLiveRangeContaining(li_->getPrevSlot(SLR->start)); + SLR = SrcInt.FindLiveRangeContaining(SLR->start.getPrevSlot()); if (SLR == SrcInt.end()) return true; MachineBasicBlock *SMBB = li_->getMBBFromIndex(SLR->start); @@ -1116,7 +1118,7 @@ if (PredMBB == SMBB) continue; if (SrcInt.overlaps(li_->getMBBStartIdx(PredMBB), - li_->getNextSlot(li_->getMBBEndIdx(PredMBB)))) + li_->getMBBEndIdx(PredMBB).getNextIndex().getBaseIndex())) return false; } } @@ -1705,7 +1707,7 @@ // Update the liveintervals of sub-registers. for (const unsigned *AS = tri_->getSubRegisters(DstReg); *AS; ++AS) - li_->getOrCreateInterval(*AS).MergeInClobberRanges(*ResSrcInt, + li_->getOrCreateInterval(*AS).MergeInClobberRanges(*li_, *ResSrcInt, li_->getVNInfoAllocator()); } @@ -1867,7 +1869,7 @@ /// is live at the given point. bool SimpleRegisterCoalescing::ValueLiveAt(LiveInterval::iterator LRItr, LiveInterval::iterator LREnd, - LiveIndex defPoint) const { + SlotIndex defPoint) const { for (const VNInfo *valno = LRItr->valno; (LRItr != LREnd) && (LRItr->valno == valno); ++LRItr) { if (LRItr->contains(defPoint)) @@ -2047,7 +2049,7 @@ // Update the liveintervals of sub-registers. if (TargetRegisterInfo::isPhysicalRegister(LHS.reg)) for (const unsigned *AS = tri_->getSubRegisters(LHS.reg); *AS; ++AS) - li_->getOrCreateInterval(*AS).MergeInClobberRanges(LHS, + li_->getOrCreateInterval(*AS).MergeInClobberRanges(*li_, LHS, li_->getVNInfoAllocator()); return true; @@ -2148,7 +2150,7 @@ } else { // It was defined as a copy from the LHS, find out what value # it is. RHSValNoInfo = - LHS.getLiveRangeContaining(li_->getPrevSlot(RHSValNoInfo0->def))->valno; + LHS.getLiveRangeContaining(RHSValNoInfo0->def.getPrevSlot())->valno; RHSValID = RHSValNoInfo->id; RHSVal0DefinedFromLHS = RHSValID; } @@ -2212,7 +2214,7 @@ // Figure out the value # from the RHS. LHSValsDefinedFromRHS[VNI]= - RHS.getLiveRangeContaining(li_->getPrevSlot(VNI->def))->valno; + RHS.getLiveRangeContaining(VNI->def.getPrevSlot())->valno; } // Loop over the value numbers of the RHS, seeing if any are defined from @@ -2230,7 +2232,7 @@ // Figure out the value # from the LHS. RHSValsDefinedFromLHS[VNI]= - LHS.getLiveRangeContaining(li_->getPrevSlot(VNI->def))->valno; + LHS.getLiveRangeContaining(VNI->def.getPrevSlot())->valno; } LHSValNoAssignments.resize(LHS.getNumValNums(), -1); @@ -2494,11 +2496,11 @@ /// lastRegisterUse - Returns the last use of the specific register between /// cycles Start and End or NULL if there are no uses. MachineOperand * -SimpleRegisterCoalescing::lastRegisterUse(LiveIndex Start, - LiveIndex End, +SimpleRegisterCoalescing::lastRegisterUse(SlotIndex Start, + SlotIndex End, unsigned Reg, - LiveIndex &UseIdx) const{ - UseIdx = LiveIndex(); + SlotIndex &UseIdx) const{ + UseIdx = SlotIndex(); if (TargetRegisterInfo::isVirtualRegister(Reg)) { MachineOperand *LastUse = NULL; for (MachineRegisterInfo::use_iterator I = mri_->use_begin(Reg), @@ -2510,22 +2512,24 @@ SrcReg == DstReg) // Ignore identity copies. continue; - LiveIndex Idx = li_->getInstructionIndex(UseMI); + SlotIndex Idx = li_->getInstructionIndex(UseMI); + // FIXME: Should this be Idx != UseIdx? SlotIndex() will return something + // that compares higher than any other interval. if (Idx >= Start && Idx < End && Idx >= UseIdx) { LastUse = &Use; - UseIdx = li_->getUseIndex(Idx); + UseIdx = Idx.getUseIndex(); } } return LastUse; } - LiveIndex s = Start; - LiveIndex e = li_->getBaseIndex(li_->getPrevSlot(End)); + SlotIndex s = Start; + SlotIndex e = End.getPrevSlot().getBaseIndex(); while (e >= s) { // Skip deleted instructions MachineInstr *MI = li_->getInstructionFromIndex(e); - while (e != LiveIndex() && li_->getPrevIndex(e) >= s && !MI) { - e = li_->getPrevIndex(e); + while (e != SlotIndex() && e.getPrevIndex() >= s && !MI) { + e = e.getPrevIndex(); MI = li_->getInstructionFromIndex(e); } if (e < s || MI == NULL) @@ -2539,12 +2543,12 @@ MachineOperand &Use = MI->getOperand(i); if (Use.isReg() && Use.isUse() && Use.getReg() && tri_->regsOverlap(Use.getReg(), Reg)) { - UseIdx = li_->getUseIndex(e); + UseIdx = e.getUseIndex(); return &Use; } } - e = li_->getPrevIndex(e); + e = e.getPrevIndex(); } return NULL; @@ -2568,7 +2572,7 @@ static bool isZeroLengthInterval(LiveInterval *li, LiveIntervals *li_) { for (LiveInterval::Ranges::const_iterator i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i) - if (li_->getPrevIndex(i->end) > i->start) + if (i->end.getPrevIndex() > i->start) return false; return true; } @@ -2579,7 +2583,7 @@ for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end(); mbbi != mbbe; ++mbbi) { MachineBasicBlock* MBB = mbbi; - LiveIndex MBBEnd = li_->getMBBEndIdx(MBB); + SlotIndex MBBEnd = li_->getMBBEndIdx(MBB); MachineLoop* loop = loopInfo->getLoopFor(MBB); unsigned loopDepth = loop ? loop->getLoopDepth() : 0; bool isExiting = loop ? loop->isLoopExiting(MBB) : false; @@ -2621,7 +2625,7 @@ float Weight = li_->getSpillWeight(HasDef, HasUse, loopDepth); if (HasDef && isExiting) { // Looks like this is a loop count variable update. - LiveIndex DefIdx = li_->getDefIndex(li_->getInstructionIndex(MI)); + SlotIndex DefIdx = li_->getInstructionIndex(MI).getDefIndex(); const LiveRange *DLR = li_->getInterval(Reg).getLiveRangeContaining(DefIdx); if (DLR->end > MBBEnd) Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h Tue Nov 3 17:52:08 2009 @@ -146,7 +146,7 @@ /// TrimLiveIntervalToLastUse - If there is a last use in the same basic /// block as the copy instruction, trim the ive interval to the last use /// and return true. - bool TrimLiveIntervalToLastUse(LiveIndex CopyIdx, + bool TrimLiveIntervalToLastUse(SlotIndex CopyIdx, MachineBasicBlock *CopyMBB, LiveInterval &li, const LiveRange *LR); @@ -205,7 +205,7 @@ /// iterator, or any subsequent range with the same value number, /// is live at the given point. bool ValueLiveAt(LiveInterval::iterator LRItr, LiveInterval::iterator LREnd, - LiveIndex defPoint) const; + SlotIndex defPoint) const; /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of /// the specified live interval is defined by a copy from the specified @@ -241,9 +241,8 @@ /// lastRegisterUse - Returns the last use of the specific register between /// cycles Start and End or NULL if there are no uses. - MachineOperand *lastRegisterUse(LiveIndex Start, - LiveIndex End, unsigned Reg, - LiveIndex &LastUseIdx) const; + MachineOperand *lastRegisterUse(SlotIndex Start, SlotIndex End, + unsigned Reg, SlotIndex &LastUseIdx) const; /// CalculateSpillWeights - Compute spill weights for all virtual register /// live intervals. Added: llvm/trunk/lib/CodeGen/SlotIndexes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SlotIndexes.cpp?rev=85979&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SlotIndexes.cpp (added) +++ llvm/trunk/lib/CodeGen/SlotIndexes.cpp Tue Nov 3 17:52:08 2009 @@ -0,0 +1,189 @@ +//===-- SlotIndexes.cpp - Slot Indexes Pass ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "slotindexes" + +#include "llvm/CodeGen/SlotIndexes.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +std::auto_ptr SlotIndex::emptyKeyPtr(0), + SlotIndex::tombstoneKeyPtr(0); + +char SlotIndexes::ID = 0; +static RegisterPass X("slotindexes", "Slot index numbering"); + +void SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const { + au.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(au); +} + +void SlotIndexes::releaseMemory() { + mi2iMap.clear(); + mbb2IdxMap.clear(); + idx2MBBMap.clear(); + terminatorGaps.clear(); + clearList(); +} + +bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { + + // Compute numbering as follows: + // Grab an iterator to the start of the index list. + // Iterate over all MBBs, and within each MBB all MIs, keeping the MI + // iterator in lock-step (though skipping it over indexes which have + // null pointers in the instruction field). + // At each iteration assert that the instruction pointed to in the index + // is the same one pointed to by the MI iterator. This + + // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should + // only need to be set up once after the first numbering is computed. + + mf = &fn; + initList(); + + const unsigned gap = 1; + + // Check that the list contains only the sentinal. + assert(indexListHead->getNext() == 0 && + "Index list non-empty at initial numbering?"); + assert(idx2MBBMap.empty() && + "Index -> MBB mapping non-empty at initial numbering?"); + assert(mbb2IdxMap.empty() && + "MBB -> Index mapping non-empty at initial numbering?"); + assert(mi2iMap.empty() && + "MachineInstr -> Index mapping non-empty at initial numbering?"); + + functionSize = 0; + /* + for (unsigned s = 0; s < SlotIndex::NUM; ++s) { + indexList.push_back(createEntry(0, s)); + } + + unsigned index = gap * SlotIndex::NUM; + */ + + unsigned index = 0; + + // Iterate over the the function. + for (MachineFunction::iterator mbbItr = mf->begin(), mbbEnd = mf->end(); + mbbItr != mbbEnd; ++mbbItr) { + MachineBasicBlock *mbb = &*mbbItr; + + // Insert an index for the MBB start. + push_back(createEntry(0, index)); + SlotIndex blockStartIndex(back(), SlotIndex::LOAD); + + index += gap * SlotIndex::NUM; + + for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end(); + miItr != miEnd; ++miItr) { + MachineInstr *mi = &*miItr; + + if (miItr == mbb->getFirstTerminator()) { + push_back(createEntry(0, index)); + terminatorGaps.insert( + std::make_pair(mbb, SlotIndex(back(), SlotIndex::PHI_BIT))); + index += gap * SlotIndex::NUM; + } + + // Insert a store index for the instr. + push_back(createEntry(mi, index)); + + // Save this base index in the maps. + mi2iMap.insert( + std::make_pair(mi, SlotIndex(back(), SlotIndex::LOAD))); + + ++functionSize; + + unsigned Slots = mi->getDesc().getNumDefs(); + if (Slots == 0) + Slots = 1; + + index += (Slots + 1) * gap * SlotIndex::NUM; + } + + if (mbb->getFirstTerminator() == mbb->end()) { + push_back(createEntry(0, index)); + terminatorGaps.insert( + std::make_pair(mbb, SlotIndex(back(), SlotIndex::PHI_BIT))); + index += gap * SlotIndex::NUM; + } + + SlotIndex blockEndIndex(back(), SlotIndex::STORE); + mbb2IdxMap.insert( + std::make_pair(mbb, std::make_pair(blockStartIndex, blockEndIndex))); + + idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, mbb)); + } + + // One blank instruction at the end. + push_back(createEntry(0, index)); + + // Sort the Idx2MBBMap + std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); + + DEBUG(dump()); + + // And we're done! + return false; +} + +void SlotIndexes::renumber() { + assert(false && "SlotIndexes::runmuber is not fully implemented yet."); + + // Compute numbering as follows: + // Grab an iterator to the start of the index list. + // Iterate over all MBBs, and within each MBB all MIs, keeping the MI + // iterator in lock-step (though skipping it over indexes which have + // null pointers in the instruction field). + // At each iteration assert that the instruction pointed to in the index + // is the same one pointed to by the MI iterator. This + + // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should + // only need to be set up once - when the first numbering is computed. + + assert(false && "Renumbering not supported yet."); +} + +void SlotIndexes::dump() const { + for (const IndexListEntry *itr = front(); itr != getTail(); + itr = itr->getNext()) { + errs() << itr->getIndex() << " "; + + if (itr->getInstr() != 0) { + errs() << *itr->getInstr(); + } else { + errs() << "\n"; + } + } + + for (MBB2IdxMap::iterator itr = mbb2IdxMap.begin(); + itr != mbb2IdxMap.end(); ++itr) { + errs() << "MBB " << itr->first->getNumber() << " (" << itr->first << ") - [" + << itr->second.first << ", " << itr->second.second << "]\n"; + } +} + +// Print a SlotIndex to a raw_ostream. +void SlotIndex::print(raw_ostream &os) const { + os << getIndex(); + if (isPHI()) + os << "*"; +} + +// Dump a SlotIndex to stderr. +void SlotIndex::dump() const { + print(errs()); + errs() << "\n"; +} + Modified: llvm/trunk/lib/CodeGen/Spiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Spiller.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Spiller.cpp (original) +++ llvm/trunk/lib/CodeGen/Spiller.cpp Tue Nov 3 17:52:08 2009 @@ -51,13 +51,15 @@ /// Ensures there is space before the given machine instruction, returns the /// instruction's new number. - LiveIndex makeSpaceBefore(MachineInstr *mi) { + SlotIndex makeSpaceBefore(MachineInstr *mi) { if (!lis->hasGapBeforeInstr(lis->getInstructionIndex(mi))) { - lis->scaleNumbering(2); - ls->scaleNumbering(2); + // FIXME: Should be updated to use rewrite-in-place methods when they're + // introduced. Currently broken. + //lis->scaleNumbering(2); + //ls->scaleNumbering(2); } - LiveIndex miIdx = lis->getInstructionIndex(mi); + SlotIndex miIdx = lis->getInstructionIndex(mi); assert(lis->hasGapBeforeInstr(miIdx)); @@ -66,13 +68,15 @@ /// Ensure there is space after the given machine instruction, returns the /// instruction's new number. - LiveIndex makeSpaceAfter(MachineInstr *mi) { + SlotIndex makeSpaceAfter(MachineInstr *mi) { if (!lis->hasGapAfterInstr(lis->getInstructionIndex(mi))) { - lis->scaleNumbering(2); - ls->scaleNumbering(2); + // FIXME: Should be updated to use rewrite-in-place methods when they're + // introduced. Currently broken. + // lis->scaleNumbering(2); + // ls->scaleNumbering(2); } - LiveIndex miIdx = lis->getInstructionIndex(mi); + SlotIndex miIdx = lis->getInstructionIndex(mi); assert(lis->hasGapAfterInstr(miIdx)); @@ -83,19 +87,19 @@ /// after the given instruction. Returns the base index of the inserted /// instruction. The caller is responsible for adding an appropriate /// LiveInterval to the LiveIntervals analysis. - LiveIndex insertStoreAfter(MachineInstr *mi, unsigned ss, + SlotIndex insertStoreAfter(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { MachineBasicBlock::iterator nextInstItr(next(mi)); - LiveIndex miIdx = makeSpaceAfter(mi); + SlotIndex miIdx = makeSpaceAfter(mi); tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg, true, ss, trc); MachineBasicBlock::iterator storeInstItr(next(mi)); MachineInstr *storeInst = &*storeInstItr; - LiveIndex storeInstIdx = lis->getNextIndex(miIdx); + SlotIndex storeInstIdx = miIdx.getNextIndex(); assert(lis->getInstructionFromIndex(storeInstIdx) == 0 && "Store inst index already in use."); @@ -108,15 +112,15 @@ /// Insert a store of the given vreg to the given stack slot immediately /// before the given instructnion. Returns the base index of the inserted /// Instruction. - LiveIndex insertStoreBefore(MachineInstr *mi, unsigned ss, + SlotIndex insertStoreBefore(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { - LiveIndex miIdx = makeSpaceBefore(mi); + SlotIndex miIdx = makeSpaceBefore(mi); tii->storeRegToStackSlot(*mi->getParent(), mi, vreg, true, ss, trc); MachineBasicBlock::iterator storeInstItr(prior(mi)); MachineInstr *storeInst = &*storeInstItr; - LiveIndex storeInstIdx = lis->getPrevIndex(miIdx); + SlotIndex storeInstIdx = miIdx.getPrevIndex(); assert(lis->getInstructionFromIndex(storeInstIdx) == 0 && "Store inst index already in use."); @@ -131,9 +135,9 @@ unsigned vreg, const TargetRegisterClass *trc) { - LiveIndex storeInstIdx = insertStoreAfter(mi, ss, vreg, trc); - LiveIndex start = lis->getDefIndex(lis->getInstructionIndex(mi)), - end = lis->getUseIndex(storeInstIdx); + SlotIndex storeInstIdx = insertStoreAfter(mi, ss, vreg, trc); + SlotIndex start = lis->getInstructionIndex(mi).getDefIndex(), + end = storeInstIdx.getUseIndex(); VNInfo *vni = li->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator()); @@ -149,18 +153,18 @@ /// after the given instruction. Returns the base index of the inserted /// instruction. The caller is responsibel for adding/removing an appropriate /// range vreg's LiveInterval. - LiveIndex insertLoadAfter(MachineInstr *mi, unsigned ss, + SlotIndex insertLoadAfter(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { MachineBasicBlock::iterator nextInstItr(next(mi)); - LiveIndex miIdx = makeSpaceAfter(mi); + SlotIndex miIdx = makeSpaceAfter(mi); tii->loadRegFromStackSlot(*mi->getParent(), nextInstItr, vreg, ss, trc); MachineBasicBlock::iterator loadInstItr(next(mi)); MachineInstr *loadInst = &*loadInstItr; - LiveIndex loadInstIdx = lis->getNextIndex(miIdx); + SlotIndex loadInstIdx = miIdx.getNextIndex(); assert(lis->getInstructionFromIndex(loadInstIdx) == 0 && "Store inst index already in use."); @@ -174,15 +178,15 @@ /// before the given instruction. Returns the base index of the inserted /// instruction. The caller is responsible for adding an appropriate /// LiveInterval to the LiveIntervals analysis. - LiveIndex insertLoadBefore(MachineInstr *mi, unsigned ss, + SlotIndex insertLoadBefore(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { - LiveIndex miIdx = makeSpaceBefore(mi); + SlotIndex miIdx = makeSpaceBefore(mi); tii->loadRegFromStackSlot(*mi->getParent(), mi, vreg, ss, trc); MachineBasicBlock::iterator loadInstItr(prior(mi)); MachineInstr *loadInst = &*loadInstItr; - LiveIndex loadInstIdx = lis->getPrevIndex(miIdx); + SlotIndex loadInstIdx = miIdx.getPrevIndex(); assert(lis->getInstructionFromIndex(loadInstIdx) == 0 && "Load inst index already in use."); @@ -197,9 +201,9 @@ unsigned vreg, const TargetRegisterClass *trc) { - LiveIndex loadInstIdx = insertLoadBefore(mi, ss, vreg, trc); - LiveIndex start = lis->getDefIndex(loadInstIdx), - end = lis->getUseIndex(lis->getInstructionIndex(mi)); + SlotIndex loadInstIdx = insertLoadBefore(mi, ss, vreg, trc); + SlotIndex start = loadInstIdx.getDefIndex(), + end = lis->getInstructionIndex(mi).getUseIndex(); VNInfo *vni = li->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator()); @@ -321,21 +325,21 @@ vrm->assignVirt2StackSlot(li->reg, ss); MachineInstr *mi = 0; - LiveIndex storeIdx = LiveIndex(); + SlotIndex storeIdx = SlotIndex(); if (valno->isDefAccurate()) { // If we have an accurate def we can just grab an iterator to the instr // after the def. mi = lis->getInstructionFromIndex(valno->def); - storeIdx = lis->getDefIndex(insertStoreAfter(mi, ss, li->reg, trc)); + storeIdx = insertStoreAfter(mi, ss, li->reg, trc).getDefIndex(); } else { // if we get here we have a PHI def. mi = &lis->getMBBFromIndex(valno->def)->front(); - storeIdx = lis->getDefIndex(insertStoreBefore(mi, ss, li->reg, trc)); + storeIdx = insertStoreBefore(mi, ss, li->reg, trc).getDefIndex(); } MachineBasicBlock *defBlock = mi->getParent(); - LiveIndex loadIdx = LiveIndex(); + SlotIndex loadIdx = SlotIndex(); // Now we need to find the load... MachineBasicBlock::iterator useItr(mi); @@ -343,11 +347,11 @@ if (useItr != defBlock->end()) { MachineInstr *loadInst = useItr; - loadIdx = lis->getUseIndex(insertLoadBefore(loadInst, ss, li->reg, trc)); + loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc).getUseIndex(); } else { MachineInstr *loadInst = &defBlock->back(); - loadIdx = lis->getUseIndex(insertLoadAfter(loadInst, ss, li->reg, trc)); + loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc).getUseIndex(); } li->removeRange(storeIdx, loadIdx, true); Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Tue Nov 3 17:52:08 2009 @@ -98,6 +98,8 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired(); + AU.addPreserved(); AU.addRequired(); AU.addRequired(); AU.addPreserved(); Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Nov 3 17:52:08 2009 @@ -72,6 +72,8 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); + AU.addRequired(); + AU.addPreserved(); AU.addRequired(); // TODO: Actually make this true. @@ -294,7 +296,7 @@ static bool isLiveIn(unsigned r, MachineBasicBlock* MBB, LiveIntervals& LI) { LiveInterval& I = LI.getOrCreateInterval(r); - LiveIndex idx = LI.getMBBStartIdx(MBB); + SlotIndex idx = LI.getMBBStartIdx(MBB); return I.liveAt(idx); } @@ -427,7 +429,7 @@ } LiveInterval& PI = LI.getOrCreateInterval(DestReg); - LiveIndex pIdx = LI.getDefIndex(LI.getInstructionIndex(P)); + SlotIndex pIdx = LI.getInstructionIndex(P).getDefIndex(); VNInfo* PVN = PI.getLiveRangeContaining(pIdx)->valno; PhiValueNumber.insert(std::make_pair(DestReg, PVN->id)); @@ -747,7 +749,7 @@ LiveInterval& I = LI.getInterval(curr.second); MachineBasicBlock::iterator term = MBB->getFirstTerminator(); - LiveIndex endIdx = LiveIndex(); + SlotIndex endIdx = SlotIndex(); if (term != MBB->end()) endIdx = LI.getInstructionIndex(term); else @@ -771,7 +773,7 @@ // Renumber the instructions so that we can perform the index computations // needed to create new live intervals. - LI.computeNumbering(); + LI.renumber(); // For copies that we inserted at the ends of predecessors, we construct // live intervals. This is pretty easy, since we know that the destination @@ -783,15 +785,15 @@ InsertedPHIDests.begin(), E = InsertedPHIDests.end(); I != E; ++I) { if (RegHandled.insert(I->first).second) { LiveInterval& Int = LI.getOrCreateInterval(I->first); - LiveIndex instrIdx = LI.getInstructionIndex(I->second); - if (Int.liveAt(LI.getDefIndex(instrIdx))) - Int.removeRange(LI.getDefIndex(instrIdx), - LI.getNextSlot(LI.getMBBEndIdx(I->second->getParent())), + SlotIndex instrIdx = LI.getInstructionIndex(I->second); + if (Int.liveAt(instrIdx.getDefIndex())) + Int.removeRange(instrIdx.getDefIndex(), + LI.getMBBEndIdx(I->second->getParent()).getNextSlot(), true); LiveRange R = LI.addLiveRangeToEndOfBlock(I->first, I->second); R.valno->setCopy(I->second); - R.valno->def = LI.getDefIndex(LI.getInstructionIndex(I->second)); + R.valno->def = LI.getInstructionIndex(I->second).getDefIndex(); } } } @@ -816,8 +818,8 @@ Stacks[I->getOperand(i).getReg()].size()) { // Remove the live range for the old vreg. LiveInterval& OldInt = LI.getInterval(I->getOperand(i).getReg()); - LiveInterval::iterator OldLR = OldInt.FindLiveRangeContaining( - LI.getUseIndex(LI.getInstructionIndex(I))); + LiveInterval::iterator OldLR = + OldInt.FindLiveRangeContaining(LI.getInstructionIndex(I).getUseIndex()); if (OldLR != OldInt.end()) OldInt.removeRange(*OldLR, true); @@ -829,11 +831,10 @@ VNInfo* FirstVN = *Int.vni_begin(); FirstVN->setHasPHIKill(false); if (I->getOperand(i).isKill()) - FirstVN->addKill( - LI.getUseIndex(LI.getInstructionIndex(I))); + FirstVN->addKill(LI.getInstructionIndex(I).getUseIndex()); LiveRange LR (LI.getMBBStartIdx(I->getParent()), - LI.getNextSlot(LI.getUseIndex(LI.getInstructionIndex(I))), + LI.getInstructionIndex(I).getUseIndex().getNextSlot(), FirstVN); Int.addRange(LR); @@ -862,14 +863,14 @@ LiveInterval& LHS = LI.getOrCreateInterval(primary); LiveInterval& RHS = LI.getOrCreateInterval(secondary); - LI.computeNumbering(); + LI.renumber(); DenseMap VNMap; for (LiveInterval::iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { LiveRange R = *I; - LiveIndex Start = R.start; - LiveIndex End = R.end; + SlotIndex Start = R.start; + SlotIndex End = R.end; if (LHS.getLiveRangeContaining(Start)) return false; @@ -963,19 +964,19 @@ TII->copyRegToReg(*SI->second, SI->second->getFirstTerminator(), I->first, SI->first, RC, RC); - LI.computeNumbering(); + LI.renumber(); LiveInterval& Int = LI.getOrCreateInterval(I->first); - LiveIndex instrIdx = + SlotIndex instrIdx = LI.getInstructionIndex(--SI->second->getFirstTerminator()); - if (Int.liveAt(LI.getDefIndex(instrIdx))) - Int.removeRange(LI.getDefIndex(instrIdx), - LI.getNextSlot(LI.getMBBEndIdx(SI->second)), true); + if (Int.liveAt(instrIdx.getDefIndex())) + Int.removeRange(instrIdx.getDefIndex(), + LI.getMBBEndIdx(SI->second).getNextSlot(), true); LiveRange R = LI.addLiveRangeToEndOfBlock(I->first, --SI->second->getFirstTerminator()); R.valno->setCopy(--SI->second->getFirstTerminator()); - R.valno->def = LI.getDefIndex(instrIdx); + R.valno->def = instrIdx.getDefIndex(); DEBUG(errs() << "Renaming failed: " << SI->first << " -> " << I->first << "\n"); @@ -1010,7 +1011,7 @@ if (PI.containsOneValue()) { LI.removeInterval(DestReg); } else { - LiveIndex idx = LI.getDefIndex(LI.getInstructionIndex(PInstr)); + SlotIndex idx = LI.getInstructionIndex(PInstr).getDefIndex(); PI.removeRange(*PI.getLiveRangeContaining(idx), true); } } else { @@ -1024,7 +1025,7 @@ LiveInterval& InputI = LI.getInterval(reg); if (MBB != PInstr->getParent() && InputI.liveAt(LI.getMBBStartIdx(PInstr->getParent())) && - InputI.expiredAt(LI.getNextIndex(LI.getInstructionIndex(PInstr)))) + InputI.expiredAt(LI.getInstructionIndex(PInstr).getNextIndex())) InputI.removeRange(LI.getMBBStartIdx(PInstr->getParent()), LI.getInstructionIndex(PInstr), true); @@ -1032,7 +1033,7 @@ // If the PHI is not dead, then the valno defined by the PHI // now has an unknown def. - LiveIndex idx = LI.getDefIndex(LI.getInstructionIndex(PInstr)); + SlotIndex idx = LI.getInstructionIndex(PInstr).getDefIndex(); const LiveRange* PLR = PI.getLiveRangeContaining(idx); PLR->valno->setIsPHIDef(true); LiveRange R (LI.getMBBStartIdx(PInstr->getParent()), @@ -1044,7 +1045,7 @@ PInstr->eraseFromParent(); } - LI.computeNumbering(); + LI.renumber(); return true; } Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Tue Nov 3 17:52:08 2009 @@ -56,7 +56,7 @@ TII = mf.getTarget().getInstrInfo(); TRI = mf.getTarget().getRegisterInfo(); MF = &mf; - + ReMatId = MAX_STACK_SLOT+1; LowSpillSlot = HighSpillSlot = NO_STACK_SLOT; Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=85979&r1=85978&r2=85979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.h (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.h Tue Nov 3 17:52:08 2009 @@ -80,7 +80,7 @@ /// Virt2SplitKillMap - This is splitted virtual register to its last use /// (kill) index mapping. - IndexedMap Virt2SplitKillMap; + IndexedMap Virt2SplitKillMap; /// ReMatMap - This is virtual register to re-materialized instruction /// mapping. Each virtual register whose definition is going to be @@ -142,7 +142,7 @@ VirtRegMap() : MachineFunctionPass(&ID), Virt2PhysMap(NO_PHYS_REG), Virt2StackSlotMap(NO_STACK_SLOT), Virt2ReMatIdMap(NO_STACK_SLOT), Virt2SplitMap(0), - Virt2SplitKillMap(LiveIndex()), ReMatMap(NULL), + Virt2SplitKillMap(SlotIndex()), ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1), LowSpillSlot(NO_STACK_SLOT), HighSpillSlot(NO_STACK_SLOT) { } virtual bool runOnMachineFunction(MachineFunction &MF); @@ -266,17 +266,17 @@ } /// @brief record the last use (kill) of a split virtual register. - void addKillPoint(unsigned virtReg, LiveIndex index) { + void addKillPoint(unsigned virtReg, SlotIndex index) { Virt2SplitKillMap[virtReg] = index; } - LiveIndex getKillPoint(unsigned virtReg) const { + SlotIndex getKillPoint(unsigned virtReg) const { return Virt2SplitKillMap[virtReg]; } /// @brief remove the last use (kill) of a split virtual register. void removeKillPoint(unsigned virtReg) { - Virt2SplitKillMap[virtReg] = LiveIndex(); + Virt2SplitKillMap[virtReg] = SlotIndex(); } /// @brief returns true if the specified MachineInstr is a spill point. From evan.cheng at apple.com Tue Nov 3 18:00:40 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 04 Nov 2009 00:00:40 -0000 Subject: [llvm-commits] [llvm] r85980 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Message-ID: <200911040000.nA400e3u001866@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 18:00:39 2009 New Revision: 85980 URL: http://llvm.org/viewvc/llvm-project?rev=85980&view=rev Log: Use ldr.n to workaround a darwin assembler bug. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85980&r1=85979&r2=85980&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov 3 18:00:39 2009 @@ -326,9 +326,10 @@ "ldr", "\t$dst, $addr", []>; // Load tconstpool +// FIXME: Use ldr.n to work around a Darwin assembler bug. let canFoldAsLoad = 1 in def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, - "ldr", "\t$dst, $addr", + "ldr.n", "\t$dst, $addr", [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; // Special LDR for loads from non-pc-relative constpools. From evan.cheng at apple.com Tue Nov 3 18:08:13 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 04 Nov 2009 00:08:13 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85982 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200911040008.nA408DFD002125@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 18:08:13 2009 New Revision: 85982 URL: http://llvm.org/viewvc/llvm-project?rev=85982&view=rev Log: llvm-gcc is inlining too little at -O2 for C++ code. On WebKit, llvm-gcc compiled code is generally > 20% smaller, but it's > 5% slower. GCC mark all C++ member functions as "inline" and that makes it inline aggressively. After careful consideration, we have decided to increase -O2 inlining limit to 200 for C++ code. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=85982&r1=85981&r2=85982&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Tue Nov 3 18:08:13 2009 @@ -352,11 +352,20 @@ // inliner. gcc has many options that control inlining, but we have decided // not to support anything like that for llvm-gcc. static unsigned GuessAtInliningThreshold() { - unsigned threshold = 200; - if (optimize_size || optimize < 3) + if (optimize_size) // Reduce inline limit. - threshold = 50; - return threshold; + return 50; + + if (optimize >= 3) + return 200; + + // gcc mark C++ member functions "inline" and inline them more aggressively. + // We are not going to do that. Up the inline threshold when compiling for + // C++. + StringRef LanguageName = lang_hooks.name; + if (LanguageName == "GNU C++" || LanguageName == "GNU Objective-C++") + return 200; + return 50; } void llvm_initialize_backend(void) { From bob.wilson at apple.com Tue Nov 3 18:26:50 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 3 Nov 2009 16:26:50 -0800 Subject: [llvm-commits] [llvm] r85980 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td In-Reply-To: <200911040000.nA400e3u001866@zion.cs.uiuc.edu> References: <200911040000.nA400e3u001866@zion.cs.uiuc.edu> Message-ID: <81ACCBF7-61BB-4E08-B324-3572DC58A017@apple.com> I think CodeGen/Thumb2/machine-licm.ll needs to be updated, too. On Nov 3, 2009, at 4:00 PM, Evan Cheng wrote: > Author: evancheng > Date: Tue Nov 3 18:00:39 2009 > New Revision: 85980 > > URL: http://llvm.org/viewvc/llvm-project?rev=85980&view=rev > Log: > Use ldr.n to workaround a darwin assembler bug. > > Modified: > llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85980&r1=85979&r2=85980&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov 3 18:00:39 > 2009 > @@ -326,9 +326,10 @@ > "ldr", "\t$dst, $addr", []>; > > // Load tconstpool > +// FIXME: Use ldr.n to work around a Darwin assembler bug. > let canFoldAsLoad = 1 in > def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, > - "ldr", "\t$dst, $addr", > + "ldr.n", "\t$dst, $addr", > [(set tGPR:$dst, (load (ARMWrapper tconstpool: > $addr)))]>; > > // Special LDR for loads from non-pc-relative constpools. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Nov 3 18:42:33 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 04 Nov 2009 00:42:33 -0000 Subject: [llvm-commits] [llvm] r85986 - /llvm/trunk/test/CodeGen/Thumb2/machine-licm.ll Message-ID: <200911040042.nA40gXgi003237@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 18:42:33 2009 New Revision: 85986 URL: http://llvm.org/viewvc/llvm-project?rev=85986&view=rev Log: Fix test. Modified: llvm/trunk/test/CodeGen/Thumb2/machine-licm.ll Modified: llvm/trunk/test/CodeGen/Thumb2/machine-licm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/machine-licm.ll?rev=85986&r1=85985&r2=85986&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/machine-licm.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/machine-licm.ll Tue Nov 3 18:42:33 2009 @@ -15,7 +15,7 @@ bb.nph: ; preds = %entry ; CHECK: BB#1 -; CHECK: ldr r{{[0-9]+}}, LCPI1_0 +; CHECK: ldr{{.*}} r{{[0-9]+}}, LCPI1_0 ; CHECK: ldr{{.*}} r{{[0-9]+}}, LCPI1_1 %.pre = load i32* @GV, align 4 ; [#uses=1] br label %bb From isanbard at gmail.com Tue Nov 3 19:24:05 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 04 Nov 2009 01:24:05 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85992 - in /llvm-gcc-4.2/trunk/gcc: config/darwin.h llvm-backend.cpp Message-ID: <200911040124.nA41O59R004608@zion.cs.uiuc.edu> Author: void Date: Tue Nov 3 19:24:04 2009 New Revision: 85992 URL: http://llvm.org/viewvc/llvm-project?rev=85992&view=rev Log: Reverting r84717. fldry is generating aligned loads of strings. It requires the strings to be 16-byte aligned, which this breaks. Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/darwin.h?rev=85992&r1=85991&r2=85992&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/darwin.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/darwin.h Tue Nov 3 19:24:04 2009 @@ -698,21 +698,10 @@ char *N = (char *)alloca(strlen(fmt) + 37); \ sprintf(N, fmt, i++); \ GV->setName(N); \ - GV->setAlignment(TARGET_64BIT ? 8 : 4); \ } \ } while (0) /* LLVM LOCAL - end radar 6389998 */ -/* LLVM LOCAL - begin radar 7291825 */ -/* Give a constant string a sufficient alignment for the platform. */ -#define TARGET_ADJUST_CSTRING_ALIGN(GV) \ - do { \ - if (GV->hasInternalLinkage()) { \ - GV->setAlignment(TARGET_64BIT ? 8 : 4); \ - } \ - } while (0) -/* LLVM LOCAL - end radar 7291825 */ - #endif /* LLVM LOCAL end */ Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=85992&r1=85991&r2=85992&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Tue Nov 3 19:24:04 2009 @@ -1415,16 +1415,8 @@ unsigned TargetAlign = getTargetData().getABITypeAlignment(GV->getType()->getElementType()); if (DECL_USER_ALIGN(decl) || - 8 * TargetAlign < (unsigned)DECL_ALIGN(decl)) { + 8 * TargetAlign < (unsigned)DECL_ALIGN(decl)) GV->setAlignment(DECL_ALIGN(decl) / 8); - } -#ifdef TARGET_ADJUST_CSTRING_ALIGN - else if (DECL_INITIAL(decl) != error_mark_node && // uninitialized? - DECL_INITIAL(decl) && - TREE_CODE(DECL_INITIAL(decl)) == STRING_CST) { - TARGET_ADJUST_CSTRING_ALIGN(GV); - } -#endif } // Handle used decls From dgregor at apple.com Tue Nov 3 19:32:06 2009 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 04 Nov 2009 01:32:06 -0000 Subject: [llvm-commits] [llvm] r85994 - /llvm/trunk/lib/CodeGen/CMakeLists.txt Message-ID: <200911040132.nA41W6qp004925@zion.cs.uiuc.edu> Author: dgregor Date: Tue Nov 3 19:32:06 2009 New Revision: 85994 URL: http://llvm.org/viewvc/llvm-project?rev=85994&view=rev Log: Fix CMake makefiles Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85994&r1=85993&r2=85994&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Tue Nov 3 19:32:06 2009 @@ -42,6 +42,7 @@ Passes.cpp PostRASchedulerList.cpp PreAllocSplitting.cpp + ProcessImplicitDefs.cpp PrologEpilogInserter.cpp PseudoSourceValue.cpp RegAllocLinearScan.cpp @@ -57,6 +58,7 @@ ShrinkWrapping.cpp SimpleRegisterCoalescing.cpp SjLjEHPrepare.cpp + SlotIndexes.cpp Spiller.cpp StackProtector.cpp StackSlotColoring.cpp From lhames at gmail.com Tue Nov 3 19:34:22 2009 From: lhames at gmail.com (Lang Hames) Date: Wed, 04 Nov 2009 01:34:22 -0000 Subject: [llvm-commits] [llvm] r85995 - /llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Message-ID: <200911040134.nA41YM8D004997@zion.cs.uiuc.edu> Author: lhames Date: Tue Nov 3 19:34:22 2009 New Revision: 85995 URL: http://llvm.org/viewvc/llvm-project?rev=85995&view=rev Log: Removed an unnecessary friend declaration and some crufty comments from IndexListEntry. Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SlotIndexes.h?rev=85995&r1=85994&r2=85995&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Tue Nov 3 19:34:22 2009 @@ -37,7 +37,6 @@ /// information. class IndexListEntry { friend class SlotIndex; - friend class SlotIndexes; private: @@ -63,38 +62,6 @@ IndexListEntry* getPrev() { return prev; } const IndexListEntry* getPrev() const { return prev; } void setPrev(IndexListEntry *prev) { this->prev = prev; } - - /* - bool operator==(const IndexListEntry &other) const { - assert(getIndex() != other.getIndex() || this == &other && - "Non-equal index list entries compare equal."); - return getIndex() == other.getIndex(); - } - - bool operator!=(const IndexListEntry &other) const { - return getIndex() != other.getIndex(); - } - - bool operator<(const IndexListEntry &other) const { - return getIndex() < other.getIndex(); - } - - bool operator<=(const IndexListEntry &other) const { - return getIndex() <= other.getIndex(); - } - - bool operator>(const IndexListEntry &other) const { - return getIndex() > other.getIndex(); - } - - bool operator>=(const IndexListEntry &other) const { - return getIndex() >= other.getIndex(); - } - - int distance(const IndexListEntry &other) const { - return other.getIndex() - getIndex(); - } - */ }; // Specialize PointerLikeTypeTraits for IndexListEntry. From lhames at gmail.com Tue Nov 3 19:52:40 2009 From: lhames at gmail.com (Lang Hames) Date: Wed, 04 Nov 2009 01:52:40 -0000 Subject: [llvm-commits] [llvm] r85997 - /llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Message-ID: <200911040152.nA41qeIt005623@zion.cs.uiuc.edu> Author: lhames Date: Tue Nov 3 19:52:40 2009 New Revision: 85997 URL: http://llvm.org/viewvc/llvm-project?rev=85997&view=rev Log: Another spurious friend declaration removed. Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SlotIndexes.h?rev=85997&r1=85996&r2=85997&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Tue Nov 3 19:52:40 2009 @@ -36,8 +36,6 @@ /// SlotIndex & SlotIndexes classes for the public interface to this /// information. class IndexListEntry { - friend class SlotIndex; - private: IndexListEntry *next, *prev; From evan.cheng at apple.com Tue Nov 3 21:08:58 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 04 Nov 2009 03:08:58 -0000 Subject: [llvm-commits] [llvm] r86000 - /llvm/trunk/include/llvm/Metadata.h Message-ID: <200911040308.nA438wxv008265@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 3 21:08:57 2009 New Revision: 86000 URL: http://llvm.org/viewvc/llvm-project?rev=86000&view=rev Log: Silence implicit conversion warnings. Modified: llvm/trunk/include/llvm/Metadata.h Modified: llvm/trunk/include/llvm/Metadata.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Metadata.h?rev=86000&r1=85999&r2=86000&view=diff ============================================================================== --- llvm/trunk/include/llvm/Metadata.h (original) +++ llvm/trunk/include/llvm/Metadata.h Tue Nov 3 21:08:57 2009 @@ -63,7 +63,7 @@ StringRef getString() const { return Str; } - unsigned getLength() const { return Str.size(); } + unsigned getLength() const { return (unsigned)Str.size(); } typedef StringRef::iterator iterator; @@ -191,7 +191,7 @@ /// getNumElements - Return number of NamedMDNode elements. unsigned getNumElements() const { - return Node.size(); + return (unsigned)Node.size(); } /// addElement - Add metadata element. From deeppatel1987 at gmail.com Tue Nov 3 21:13:05 2009 From: deeppatel1987 at gmail.com (Sandeep Patel) Date: Wed, 4 Nov 2009 03:13:05 +0000 Subject: [llvm-commits] [llvm] r85980 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td In-Reply-To: <200911040000.nA400e3u001866@zion.cs.uiuc.edu> References: <200911040000.nA400e3u001866@zion.cs.uiuc.edu> Message-ID: <305d6f60911031913j7f35487bwc6632536364f150d@mail.gmail.com> This broke arm-eabi. deep On Wed, Nov 4, 2009 at 12:00 AM, Evan Cheng wrote: > Author: evancheng > Date: Tue Nov ?3 18:00:39 2009 > New Revision: 85980 > > URL: http://llvm.org/viewvc/llvm-project?rev=85980&view=rev > Log: > Use ldr.n to workaround a darwin assembler bug. > > Modified: > ? ?llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85980&r1=85979&r2=85980&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov ?3 18:00:39 2009 > @@ -326,9 +326,10 @@ > ? ? ? ? ? ? ? ? ? ? "ldr", "\t$dst, $addr", []>; > > ?// Load tconstpool > +// FIXME: Use ldr.n to work around a Darwin assembler bug. > ?let canFoldAsLoad = 1 in > ?def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, > - ? ? ? ? ? ? ? ? ?"ldr", "\t$dst, $addr", > + ? ? ? ? ? ? ? ? ?"ldr.n", "\t$dst, $addr", > ? ? ? ? ? ? ? ? ? [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; > > ?// Special LDR for loads from non-pc-relative constpools. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From bob.wilson at apple.com Tue Nov 3 21:24:22 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 3 Nov 2009 19:24:22 -0800 Subject: [llvm-commits] [llvm] r85980 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td In-Reply-To: <305d6f60911031913j7f35487bwc6632536364f150d@mail.gmail.com> References: <200911040000.nA400e3u001866@zion.cs.uiuc.edu> <305d6f60911031913j7f35487bwc6632536364f150d@mail.gmail.com> Message-ID: <0FB6BDEA-FF15-4C8E-98A9-9486A3D9383C@apple.com> How? testcase, etc.... On Nov 3, 2009, at 7:13 PM, Sandeep Patel wrote: > This broke arm-eabi. > > deep > > On Wed, Nov 4, 2009 at 12:00 AM, Evan Cheng wrote: >> Author: evancheng >> Date: Tue Nov 3 18:00:39 2009 >> New Revision: 85980 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85980&view=rev >> Log: >> Use ldr.n to workaround a darwin assembler bug. >> >> Modified: >> llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >> >> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85980&r1=85979&r2=85980&view=diff >> >> ============================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) >> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov 3 18:00:39 2009 >> @@ -326,9 +326,10 @@ >> "ldr", "\t$dst, $addr", []>; >> >> // Load tconstpool >> +// FIXME: Use ldr.n to work around a Darwin assembler bug. >> let canFoldAsLoad = 1 in >> def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, >> - "ldr", "\t$dst, $addr", >> + "ldr.n", "\t$dst, $addr", >> [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; >> >> // Special LDR for loads from non-pc-relative constpools. >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From deeppatel1987 at gmail.com Tue Nov 3 21:29:04 2009 From: deeppatel1987 at gmail.com (Sandeep Patel) Date: Wed, 4 Nov 2009 03:29:04 +0000 Subject: [llvm-commits] [llvm] r85980 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td In-Reply-To: <0FB6BDEA-FF15-4C8E-98A9-9486A3D9383C@apple.com> References: <200911040000.nA400e3u001866@zion.cs.uiuc.edu> <305d6f60911031913j7f35487bwc6632536364f150d@mail.gmail.com> <0FB6BDEA-FF15-4C8E-98A9-9486A3D9383C@apple.com> Message-ID: <305d6f60911031929j1655f870ga414dfc30d14e75b@mail.gmail.com> ccOyyiCD.s:214: Error: bad instruction `ldr.nhi r1,.LCPI3_1' while building _gcov.c for the thumb multilib. We're working on a buildbot. deep On Wed, Nov 4, 2009 at 3:24 AM, Bob Wilson wrote: > How? ?testcase, etc.... > > On Nov 3, 2009, at 7:13 PM, Sandeep Patel wrote: > >> This broke arm-eabi. >> >> deep >> >> On Wed, Nov 4, 2009 at 12:00 AM, Evan Cheng wrote: >>> Author: evancheng >>> Date: Tue Nov ?3 18:00:39 2009 >>> New Revision: 85980 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=85980&view=rev >>> Log: >>> Use ldr.n to workaround a darwin assembler bug. >>> >>> Modified: >>> ? ?llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >>> >>> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85980&r1=85979&r2=85980&view=diff >>> >>> ============================================================================== >>> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) >>> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov ?3 18:00:39 2009 >>> @@ -326,9 +326,10 @@ >>> ? ? ? ? ? ? ? ? ? ? "ldr", "\t$dst, $addr", []>; >>> >>> ?// Load tconstpool >>> +// FIXME: Use ldr.n to work around a Darwin assembler bug. >>> ?let canFoldAsLoad = 1 in >>> ?def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, >>> - ? ? ? ? ? ? ? ? ?"ldr", "\t$dst, $addr", >>> + ? ? ? ? ? ? ? ? ?"ldr.n", "\t$dst, $addr", >>> ? ? ? ? ? ? ? ? ? [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; >>> >>> ?// Special LDR for loads from non-pc-relative constpools. >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > From daniel at zuster.org Tue Nov 3 22:32:50 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 04 Nov 2009 04:32:50 -0000 Subject: [llvm-commits] [llvm] r86005 - in /llvm/trunk: Makefile.config.in Makefile.rules autoconf/configure.ac configure Message-ID: <200911040432.nA44Wp3o011088@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 3 22:32:50 2009 New Revision: 86005 URL: http://llvm.org/viewvc/llvm-project?rev=86005&view=rev Log: configure: Add --with-optimize-option, for setting the default value of OPTIMIZE_OPTION. Modified: llvm/trunk/Makefile.config.in llvm/trunk/Makefile.rules llvm/trunk/autoconf/configure.ac llvm/trunk/configure Modified: llvm/trunk/Makefile.config.in URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.config.in?rev=86005&r1=86004&r2=86005&view=diff ============================================================================== --- llvm/trunk/Makefile.config.in (original) +++ llvm/trunk/Makefile.config.in Tue Nov 3 22:32:50 2009 @@ -250,6 +250,9 @@ #DEBUG_SYMBOLS = 1 @DEBUG_SYMBOLS@ +# The compiler flags to use for optimized builds. +OPTIMIZE_OPTION := @OPTIMIZE_OPTION@ + # When ENABLE_PROFILING is enabled, the llvm source base is built with profile # information to allow gprof to be used to get execution frequencies. #ENABLE_PROFILING = 1 Modified: llvm/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=86005&r1=86004&r2=86005&view=diff ============================================================================== --- llvm/trunk/Makefile.rules (original) +++ llvm/trunk/Makefile.rules Tue Nov 3 22:32:50 2009 @@ -312,16 +312,6 @@ #-------------------------------------------------------------------- CPP.Defines := -# OPTIMIZE_OPTION - The optimization level option we want to build LLVM with -# this can be overridden on the make command line. -ifndef OPTIMIZE_OPTION - ifneq ($(HOST_OS),MingW) - OPTIMIZE_OPTION := -O3 - else - OPTIMIZE_OPTION := -O2 - endif -endif - ifeq ($(ENABLE_OPTIMIZED),1) BuildMode := Release # Don't use -fomit-frame-pointer on Darwin or FreeBSD. Modified: llvm/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=86005&r1=86004&r2=86005&view=diff ============================================================================== --- llvm/trunk/autoconf/configure.ac (original) +++ llvm/trunk/autoconf/configure.ac Tue Nov 3 22:32:50 2009 @@ -607,6 +607,23 @@ AC_MSG_ERROR([Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used]); fi +dnl Override the option to use for optimized builds. +AC_ARG_WITH(optimize-option, + AS_HELP_STRING([--with-optimize-option], + [Select the compiler options to use for optimized builds]),, + withval=default) +AC_MSG_CHECKING([optimization flags]) +case "$withval" in + default) + case "$llvm_cv_os_type" in + MingW) optimize_option=-O3 ;; + *) optimize_option=-O2 ;; + esac ;; + *) optimize_option="$withval" ;; +esac +AC_SUBST(OPTIMIZE_OPTION,$optimize_option) +AC_MSG_RESULT([$optimize_option]) + dnl Specify extra build options AC_ARG_WITH(extra-options, AS_HELP_STRING([--with-extra-options], Modified: llvm/trunk/configure URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/configure?rev=86005&r1=86004&r2=86005&view=diff ============================================================================== --- llvm/trunk/configure (original) +++ llvm/trunk/configure Tue Nov 3 22:32:50 2009 @@ -848,6 +848,7 @@ LLVM_ENUM_ASM_PRINTERS LLVM_ENUM_ASM_PARSERS ENABLE_CBE_PRINTF_A +OPTIMIZE_OPTION EXTRA_OPTIONS BINUTILS_INCDIR ENABLE_LLVMC_DYNAMIC @@ -1597,6 +1598,8 @@ searches PATH) --with-llvmgxx Specify location of llvm-g++ driver (default searches PATH) + --with-optimize-option Select the compiler options to use for optimized + builds --with-extra-options Specify additional options to compile LLVM with --with-ocaml-libdir Specify install location for ocaml bindings (default is stdlib) @@ -5192,6 +5195,29 @@ fi +# Check whether --with-optimize-option was given. +if test "${with_optimize_option+set}" = set; then + withval=$with_optimize_option; +else + withval=default +fi + +{ echo "$as_me:$LINENO: checking optimization flags" >&5 +echo $ECHO_N "checking optimization flags... $ECHO_C" >&6; } +case "$withval" in + default) + case "$llvm_cv_os_type" in + MingW) optimize_option=-O3 ;; + *) optimize_option=-O2 ;; + esac ;; + *) optimize_option="$withval" ;; +esac +OPTIMIZE_OPTION=$optimize_option + +{ echo "$as_me:$LINENO: result: $optimize_option" >&5 +echo "${ECHO_T}$optimize_option" >&6; } + + # Check whether --with-extra-options was given. if test "${with_extra_options+set}" = set; then withval=$with_extra_options; @@ -11010,7 +11036,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext + echo '#line 13183 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -14872,11 +14898,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14875: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14901: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14879: \$? = $ac_status" >&5 + echo "$as_me:14905: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -15140,11 +15166,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15143: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15169: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15147: \$? = $ac_status" >&5 + echo "$as_me:15173: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -15244,11 +15270,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15247: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15273: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15251: \$? = $ac_status" >&5 + echo "$as_me:15277: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17696,7 +17722,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:20193: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:20171: \$? = $ac_status" >&5 + echo "$as_me:20197: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -20268,11 +20294,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:20271: $lt_compile\"" >&5) + (eval echo "\"\$as_me:20297: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:20275: \$? = $ac_status" >&5 + echo "$as_me:20301: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21838,11 +21864,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21841: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21867: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:21845: \$? = $ac_status" >&5 + echo "$as_me:21871: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -21942,11 +21968,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21945: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21971: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:21949: \$? = $ac_status" >&5 + echo "$as_me:21975: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -24177,11 +24203,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24180: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24206: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:24184: \$? = $ac_status" >&5 + echo "$as_me:24210: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24445,11 +24471,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24448: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24474: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:24452: \$? = $ac_status" >&5 + echo "$as_me:24478: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24549,11 +24575,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24552: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24578: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:24556: \$? = $ac_status" >&5 + echo "$as_me:24582: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -36072,11 +36098,11 @@ LLVM_ENUM_ASM_PRINTERS!$LLVM_ENUM_ASM_PRINTERS$ac_delim LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim +OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim ENABLE_LLVMC_DYNAMIC!$ENABLE_LLVMC_DYNAMIC$ac_delim ENABLE_LLVMC_DYNAMIC_PLUGINS!$ENABLE_LLVMC_DYNAMIC_PLUGINS$ac_delim -CXX!$CXX$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -36118,6 +36144,7 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +CXX!$CXX$ac_delim CXXFLAGS!$CXXFLAGS$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim NM!$NM$ac_delim @@ -36214,7 +36241,7 @@ LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 95; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 From sabre at nondot.org Tue Nov 3 23:00:13 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 04 Nov 2009 05:00:13 -0000 Subject: [llvm-commits] [llvm] r86006 - /llvm/trunk/include/llvm/Support/IRBuilder.h Message-ID: <200911040500.nA450Eqp011960@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 3 23:00:12 2009 New Revision: 86006 URL: http://llvm.org/viewvc/llvm-project?rev=86006&view=rev Log: make IRBuilder zap "X|0" and "X&-1" when building IR, this happens during bitfield codegen and slows down -O0 compile times by making useless IR. rdar://7362516 Modified: llvm/trunk/include/llvm/Support/IRBuilder.h Modified: llvm/trunk/include/llvm/Support/IRBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=86006&r1=86005&r2=86006&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/IRBuilder.h (original) +++ llvm/trunk/include/llvm/Support/IRBuilder.h Tue Nov 3 23:00:12 2009 @@ -390,15 +390,21 @@ return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name); } Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") { - if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) + if (Constant *RC = dyn_cast(RHS)) { + if (isa(RC) && cast(RC)->isAllOnesValue()) + return LHS; // LHS & -1 -> LHS + if (Constant *LC = dyn_cast(LHS)) return Folder.CreateAnd(LC, RC); + } return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name); } Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { - if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) + if (Constant *RC = dyn_cast(RHS)) { + if (RC->isNullValue()) + return LHS; // LHS | 0 -> LHS + if (Constant *LC = dyn_cast(LHS)) return Folder.CreateOr(LC, RC); + } return Insert(BinaryOperator::CreateOr(LHS, RHS), Name); } Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") { From nicholas at mxc.ca Wed Nov 4 00:15:28 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 04 Nov 2009 06:15:28 -0000 Subject: [llvm-commits] [llvm] r86009 - /llvm/trunk/docs/GettingStarted.html Message-ID: <200911040615.nA46FStr014546@zion.cs.uiuc.edu> Author: nicholas Date: Wed Nov 4 00:15:28 2009 New Revision: 86009 URL: http://llvm.org/viewvc/llvm-project?rev=86009&view=rev Log: The magic for our current brand of .bc files is BC. For older ones it was llvc. When was it ever "llvm"? Modified: llvm/trunk/docs/GettingStarted.html Modified: llvm/trunk/docs/GettingStarted.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/GettingStarted.html?rev=86009&r1=86008&r2=86009&view=diff ============================================================================== --- llvm/trunk/docs/GettingStarted.html (original) +++ llvm/trunk/docs/GettingStarted.html Wed Nov 4 00:15:28 2009 @@ -1154,7 +1154,7 @@

                           $ mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
                          -$ echo ':llvm:M::llvm::/path/to/lli:' > /proc/sys/fs/binfmt_misc/register
                          +$ echo ':llvm:M::BC::/path/to/lli:' > /proc/sys/fs/binfmt_misc/register
                           $ chmod u+x hello.bc   (if needed)
                           $ ./hello.bc
                           
                          From sabre at nondot.org Wed Nov 4 00:24:41 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 04 Nov 2009 06:24:41 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r86012 - /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Message-ID: <200911040624.nA46OfI1014936@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 4 00:24:41 2009 New Revision: 86012 URL: http://llvm.org/viewvc/llvm-project?rev=86012&view=rev Log: tidy up Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=86012&r1=86011&r2=86012&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Wed Nov 4 00:24:41 2009 @@ -654,15 +654,11 @@ /// GetFieldIndex - Returns the index of the LLVM field corresponding to /// this FIELD_DECL, or ~0U if the type the field belongs to has not yet /// been converted. -unsigned int TypeConverter::GetFieldIndex(tree_node *field_decl) { +unsigned int TypeConverter::GetFieldIndex(tree field_decl) { assert(TREE_CODE(field_decl) == FIELD_DECL && "Not a FIELD_DECL!"); std::map::iterator I = FieldIndexMap.find(field_decl); - if (I != FieldIndexMap.end()) { - return I->second; - } else { - assert(false && "Type not laid out for LLVM?"); - return ~0U; - } + assert(I != FieldIndexMap.end() && "Type not laid out for LLVM?"); + return I->second; } /// SetFieldIndex - Set the index of the LLVM field corresponding to From evan.cheng at apple.com Wed Nov 4 01:38:48 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 04 Nov 2009 07:38:48 -0000 Subject: [llvm-commits] [llvm] r86019 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Message-ID: <200911040738.nA47cm8m017413@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 4 01:38:48 2009 New Revision: 86019 URL: http://llvm.org/viewvc/llvm-project?rev=86019&view=rev Log: The .n suffix must go after the predicate. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=86019&r1=86018&r2=86019&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Wed Nov 4 01:38:48 2009 @@ -329,7 +329,7 @@ // FIXME: Use ldr.n to work around a Darwin assembler bug. let canFoldAsLoad = 1 in def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, - "ldr.n", "\t$dst, $addr", + "ldr", ".n\t$dst, $addr", [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; // Special LDR for loads from non-pc-relative constpools. From evan.cheng at apple.com Wed Nov 4 01:53:29 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 3 Nov 2009 23:53:29 -0800 Subject: [llvm-commits] [llvm] r85980 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td In-Reply-To: <305d6f60911031929j1655f870ga414dfc30d14e75b@mail.gmail.com> References: <200911040000.nA400e3u001866@zion.cs.uiuc.edu> <305d6f60911031913j7f35487bwc6632536364f150d@mail.gmail.com> <0FB6BDEA-FF15-4C8E-98A9-9486A3D9383C@apple.com> <305d6f60911031929j1655f870ga414dfc30d14e75b@mail.gmail.com> Message-ID: Fixed. Evan On Nov 3, 2009, at 7:29 PM, Sandeep Patel wrote: > ccOyyiCD.s:214: Error: bad instruction `ldr.nhi r1,.LCPI3_1' > > while building _gcov.c for the thumb multilib. > > We're working on a buildbot. > > deep > > On Wed, Nov 4, 2009 at 3:24 AM, Bob Wilson > wrote: >> How? testcase, etc.... >> >> On Nov 3, 2009, at 7:13 PM, Sandeep Patel wrote: >> >>> This broke arm-eabi. >>> >>> deep >>> >>> On Wed, Nov 4, 2009 at 12:00 AM, Evan Cheng >>> wrote: >>>> Author: evancheng >>>> Date: Tue Nov 3 18:00:39 2009 >>>> New Revision: 85980 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=85980&view=rev >>>> Log: >>>> Use ldr.n to workaround a darwin assembler bug. >>>> >>>> Modified: >>>> llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >>>> >>>> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85980&r1=85979&r2=85980&view=diff >>>> >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> =================================================================== >>>> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) >>>> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov 3 >>>> 18:00:39 2009 >>>> @@ -326,9 +326,10 @@ >>>> "ldr", "\t$dst, $addr", []>; >>>> >>>> // Load tconstpool >>>> +// FIXME: Use ldr.n to work around a Darwin assembler bug. >>>> let canFoldAsLoad = 1 in >>>> def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), >>>> IIC_iLoadi, >>>> - "ldr", "\t$dst, $addr", >>>> + "ldr.n", "\t$dst, $addr", >>>> [(set tGPR:$dst, (load (ARMWrapper tconstpool: >>>> $addr)))]>; >>>> >>>> // Special LDR for loads from non-pc-relative constpools. >>>> >>>> >>>> _______________________________________________ >>>> llvm-commits mailing list >>>> llvm-commits at cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> From sabre at nondot.org Wed Nov 4 01:57:05 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 04 Nov 2009 07:57:05 -0000 Subject: [llvm-commits] [llvm] r86020 - /llvm/trunk/test/Transforms/InstCombine/sub.ll Message-ID: <200911040757.nA47v5mI017975@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 4 01:57:05 2009 New Revision: 86020 URL: http://llvm.org/viewvc/llvm-project?rev=86020&view=rev Log: filecheckize this test. Modified: llvm/trunk/test/Transforms/InstCombine/sub.ll Modified: llvm/trunk/test/Transforms/InstCombine/sub.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sub.ll?rev=86020&r1=86019&r2=86020&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sub.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/sub.ll Wed Nov 4 01:57:05 2009 @@ -1,148 +1,213 @@ ; This test makes sure that these instructions are properly eliminated. ; -; RUN: opt < %s -instcombine -S | \ -; RUN: grep -v {sub i32 %Cok, %Bok} | grep -v {sub i32 0, %Aok} | not grep sub +; RUN: opt < %s -instcombine -S | FileCheck %s define i32 @test1(i32 %A) { - %B = sub i32 %A, %A ; [#uses=1] + %B = sub i32 %A, %A ret i32 %B +; CHECK: @test1 +; CHECK: ret i32 0 } define i32 @test2(i32 %A) { - %B = sub i32 %A, 0 ; [#uses=1] + %B = sub i32 %A, 0 ret i32 %B +; CHECK: @test2 +; CHECK: ret i32 %A } define i32 @test3(i32 %A) { - %B = sub i32 0, %A ; [#uses=1] - %C = sub i32 0, %B ; [#uses=1] + %B = sub i32 0, %A + %C = sub i32 0, %B ret i32 %C +; CHECK: @test3 +; CHECK: ret i32 %A } define i32 @test4(i32 %A, i32 %x) { - %B = sub i32 0, %A ; [#uses=1] - %C = sub i32 %x, %B ; [#uses=1] + %B = sub i32 0, %A + %C = sub i32 %x, %B ret i32 %C +; CHECK: @test4 +; CHECK: %C = add i32 %x, %A +; CHECK: ret i32 %C } -define i32 @test5(i32 %A, i32 %Bok, i32 %Cok) { - %D = sub i32 %Bok, %Cok ; [#uses=1] - %E = sub i32 %A, %D ; [#uses=1] +define i32 @test5(i32 %A, i32 %B, i32 %C) { + %D = sub i32 %B, %C + %E = sub i32 %A, %D ret i32 %E +; CHECK: @test5 +; CHECK: %D = sub i32 %C, %B +; CHECK: %E = add +; CHECK: ret i32 %E } define i32 @test6(i32 %A, i32 %B) { - %C = and i32 %A, %B ; [#uses=1] - %D = sub i32 %A, %C ; [#uses=1] + %C = and i32 %A, %B + %D = sub i32 %A, %C ret i32 %D +; CHECK: @test6 +; CHECK-NEXT: xor i32 %B, -1 +; CHECK-NEXT: %D = and i32 +; CHECK-NEXT: ret i32 %D } define i32 @test7(i32 %A) { - %B = sub i32 -1, %A ; [#uses=1] + %B = sub i32 -1, %A ret i32 %B +; CHECK: @test7 +; CHECK: %B = xor i32 %A, -1 +; CHECK: ret i32 %B } define i32 @test8(i32 %A) { - %B = mul i32 9, %A ; [#uses=1] - %C = sub i32 %B, %A ; [#uses=1] + %B = mul i32 9, %A + %C = sub i32 %B, %A ret i32 %C +; CHECK: @test8 +; CHECK: %C = shl i32 %A, 3 +; CHECK: ret i32 %C } define i32 @test9(i32 %A) { - %B = mul i32 3, %A ; [#uses=1] - %C = sub i32 %A, %B ; [#uses=1] + %B = mul i32 3, %A + %C = sub i32 %A, %B ret i32 %C +; CHECK: @test9 +; CHECK: %C = mul i32 %A, -2 +; CHECK: ret i32 %C } define i32 @test10(i32 %A, i32 %B) { - %C = sub i32 0, %A ; [#uses=1] - %D = sub i32 0, %B ; [#uses=1] - %E = mul i32 %C, %D ; [#uses=1] + %C = sub i32 0, %A + %D = sub i32 0, %B + %E = mul i32 %C, %D ret i32 %E +; CHECK: @test10 +; CHECK: %E = mul i32 %A, %B +; CHECK: ret i32 %E } -define i32 @test10.upgrd.1(i32 %A) { - %C = sub i32 0, %A ; [#uses=1] - %E = mul i32 %C, 7 ; [#uses=1] +define i32 @test10a(i32 %A) { + %C = sub i32 0, %A + %E = mul i32 %C, 7 ret i32 %E +; CHECK: @test10a +; CHECK: %E = mul i32 %A, -7 +; CHECK: ret i32 %E } define i1 @test11(i8 %A, i8 %B) { - %C = sub i8 %A, %B ; [#uses=1] - %cD = icmp ne i8 %C, 0 ; [#uses=1] + %C = sub i8 %A, %B + %cD = icmp ne i8 %C, 0 ret i1 %cD +; CHECK: @test11 +; CHECK: %cD = icmp ne i8 %A, %B +; CHECK: ret i1 %cD } define i32 @test12(i32 %A) { - %B = ashr i32 %A, 31 ; [#uses=1] - %C = sub i32 0, %B ; [#uses=1] + %B = ashr i32 %A, 31 + %C = sub i32 0, %B ret i32 %C +; CHECK: @test12 +; CHECK: %C = lshr i32 %A, 31 +; CHECK: ret i32 %C } define i32 @test13(i32 %A) { - %B = lshr i32 %A, 31 ; [#uses=1] - %C = sub i32 0, %B ; [#uses=1] + %B = lshr i32 %A, 31 + %C = sub i32 0, %B ret i32 %C +; CHECK: @test13 +; CHECK: %C = ashr i32 %A, 31 +; CHECK: ret i32 %C } define i32 @test14(i32 %A) { - %B = lshr i32 %A, 31 ; [#uses=1] - %C = bitcast i32 %B to i32 ; [#uses=1] - %D = sub i32 0, %C ; [#uses=1] + %B = lshr i32 %A, 31 + %C = bitcast i32 %B to i32 + %D = sub i32 0, %C ret i32 %D +; CHECK: @test14 +; CHECK: %D = ashr i32 %A, 31 +; CHECK: ret i32 %D } define i32 @test15(i32 %A, i32 %B) { - %C = sub i32 0, %A ; [#uses=1] - %D = srem i32 %B, %C ; [#uses=1] + %C = sub i32 0, %A + %D = srem i32 %B, %C ret i32 %D +; CHECK: @test15 +; CHECK: %D = srem i32 %B, %A +; CHECK: ret i32 %D } define i32 @test16(i32 %A) { - %X = sdiv i32 %A, 1123 ; [#uses=1] - %Y = sub i32 0, %X ; [#uses=1] + %X = sdiv i32 %A, 1123 + %Y = sub i32 0, %X ret i32 %Y +; CHECK: @test16 +; CHECK: %Y = sdiv i32 %A, -1123 +; CHECK: ret i32 %Y } ; Can't fold subtract here because negation it might oveflow. ; PR3142 -define i32 @test17(i32 %Aok) { - %B = sub i32 0, %Aok ; [#uses=1] - %C = sdiv i32 %B, 1234 ; [#uses=1] - ret i32 %C +define i32 @test17(i32 %A) { + %B = sub i32 0, %A + %C = sdiv i32 %B, 1234 + ret i32 %C +; CHECK: @test17 +; CHECK: %B = sub i32 0, %A +; CHECK: %C = sdiv i32 %B, 1234 +; CHECK: ret i32 %C } define i64 @test18(i64 %Y) { - %tmp.4 = shl i64 %Y, 2 ; [#uses=1] - %tmp.12 = shl i64 %Y, 2 ; [#uses=1] - %tmp.8 = sub i64 %tmp.4, %tmp.12 ; [#uses=1] + %tmp.4 = shl i64 %Y, 2 + %tmp.12 = shl i64 %Y, 2 + %tmp.8 = sub i64 %tmp.4, %tmp.12 ret i64 %tmp.8 +; CHECK: @test18 +; CHECK: ret i64 0 } define i32 @test19(i32 %X, i32 %Y) { - %Z = sub i32 %X, %Y ; [#uses=1] - %Q = add i32 %Z, %Y ; [#uses=1] + %Z = sub i32 %X, %Y + %Q = add i32 %Z, %Y ret i32 %Q +; CHECK: @test19 +; CHECK: ret i32 %X } define i1 @test20(i32 %g, i32 %h) { - %tmp.2 = sub i32 %g, %h ; [#uses=1] - %tmp.4 = icmp ne i32 %tmp.2, %g ; [#uses=1] + %tmp.2 = sub i32 %g, %h + %tmp.4 = icmp ne i32 %tmp.2, %g ret i1 %tmp.4 +; CHECK: @test20 +; CHECK: %tmp.4 = icmp ne i32 %h, 0 +; CHECK: ret i1 %tmp.4 } define i1 @test21(i32 %g, i32 %h) { - %tmp.2 = sub i32 %g, %h ; [#uses=1] - %tmp.4 = icmp ne i32 %tmp.2, %g ; [#uses=1] - ret i1 %tmp.4 + %tmp.2 = sub i32 %g, %h + %tmp.4 = icmp ne i32 %tmp.2, %g + ret i1 %tmp.4 +; CHECK: @test21 +; CHECK: %tmp.4 = icmp ne i32 %h, 0 +; CHECK: ret i1 %tmp.4 } ; PR2298 -define i8 @test22(i32 %a, i32 %b) zeroext nounwind { - %tmp2 = sub i32 0, %a ; [#uses=1] - %tmp4 = sub i32 0, %b ; [#uses=1] - %tmp5 = icmp eq i32 %tmp2, %tmp4 ; [#uses=1] - %retval89 = zext i1 %tmp5 to i8 ; [#uses=1] - ret i8 %retval89 +define i1 @test22(i32 %a, i32 %b) zeroext nounwind { + %tmp2 = sub i32 0, %a + %tmp4 = sub i32 0, %b + %tmp5 = icmp eq i32 %tmp2, %tmp4 + ret i1 %tmp5 +; CHECK: @test22 +; CHECK: %tmp5 = icmp eq i32 %a, %b +; CHECK: ret i1 %tmp5 } From sabre at nondot.org Wed Nov 4 02:05:21 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 04 Nov 2009 08:05:21 -0000 Subject: [llvm-commits] [llvm] r86021 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/sub.ll Message-ID: <200911040805.nA485LdL018303@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 4 02:05:20 2009 New Revision: 86021 URL: http://llvm.org/viewvc/llvm-project?rev=86021&view=rev Log: move two functions up higher in the file. Delete a useless argument to EmitGEPOffset. Implement some new transforms for optimizing subtracts of two pointer to ints into the same vector. This happens for C++ iterator idioms for example, stringmap takes a const char* that points to the start and end of a string. Once inlined, we want the pointer difference to turn back into a length. This is rdar://7362831. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/sub.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=86021&r1=86020&r2=86021&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed Nov 4 02:05:20 2009 @@ -217,6 +217,7 @@ // Instruction *visitAdd(BinaryOperator &I); Instruction *visitFAdd(BinaryOperator &I); + Value *OptimizePointerDifference(Value *LHS, Value *RHS, const Type *Ty); Instruction *visitSub(BinaryOperator &I); Instruction *visitFSub(BinaryOperator &I); Instruction *visitMul(BinaryOperator &I); @@ -2510,7 +2511,7 @@ RHSConv->getOperand(0))) { // Insert the new integer add. Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), - RHSConv->getOperand(0), "addconv"); + RHSConv->getOperand(0),"addconv"); return new SIToFPInst(NewAdd, I.getType()); } } @@ -2519,13 +2520,210 @@ return Changed ? &I : 0; } + +/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the +/// code necessary to compute the offset from the base pointer (without adding +/// in the base pointer). Return the result as a signed integer of intptr size. +static Value *EmitGEPOffset(User *GEP, InstCombiner &IC) { + TargetData &TD = *IC.getTargetData(); + gep_type_iterator GTI = gep_type_begin(GEP); + const Type *IntPtrTy = TD.getIntPtrType(GEP->getContext()); + Value *Result = Constant::getNullValue(IntPtrTy); + + // Build a mask for high order bits. + unsigned IntPtrWidth = TD.getPointerSizeInBits(); + uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth); + + for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; + ++i, ++GTI) { + Value *Op = *i; + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; + if (ConstantInt *OpC = dyn_cast(Op)) { + if (OpC->isZero()) continue; + + // Handle a struct index, which adds its field offset to the pointer. + if (const StructType *STy = dyn_cast(*GTI)) { + Size = TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue()); + + Result = IC.Builder->CreateAdd(Result, + ConstantInt::get(IntPtrTy, Size), + GEP->getName()+".offs"); + continue; + } + + Constant *Scale = ConstantInt::get(IntPtrTy, Size); + Constant *OC = + ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/); + Scale = ConstantExpr::getMul(OC, Scale); + // Emit an add instruction. + Result = IC.Builder->CreateAdd(Result, Scale, GEP->getName()+".offs"); + continue; + } + // Convert to correct type. + if (Op->getType() != IntPtrTy) + Op = IC.Builder->CreateIntCast(Op, IntPtrTy, true, Op->getName()+".c"); + if (Size != 1) { + Constant *Scale = ConstantInt::get(IntPtrTy, Size); + // We'll let instcombine(mul) convert this to a shl if possible. + Op = IC.Builder->CreateMul(Op, Scale, GEP->getName()+".idx"); + } + + // Emit an add instruction. + Result = IC.Builder->CreateAdd(Op, Result, GEP->getName()+".offs"); + } + return Result; +} + + +/// EvaluateGEPOffsetExpression - Return a value that can be used to compare +/// the *offset* implied by a GEP to zero. For example, if we have &A[i], we +/// want to return 'i' for "icmp ne i, 0". Note that, in general, indices can +/// be complex, and scales are involved. The above expression would also be +/// legal to codegen as "icmp ne (i*4), 0" (assuming A is a pointer to i32). +/// This later form is less amenable to optimization though, and we are allowed +/// to generate the first by knowing that pointer arithmetic doesn't overflow. +/// +/// If we can't emit an optimized form for this expression, this returns null. +/// +static Value *EvaluateGEPOffsetExpression(User *GEP, Instruction &I, + InstCombiner &IC) { + TargetData &TD = *IC.getTargetData(); + gep_type_iterator GTI = gep_type_begin(GEP); + + // Check to see if this gep only has a single variable index. If so, and if + // any constant indices are a multiple of its scale, then we can compute this + // in terms of the scale of the variable index. For example, if the GEP + // implies an offset of "12 + i*4", then we can codegen this as "3 + i", + // because the expression will cross zero at the same point. + unsigned i, e = GEP->getNumOperands(); + int64_t Offset = 0; + for (i = 1; i != e; ++i, ++GTI) { + if (ConstantInt *CI = dyn_cast(GEP->getOperand(i))) { + // Compute the aggregate offset of constant indices. + if (CI->isZero()) continue; + + // Handle a struct index, which adds its field offset to the pointer. + if (const StructType *STy = dyn_cast(*GTI)) { + Offset += TD.getStructLayout(STy)->getElementOffset(CI->getZExtValue()); + } else { + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); + Offset += Size*CI->getSExtValue(); + } + } else { + // Found our variable index. + break; + } + } + + // If there are no variable indices, we must have a constant offset, just + // evaluate it the general way. + if (i == e) return 0; + + Value *VariableIdx = GEP->getOperand(i); + // Determine the scale factor of the variable element. For example, this is + // 4 if the variable index is into an array of i32. + uint64_t VariableScale = TD.getTypeAllocSize(GTI.getIndexedType()); + + // Verify that there are no other variable indices. If so, emit the hard way. + for (++i, ++GTI; i != e; ++i, ++GTI) { + ConstantInt *CI = dyn_cast(GEP->getOperand(i)); + if (!CI) return 0; + + // Compute the aggregate offset of constant indices. + if (CI->isZero()) continue; + + // Handle a struct index, which adds its field offset to the pointer. + if (const StructType *STy = dyn_cast(*GTI)) { + Offset += TD.getStructLayout(STy)->getElementOffset(CI->getZExtValue()); + } else { + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); + Offset += Size*CI->getSExtValue(); + } + } + + // Okay, we know we have a single variable index, which must be a + // pointer/array/vector index. If there is no offset, life is simple, return + // the index. + unsigned IntPtrWidth = TD.getPointerSizeInBits(); + if (Offset == 0) { + // Cast to intptrty in case a truncation occurs. If an extension is needed, + // we don't need to bother extending: the extension won't affect where the + // computation crosses zero. + if (VariableIdx->getType()->getPrimitiveSizeInBits() > IntPtrWidth) + VariableIdx = new TruncInst(VariableIdx, + TD.getIntPtrType(VariableIdx->getContext()), + VariableIdx->getName(), &I); + return VariableIdx; + } + + // Otherwise, there is an index. The computation we will do will be modulo + // the pointer size, so get it. + uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth); + + Offset &= PtrSizeMask; + VariableScale &= PtrSizeMask; + + // To do this transformation, any constant index must be a multiple of the + // variable scale factor. For example, we can evaluate "12 + 4*i" as "3 + i", + // but we can't evaluate "10 + 3*i" in terms of i. Check that the offset is a + // multiple of the variable scale. + int64_t NewOffs = Offset / (int64_t)VariableScale; + if (Offset != NewOffs*(int64_t)VariableScale) + return 0; + + // Okay, we can do this evaluation. Start by converting the index to intptr. + const Type *IntPtrTy = TD.getIntPtrType(VariableIdx->getContext()); + if (VariableIdx->getType() != IntPtrTy) + VariableIdx = CastInst::CreateIntegerCast(VariableIdx, IntPtrTy, + true /*SExt*/, + VariableIdx->getName(), &I); + Constant *OffsetVal = ConstantInt::get(IntPtrTy, NewOffs); + return BinaryOperator::CreateAdd(VariableIdx, OffsetVal, "offset", &I); +} + + +/// Optimize pointer differences into the same array into a size. Consider: +/// &A[10] - &A[0]: we should compile this to "10". LHS/RHS are the pointer +/// operands to the ptrtoint instructions for the LHS/RHS of the subtract. +/// +Value *InstCombiner::OptimizePointerDifference(Value *LHS, Value *RHS, + const Type *Ty) { + assert(TD && "Must have target data info for this"); + + // If LHS is a gep based on RHS or RHS is a gep based on LHS, we can optimize + // this. + bool Swapped; + GetElementPtrInst *GEP; + + if ((GEP = dyn_cast(LHS)) && + GEP->getOperand(0) == RHS) + Swapped = false; + else if ((GEP = dyn_cast(RHS)) && + GEP->getOperand(0) == LHS) + Swapped = true; + else + return 0; + + // TODO: Could also optimize &A[i] - &A[j] -> "i-j". + + // Emit the offset of the GEP and an intptr_t. + Value *Result = EmitGEPOffset(GEP, *this); + + // If we have p - gep(p, ...) then we have to negate the result. + if (Swapped) + Result = Builder->CreateNeg(Result, "diff.neg"); + + return Builder->CreateIntCast(Result, Ty, true); +} + + Instruction *InstCombiner::visitSub(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (Op0 == Op1) // sub X, X -> 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - // If this is a 'B = x-(-A)', change to B = x+A... + // If this is a 'B = x-(-A)', change to B = x+A. if (Value *V = dyn_castNegVal(Op1)) return BinaryOperator::CreateAdd(Op0, V); @@ -2533,9 +2731,11 @@ return ReplaceInstUsesWith(I, Op0); // undef - X -> undef if (isa(Op1)) return ReplaceInstUsesWith(I, Op1); // X - undef -> undef - + if (I.getType() == Type::getInt1Ty(*Context)) + return BinaryOperator::CreateXor(Op0, Op1); + if (ConstantInt *C = dyn_cast(Op0)) { - // Replace (-1 - A) with (~A)... + // Replace (-1 - A) with (~A). if (C->isAllOnesValue()) return BinaryOperator::CreateNot(Op1); @@ -2558,8 +2758,7 @@ SI->getOperand(0), CU, SI->getName()); } } - } - else if (SI->getOpcode() == Instruction::AShr) { + } else if (SI->getOpcode() == Instruction::AShr) { if (ConstantInt *CU = dyn_cast(SI->getOperand(1))) { // Check to see if we are shifting out everything but the sign bit. if (CU->getLimitedValue(SI->getType()->getPrimitiveSizeInBits()) == @@ -2584,9 +2783,6 @@ return SelectInst::Create(ZI->getOperand(0), SubOne(C), C); } - if (I.getType() == Type::getInt1Ty(*Context)) - return BinaryOperator::CreateXor(Op0, Op1); - if (BinaryOperator *Op1I = dyn_cast(Op1)) { if (Op1I->getOpcode() == Instruction::Add) { if (Op1I->getOperand(0) == Op0) // X-(X+Y) == -Y @@ -2668,6 +2864,28 @@ if (X == dyn_castFoldableMul(Op1, C2)) return BinaryOperator::CreateMul(X, ConstantExpr::getSub(C1, C2)); } + + // Optimize pointer differences into the same array into a size. Consider: + // &A[10] - &A[0]: we should compile this to "10". + if (TD) { + if (PtrToIntInst *LHS = dyn_cast(Op0)) + if (PtrToIntInst *RHS = dyn_cast(Op1)) + if (Value *Res = OptimizePointerDifference(LHS->getOperand(0), + RHS->getOperand(0), + I.getType())) + return ReplaceInstUsesWith(I, Res); + + // trunc(p)-trunc(q) -> trunc(p-q) + if (TruncInst *LHST = dyn_cast(Op0)) + if (TruncInst *RHST = dyn_cast(Op1)) + if (PtrToIntInst *LHS = dyn_cast(LHST->getOperand(0))) + if (PtrToIntInst *RHS = dyn_cast(RHST->getOperand(0))) + if (Value *Res = OptimizePointerDifference(LHS->getOperand(0), + RHS->getOperand(0), + I.getType())) + return ReplaceInstUsesWith(I, Res); + } + return 0; } @@ -5417,166 +5635,6 @@ IsSigned); } -/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the -/// code necessary to compute the offset from the base pointer (without adding -/// in the base pointer). Return the result as a signed integer of intptr size. -static Value *EmitGEPOffset(User *GEP, Instruction &I, InstCombiner &IC) { - TargetData &TD = *IC.getTargetData(); - gep_type_iterator GTI = gep_type_begin(GEP); - const Type *IntPtrTy = TD.getIntPtrType(I.getContext()); - Value *Result = Constant::getNullValue(IntPtrTy); - - // Build a mask for high order bits. - unsigned IntPtrWidth = TD.getPointerSizeInBits(); - uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth); - - for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; - ++i, ++GTI) { - Value *Op = *i; - uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; - if (ConstantInt *OpC = dyn_cast(Op)) { - if (OpC->isZero()) continue; - - // Handle a struct index, which adds its field offset to the pointer. - if (const StructType *STy = dyn_cast(*GTI)) { - Size = TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue()); - - Result = IC.Builder->CreateAdd(Result, - ConstantInt::get(IntPtrTy, Size), - GEP->getName()+".offs"); - continue; - } - - Constant *Scale = ConstantInt::get(IntPtrTy, Size); - Constant *OC = - ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/); - Scale = ConstantExpr::getMul(OC, Scale); - // Emit an add instruction. - Result = IC.Builder->CreateAdd(Result, Scale, GEP->getName()+".offs"); - continue; - } - // Convert to correct type. - if (Op->getType() != IntPtrTy) - Op = IC.Builder->CreateIntCast(Op, IntPtrTy, true, Op->getName()+".c"); - if (Size != 1) { - Constant *Scale = ConstantInt::get(IntPtrTy, Size); - // We'll let instcombine(mul) convert this to a shl if possible. - Op = IC.Builder->CreateMul(Op, Scale, GEP->getName()+".idx"); - } - - // Emit an add instruction. - Result = IC.Builder->CreateAdd(Op, Result, GEP->getName()+".offs"); - } - return Result; -} - - -/// EvaluateGEPOffsetExpression - Return a value that can be used to compare -/// the *offset* implied by a GEP to zero. For example, if we have &A[i], we -/// want to return 'i' for "icmp ne i, 0". Note that, in general, indices can -/// be complex, and scales are involved. The above expression would also be -/// legal to codegen as "icmp ne (i*4), 0" (assuming A is a pointer to i32). -/// This later form is less amenable to optimization though, and we are allowed -/// to generate the first by knowing that pointer arithmetic doesn't overflow. -/// -/// If we can't emit an optimized form for this expression, this returns null. -/// -static Value *EvaluateGEPOffsetExpression(User *GEP, Instruction &I, - InstCombiner &IC) { - TargetData &TD = *IC.getTargetData(); - gep_type_iterator GTI = gep_type_begin(GEP); - - // Check to see if this gep only has a single variable index. If so, and if - // any constant indices are a multiple of its scale, then we can compute this - // in terms of the scale of the variable index. For example, if the GEP - // implies an offset of "12 + i*4", then we can codegen this as "3 + i", - // because the expression will cross zero at the same point. - unsigned i, e = GEP->getNumOperands(); - int64_t Offset = 0; - for (i = 1; i != e; ++i, ++GTI) { - if (ConstantInt *CI = dyn_cast(GEP->getOperand(i))) { - // Compute the aggregate offset of constant indices. - if (CI->isZero()) continue; - - // Handle a struct index, which adds its field offset to the pointer. - if (const StructType *STy = dyn_cast(*GTI)) { - Offset += TD.getStructLayout(STy)->getElementOffset(CI->getZExtValue()); - } else { - uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); - Offset += Size*CI->getSExtValue(); - } - } else { - // Found our variable index. - break; - } - } - - // If there are no variable indices, we must have a constant offset, just - // evaluate it the general way. - if (i == e) return 0; - - Value *VariableIdx = GEP->getOperand(i); - // Determine the scale factor of the variable element. For example, this is - // 4 if the variable index is into an array of i32. - uint64_t VariableScale = TD.getTypeAllocSize(GTI.getIndexedType()); - - // Verify that there are no other variable indices. If so, emit the hard way. - for (++i, ++GTI; i != e; ++i, ++GTI) { - ConstantInt *CI = dyn_cast(GEP->getOperand(i)); - if (!CI) return 0; - - // Compute the aggregate offset of constant indices. - if (CI->isZero()) continue; - - // Handle a struct index, which adds its field offset to the pointer. - if (const StructType *STy = dyn_cast(*GTI)) { - Offset += TD.getStructLayout(STy)->getElementOffset(CI->getZExtValue()); - } else { - uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); - Offset += Size*CI->getSExtValue(); - } - } - - // Okay, we know we have a single variable index, which must be a - // pointer/array/vector index. If there is no offset, life is simple, return - // the index. - unsigned IntPtrWidth = TD.getPointerSizeInBits(); - if (Offset == 0) { - // Cast to intptrty in case a truncation occurs. If an extension is needed, - // we don't need to bother extending: the extension won't affect where the - // computation crosses zero. - if (VariableIdx->getType()->getPrimitiveSizeInBits() > IntPtrWidth) - VariableIdx = new TruncInst(VariableIdx, - TD.getIntPtrType(VariableIdx->getContext()), - VariableIdx->getName(), &I); - return VariableIdx; - } - - // Otherwise, there is an index. The computation we will do will be modulo - // the pointer size, so get it. - uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth); - - Offset &= PtrSizeMask; - VariableScale &= PtrSizeMask; - - // To do this transformation, any constant index must be a multiple of the - // variable scale factor. For example, we can evaluate "12 + 4*i" as "3 + i", - // but we can't evaluate "10 + 3*i" in terms of i. Check that the offset is a - // multiple of the variable scale. - int64_t NewOffs = Offset / (int64_t)VariableScale; - if (Offset != NewOffs*(int64_t)VariableScale) - return 0; - - // Okay, we can do this evaluation. Start by converting the index to intptr. - const Type *IntPtrTy = TD.getIntPtrType(VariableIdx->getContext()); - if (VariableIdx->getType() != IntPtrTy) - VariableIdx = CastInst::CreateIntegerCast(VariableIdx, IntPtrTy, - true /*SExt*/, - VariableIdx->getName(), &I); - Constant *OffsetVal = ConstantInt::get(IntPtrTy, NewOffs); - return BinaryOperator::CreateAdd(VariableIdx, OffsetVal, "offset", &I); -} - /// FoldGEPICmp - Fold comparisons between a GEP instruction and something /// else. At this point we know that the GEP is on the LHS of the comparison. @@ -5597,7 +5655,7 @@ // If not, synthesize the offset the hard way. if (Offset == 0) - Offset = EmitGEPOffset(GEPLHS, I, *this); + Offset = EmitGEPOffset(GEPLHS, *this); return new ICmpInst(ICmpInst::getSignedPredicate(Cond), Offset, Constant::getNullValue(Offset->getType())); } else if (GEPOperator *GEPRHS = dyn_cast(RHS)) { @@ -5683,8 +5741,8 @@ (isa(GEPLHS) || GEPLHS->hasOneUse()) && (isa(GEPRHS) || GEPRHS->hasOneUse())) { // ((gep Ptr, OFFSET1) cmp (gep Ptr, OFFSET2) ---> (OFFSET1 cmp OFFSET2) - Value *L = EmitGEPOffset(GEPLHS, I, *this); - Value *R = EmitGEPOffset(GEPRHS, I, *this); + Value *L = EmitGEPOffset(GEPLHS, *this); + Value *R = EmitGEPOffset(GEPRHS, *this); return new ICmpInst(ICmpInst::getSignedPredicate(Cond), L, R); } } @@ -8201,8 +8259,7 @@ if (TD && GEP->hasOneUse() && isa(GEP->getOperand(0))) { if (GEP->hasAllConstantIndices()) { // We are guaranteed to get a constant from EmitGEPOffset. - ConstantInt *OffsetV = - cast(EmitGEPOffset(GEP, CI, *this)); + ConstantInt *OffsetV = cast(EmitGEPOffset(GEP, *this)); int64_t Offset = OffsetV->getSExtValue(); // Get the base pointer input of the bitcast, and the type it points to. @@ -11310,8 +11367,7 @@ !isa(BCI->getOperand(0)) && GEP.hasAllConstantIndices()) { // Determine how much the GEP moves the pointer. We are guaranteed to get // a constant back from EmitGEPOffset. - ConstantInt *OffsetV = - cast(EmitGEPOffset(&GEP, GEP, *this)); + ConstantInt *OffsetV = cast(EmitGEPOffset(&GEP, *this)); int64_t Offset = OffsetV->getSExtValue(); // If this GEP instruction doesn't move the pointer, just replace the GEP Modified: llvm/trunk/test/Transforms/InstCombine/sub.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sub.ll?rev=86021&r1=86020&r2=86021&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sub.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/sub.ll Wed Nov 4 02:05:20 2009 @@ -1,4 +1,6 @@ -; This test makes sure that these instructions are properly eliminated. +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" + +; Optimize subtracts. ; ; RUN: opt < %s -instcombine -S | FileCheck %s @@ -211,3 +213,38 @@ ; CHECK: ret i1 %tmp5 } +; rdar://7362831 +define i32 @test23(i8* %P, i64 %A){ + %B = getelementptr inbounds i8* %P, i64 %A + %C = ptrtoint i8* %B to i64 + %D = trunc i64 %C to i32 + %E = ptrtoint i8* %P to i64 + %F = trunc i64 %E to i32 + %G = sub i32 %D, %F + ret i32 %G +; CHECK: @test23 +; CHECK: %A1 = trunc i64 %A to i32 +; CHECK: ret i32 %A1 +} + +define i64 @test24(i8* %P, i64 %A){ + %B = getelementptr inbounds i8* %P, i64 %A + %C = ptrtoint i8* %B to i64 + %E = ptrtoint i8* %P to i64 + %G = sub i64 %C, %E + ret i64 %G +; CHECK: @test24 +; CHECK-NEXT: ret i64 %A +} + +define i64 @test24a(i8* %P, i64 %A){ + %B = getelementptr inbounds i8* %P, i64 %A + %C = ptrtoint i8* %B to i64 + %E = ptrtoint i8* %P to i64 + %G = sub i64 %E, %C + ret i64 %G +; CHECK: @test24a +; CHECK-NEXT: sub i64 0, %A +; CHECK-NEXT: ret i64 +} + From evan.cheng at apple.com Wed Nov 4 02:33:20 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 04 Nov 2009 08:33:20 -0000 Subject: [llvm-commits] [llvm] r86022 - in /llvm/trunk: lib/CodeGen/SimpleRegisterCoalescing.cpp test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll Message-ID: <200911040833.nA48XKjV019452@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 4 02:33:14 2009 New Revision: 86022 URL: http://llvm.org/viewvc/llvm-project?rev=86022&view=rev Log: RangeIsDefinedByCopyFromReg() should check for subreg_to_reg, insert_subreg, and extract_subreg as a "copy" that defines a valno. Also fixes a typo. These two issues prevent a simple subreg coalescing from happening before. Added: llvm/trunk/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=86022&r1=86021&r2=86022&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Wed Nov 4 02:33:14 2009 @@ -1369,7 +1369,7 @@ if (SrcSubIdx) SrcSubRC = SrcRC->getSubRegisterRegClass(SrcSubIdx); assert(SrcSubRC && "Illegal subregister index"); - if (!SrcSubRC->contains(DstReg)) { + if (!SrcSubRC->contains(DstSubReg)) { DEBUG(errs() << "\tIncompatible source regclass: " << tri_->getName(DstSubReg) << " not in " << SrcSubRC->getName() << ".\n"); @@ -1834,6 +1834,25 @@ return std::find(V.begin(), V.end(), Val) != V.end(); } +static bool isValNoDefMove(const MachineInstr *MI, unsigned DR, unsigned SR, + const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) { + unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; + if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) + ; + else if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { + DstReg = MI->getOperand(0).getReg(); + SrcReg = MI->getOperand(1).getReg(); + } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG || + MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { + DstReg = MI->getOperand(0).getReg(); + SrcReg = MI->getOperand(2).getReg(); + } else + return false; + return (SrcReg == SR || TRI->isSuperRegister(SR, SrcReg)) && + (DstReg == DR || TRI->isSuperRegister(DR, DstReg)); +} + /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of /// the specified live interval is defined by a copy from the specified /// register. @@ -1850,12 +1869,9 @@ // It's a sub-register live interval, we may not have precise information. // Re-compute it. MachineInstr *DefMI = li_->getInstructionFromIndex(LR->start); - unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; - if (DefMI && - tii_->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) && - DstReg == li.reg && SrcReg == Reg) { + if (DefMI && isValNoDefMove(DefMI, li.reg, Reg, tii_, tri_)) { // Cache computed info. - LR->valno->def = LR->start; + LR->valno->def = LR->start; LR->valno->setCopy(DefMI); return true; } Added: llvm/trunk/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll?rev=86022&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll (added) +++ llvm/trunk/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll Wed Nov 4 02:33:14 2009 @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin11 | FileCheck %s +; rdar://7362871 + +define void @bar(i32 %b, i32 %a) nounwind optsize ssp { +entry: +; CHECK: leal 15(%rsi), %edi +; CHECK-NOT: movl +; CHECK: call _foo + %0 = add i32 %a, 15 ; [#uses=1] + %1 = zext i32 %0 to i64 ; [#uses=1] + tail call void @foo(i64 %1) nounwind + ret void +} + +declare void @foo(i64) From evan.cheng at apple.com Wed Nov 4 02:36:50 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 04 Nov 2009 08:36:50 -0000 Subject: [llvm-commits] [llvm] r86023 - /llvm/trunk/utils/buildit/build_llvm Message-ID: <200911040836.nA48aobJ019556@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 4 02:36:50 2009 New Revision: 86023 URL: http://llvm.org/viewvc/llvm-project?rev=86023&view=rev Log: Look for llvm-gcc under /Developer/usr/bin first. Modified: llvm/trunk/utils/buildit/build_llvm Modified: llvm/trunk/utils/buildit/build_llvm URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/buildit/build_llvm?rev=86023&r1=86022&r2=86023&view=diff ============================================================================== --- llvm/trunk/utils/buildit/build_llvm (original) +++ llvm/trunk/utils/buildit/build_llvm Wed Nov 4 02:36:50 2009 @@ -127,7 +127,7 @@ # If the user has set CC or CXX, respect their wishes. If not, # compile with LLVM-GCC/LLVM-G++ if available; if LLVM is not # available, fall back to usual GCC/G++ default. - savedPATH=$PATH ; PATH="$PATH:/Developer/usr/bin" + savedPATH=$PATH ; PATH="/Developer/usr/bin:$PATH" XTMPCC=$(which llvm-gcc) if [ x$CC = x -a x$XTMPCC != x ] ; then export CC=$XTMPCC ; fi XTMPCC=$(which llvm-g++) From lessen42 at gmail.com Wed Nov 4 03:29:27 2009 From: lessen42 at gmail.com (David Conrad) Date: Wed, 4 Nov 2009 04:29:27 -0500 Subject: [llvm-commits] [llvm] r85697 - in /llvm/trunk: lib/Target/ARM/ARMInstrNEON.td test/CodeGen/ARM/fmacs.ll test/CodeGen/ARM/fnmacs.ll test/CodeGen/Thumb2/cross-rc-coalescing-2.ll In-Reply-To: <7098F362-DE42-4D5D-B84A-78C3ED93F2AA@apple.com> References: <200910312257.n9VMvbZm030355@zion.cs.uiuc.edu> <72AADD0D-6CAF-433E-8533-A8157E28F8D9@gmail.com> <7098F362-DE42-4D5D-B84A-78C3ED93F2AA@apple.com> Message-ID: <60FF8C44-7B05-4910-92B2-E6AF8E653DE9@gmail.com> On Nov 3, 2009, at 5:07 PM, Jim Grosbach wrote: > > On Nov 2, 2009, at 1:53 AM, David Conrad wrote: > >> Thus even without modeling the special behaviour of vmla it's always >> better to use it: it'll always be at least as fast as a separate vmul >> +vadd. This applies to the integer versions as well. > > > Hi David, > > Unfortunately, this turns out not to be the case. The NEON unit will > stall adjacent instructions in the presence of vmla to preserve in- > order retirement. If a RAW hazard is present, the stall is 8 > (possibly 7) cycles, otherwise it is 4 cycles. You're correct, sorry for the noise and wrong information. From grosbach at apple.com Wed Nov 4 09:54:58 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 4 Nov 2009 07:54:58 -0800 Subject: [llvm-commits] [llvm] r85697 - in /llvm/trunk: lib/Target/ARM/ARMInstrNEON.td test/CodeGen/ARM/fmacs.ll test/CodeGen/ARM/fnmacs.ll test/CodeGen/Thumb2/cross-rc-coalescing-2.ll In-Reply-To: <60FF8C44-7B05-4910-92B2-E6AF8E653DE9@gmail.com> References: <200910312257.n9VMvbZm030355@zion.cs.uiuc.edu> <72AADD0D-6CAF-433E-8533-A8157E28F8D9@gmail.com> <7098F362-DE42-4D5D-B84A-78C3ED93F2AA@apple.com> <60FF8C44-7B05-4910-92B2-E6AF8E653DE9@gmail.com> Message-ID: <6EE77ABE-BB3A-4421-9B44-258631F3D41D@apple.com> On Nov 4, 2009, at 1:29 AM, David Conrad wrote: > On Nov 3, 2009, at 5:07 PM, Jim Grosbach wrote: > >> >> On Nov 2, 2009, at 1:53 AM, David Conrad wrote: >> >>> Thus even without modeling the special behaviour of vmla it's always >>> better to use it: it'll always be at least as fast as a separate >>> vmul >>> +vadd. This applies to the integer versions as well. >> >> >> Hi David, >> >> Unfortunately, this turns out not to be the case. The NEON unit >> will stall adjacent instructions in the presence of vmla to >> preserve in-order retirement. If a RAW hazard is present, the stall >> is 8 (possibly 7) cycles, otherwise it is 4 cycles. > > You're correct, sorry for the noise and wrong information. No worries. Always better to talk it through and make sure things are right. Thanks for having a look and providing feedback! Regards, Jim From baldrick at free.fr Wed Nov 4 12:08:39 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 04 Nov 2009 18:08:39 -0000 Subject: [llvm-commits] [dragonegg] r86033 - in /dragonegg/trunk: llvm-convert.cpp llvm-internal.h Message-ID: <200911041808.nA4I8dQj026031@zion.cs.uiuc.edu> Author: baldrick Date: Wed Nov 4 12:08:38 2009 New Revision: 86033 URL: http://llvm.org/viewvc/llvm-project?rev=86033&view=rev Log: Add correct trampoline support. The issue here is that LLVM has one trampoline intrinsic, while gcc has two. The LLVM intrinsic combines the effect of the two gcc intrinsics. However since the gcc init and adjust intrinsics for the same trampoline can be called in different (nested) functions, using the LLVM intrinsic requires storing its result in the stack frame object passed to nested functions as the static chain. In llvm-gcc this is taken care of by creating a variable for this during nested function lowering. However dragonegg does not have this luxury. In fact there's only one place we can put it: the storage that was intended by gcc to be used for holding the trampoline machine code. So put it there, and place the machine code in a separate stack temporary. Modified: dragonegg/trunk/llvm-convert.cpp dragonegg/trunk/llvm-internal.h Modified: dragonegg/trunk/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=86033&r1=86032&r2=86033&view=diff ============================================================================== --- dragonegg/trunk/llvm-convert.cpp (original) +++ dragonegg/trunk/llvm-convert.cpp Wed Nov 4 12:08:38 2009 @@ -4406,6 +4406,8 @@ return EmitBuiltinExtractReturnAddr(stmt, Result); case BUILT_IN_FROB_RETURN_ADDR: return EmitBuiltinFrobReturnAddr(stmt, Result); + case BUILT_IN_ADJUST_TRAMPOLINE: + return EmitBuiltinAdjustTrampoline(stmt, Result); case BUILT_IN_INIT_TRAMPOLINE: return EmitBuiltinInitTrampoline(stmt, Result); @@ -5631,27 +5633,76 @@ return true; } +bool TreeToLLVM::EmitBuiltinAdjustTrampoline(gimple stmt, Value *&Result) { + if (!validate_gimple_arglist(stmt, POINTER_TYPE, VOID_TYPE)) + return false; + + const Type *ResultTy = ConvertType(gimple_call_return_type(stmt)); + + // The adjusted value is stored as a pointer at the start of the storage GCC + // allocated for the trampoline - load it out and return it. + assert(TD.getPointerSize() <= TRAMPOLINE_SIZE && + "Trampoline smaller than a pointer!"); + Value *Tramp = EmitGimpleReg(gimple_call_arg(stmt, 0)); + Tramp = Builder.CreateBitCast(Tramp, ResultTy->getPointerTo()); + Result = Builder.CreateLoad(Tramp, "adjusted"); + + // The load has the alignment of the trampoline storage. + unsigned Align = TYPE_ALIGN(TREE_TYPE(TREE_TYPE(gimple_call_arg(stmt, 0))))/8; + cast(Result)->setAlignment(Align); + + return true; +} + bool TreeToLLVM::EmitBuiltinInitTrampoline(gimple stmt, Value *&Result) { if (!validate_gimple_arglist(stmt, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) return false; + // LLVM's trampoline intrinsic, llvm.init.trampoline, combines the effect of + // GCC's init_trampoline and adjust_trampoline. Calls to adjust_trampoline + // should return the result of the llvm.init.trampoline call. This is tricky + // because the adjust_trampoline and init_trampoline calls need not occur in + // the same function. To overcome this, we don't store the trampoline machine + // code in the storage GCC created for it, we store the result of the call to + // llvm.init.trampoline there instead. Since this storage is the argument to + // adjust_trampoline, we turn adjust_trampoline into a load from its argument. + // The trampoline machine code itself is stored in a stack temporary that we + // create (one for each init_trampoline) in the function where init_trampoline + // is called. static const Type *VPTy = Type::getInt8PtrTy(Context); - Value *Tramp = Emit(gimple_call_arg(stmt, 0), 0); - Tramp = Builder.CreateBitCast(Tramp, VPTy); + // Create a stack temporary to hold the trampoline machine code. + const Type *TrampType = ArrayType::get(Type::getInt8Ty(Context), + TRAMPOLINE_SIZE); + AllocaInst *TrampTmp = CreateTemporary(TrampType); + TrampTmp->setAlignment(TRAMPOLINE_ALIGNMENT); + TrampTmp->setName("TRAMP"); Value *Func = Emit(gimple_call_arg(stmt, 1), 0); - Func = Builder.CreateBitCast(Func, VPTy); - Value *Chain = Emit(gimple_call_arg(stmt, 2), 0); - Chain = Builder.CreateBitCast(Chain, VPTy); - Value *Ops[3] = { Tramp, Func, Chain }; + Value *Ops[3] = { + Builder.CreateBitCast(TrampTmp, VPTy), + Builder.CreateBitCast(Func, VPTy), + Builder.CreateBitCast(Chain, VPTy) + }; Function *Intr = Intrinsic::getDeclaration(TheModule, Intrinsic::init_trampoline); - Result = Builder.CreateCall(Intr, Ops, Ops+3, "tramp"); + Value *Adjusted = Builder.CreateCall(Intr, Ops, Ops + 3, "adjusted"); + + // Store the llvm.init.trampoline result to the GCC trampoline storage. + assert(TD.getPointerSize() <= TRAMPOLINE_SIZE && + "Trampoline smaller than a pointer!"); + Value *Tramp = Emit(gimple_call_arg(stmt, 0), 0); + Tramp = Builder.CreateBitCast(Tramp, Adjusted->getType()->getPointerTo()); + StoreInst *Store = Builder.CreateStore(Adjusted, Tramp); + + // The store has the alignment of the trampoline storage. + unsigned Align = TYPE_ALIGN(TREE_TYPE(TREE_TYPE(gimple_call_arg(stmt, 0))))/8; + Store->setAlignment(Align); + return true; } Modified: dragonegg/trunk/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=86033&r1=86032&r2=86033&view=diff ============================================================================== --- dragonegg/trunk/llvm-internal.h (original) +++ dragonegg/trunk/llvm-internal.h Wed Nov 4 12:08:38 2009 @@ -674,6 +674,7 @@ bool EmitBuiltinEHReturn(gimple stmt, Value *&Result); bool EmitBuiltinInitDwarfRegSizes(gimple stmt, Value *&Result); bool EmitBuiltinUnwindInit(gimple stmt, Value *&Result); + bool EmitBuiltinAdjustTrampoline(gimple stmt, Value *&Result); bool EmitBuiltinInitTrampoline(gimple stmt, Value *&Result); // Complex Math Expressions. From clattner at apple.com Wed Nov 4 12:10:15 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 4 Nov 2009 10:10:15 -0800 Subject: [llvm-commits] [llvm] r86009 - /llvm/trunk/docs/GettingStarted.html In-Reply-To: <200911040615.nA46FStr014546@zion.cs.uiuc.edu> References: <200911040615.nA46FStr014546@zion.cs.uiuc.edu> Message-ID: <69E5E751-3512-4E12-A25C-8297DC25E398@apple.com> On Nov 3, 2009, at 10:15 PM, Nick Lewycky wrote: > Author: nicholas > Date: Wed Nov 4 00:15:28 2009 > New Revision: 86009 > > URL: http://llvm.org/viewvc/llvm-project?rev=86009&view=rev > Log: > The magic for our current brand of .bc files is BC. For older ones > it was llvc. > When was it ever "llvm"? That was before Reid made LLVM BC files be gzip'ed internally, I vaguely remember that this was ~ LLVM 1.3. -Chris > > Modified: > llvm/trunk/docs/GettingStarted.html > > Modified: llvm/trunk/docs/GettingStarted.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/GettingStarted.html?rev=86009&r1=86008&r2=86009&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/docs/GettingStarted.html (original) > +++ llvm/trunk/docs/GettingStarted.html Wed Nov 4 00:15:28 2009 > @@ -1154,7 +1154,7 @@ >
                          >
                          > $ mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
                          > -$ echo ':llvm:M::llvm::/path/to/lli:' > /proc/sys/fs/binfmt_misc/ 
                          > register
                          > +$ echo ':llvm:M::BC::/path/to/lli:' > /proc/sys/fs/binfmt_misc/ 
                          > register
                          > $ chmod u+x hello.bc   (if needed)
                          > $ ./hello.bc
                          > 
                          > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From grosbach at apple.com Wed Nov 4 12:40:08 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 04 Nov 2009 18:40:08 -0000 Subject: [llvm-commits] [test-suite] r86035 - /test-suite/trunk/Makefile.programs Message-ID: <200911041840.nA4Ie8xA027248@zion.cs.uiuc.edu> Author: grosbach Date: Wed Nov 4 12:40:08 2009 New Revision: 86035 URL: http://llvm.org/viewvc/llvm-project?rev=86035&view=rev Log: back to dynamic stack alignment for ARM LLCBETA Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=86035&r1=86034&r2=86035&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Nov 4 12:40:08 2009 @@ -244,12 +244,12 @@ LLCBETAOPTION := -enable-sparc-v9-insts endif ifeq ($(ARCH),ARM) -LLCBETAOPTION := -arm-use-neon-fp=0 +LLCBETAOPTION := -arm-dynamic-stack-alignment #-combiner-alias-analysis #-schedule-livein-copies endif ifeq ($(ARCH),THUMB) -LLCBETAOPTION := -arm-use-neon-fp=0 +LLCBETAOPTION := -arm-dynamic-stack-alignment #-combiner-alias-analysis #-enable-thumb-reg-scavenging endif From sabre at nondot.org Wed Nov 4 12:57:42 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 04 Nov 2009 18:57:42 -0000 Subject: [llvm-commits] [llvm] r86036 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200911041857.nA4Ivgc2027935@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 4 12:57:42 2009 New Revision: 86036 URL: http://llvm.org/viewvc/llvm-project?rev=86036&view=rev Log: Fix an iterator invalidation bug that happens when a hashtable resizes in IPSCCP. This fixes PR5394. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=86036&r1=86035&r2=86036&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Wed Nov 4 12:57:42 2009 @@ -1280,9 +1280,10 @@ } if (const StructType *STy = dyn_cast(AI->getType())) { - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) - mergeInValue(getStructValueState(AI, i), AI, - getStructValueState(*CAI, i)); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + LatticeVal CallArg = getStructValueState(*CAI, i); + mergeInValue(getStructValueState(AI, i), AI, CallArg); + } } else { mergeInValue(AI, getValueState(*CAI)); } From stoklund at 2pi.dk Wed Nov 4 13:24:37 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 04 Nov 2009 19:24:37 -0000 Subject: [llvm-commits] [llvm] r86041 - in /llvm/trunk: include/llvm/CodeGen/AsmPrinter.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp lib/Target/X86/AsmPrinter/X86MCInstLower.cpp Message-ID: <200911041924.nA4JOc2D029091@zion.cs.uiuc.edu> Author: stoklund Date: Wed Nov 4 13:24:37 2009 New Revision: 86041 URL: http://llvm.org/viewvc/llvm-project?rev=86041&view=rev Log: Print out an informative comment for KILL instructions. The KILL pseudo-instruction may survive to the asm printer pass, just like the IMPLICIT_DEF. Print the KILL as a comment instead of just leaving a blank line in the output. With -asm-verbose=0, a blank line is printed, like IMPLICIT?DEF. Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp llvm/trunk/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp llvm/trunk/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=86041&r1=86040&r2=86041&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original) +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Wed Nov 4 13:24:37 2009 @@ -374,8 +374,10 @@ /// printImplicitDef - This method prints the specified machine instruction /// that is an implicit def. virtual void printImplicitDef(const MachineInstr *MI) const; - - + + /// printKill - This method prints the specified kill machine instruction. + virtual void printKill(const MachineInstr *MI) const; + /// printPICJumpTableSetLabel - This method prints a set label for the /// specified MachineBasicBlock for a jumptable entry. virtual void printPICJumpTableSetLabel(unsigned uid, Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=86041&r1=86040&r2=86041&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Wed Nov 4 13:24:37 2009 @@ -1590,6 +1590,17 @@ << TRI->getName(MI->getOperand(0).getReg()); } +void AsmPrinter::printKill(const MachineInstr *MI) const { + if (!VerboseAsm) return; + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " kill:"; + for (unsigned n = 0, e = MI->getNumOperands(); n != e; ++n) { + const MachineOperand &op = MI->getOperand(n); + assert(op.isReg() && "KILL instruction must have only register operands"); + O << ' ' << TRI->getName(op.getReg()) << (op.isDef() ? "" : ""); + } +} + /// printLabel - This method prints a local label used by debug and /// exception handling tables. void AsmPrinter::printLabel(const MachineInstr *MI) const { Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=86041&r1=86040&r2=86041&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Wed Nov 4 13:24:37 2009 @@ -1346,6 +1346,7 @@ printLabel(MI); return; case TargetInstrInfo::KILL: + printKill(MI); return; case TargetInstrInfo::INLINEASM: O << '\t'; Modified: llvm/trunk/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp?rev=86041&r1=86040&r2=86041&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp Wed Nov 4 13:24:37 2009 @@ -306,6 +306,7 @@ printLabel(MI); return; case TargetInstrInfo::KILL: + printKill(MI); return; case TargetInstrInfo::INLINEASM: O << '\t'; Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp?rev=86041&r1=86040&r2=86041&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp Wed Nov 4 13:24:37 2009 @@ -412,6 +412,7 @@ printImplicitDef(MI); return; case TargetInstrInfo::KILL: + printKill(MI); return; case X86::MOVPC32r: { MCInst TmpInst; From bob.wilson at apple.com Wed Nov 4 13:25:34 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 04 Nov 2009 19:25:34 -0000 Subject: [llvm-commits] [llvm] r86042 - /llvm/trunk/test/CodeGen/ARM/indirectbr.ll Message-ID: <200911041925.nA4JPZ83029141@zion.cs.uiuc.edu> Author: bwilson Date: Wed Nov 4 13:25:34 2009 New Revision: 86042 URL: http://llvm.org/viewvc/llvm-project?rev=86042&view=rev Log: Add test for ARM indirectbr codegen. Added: llvm/trunk/test/CodeGen/ARM/indirectbr.ll Added: llvm/trunk/test/CodeGen/ARM/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/indirectbr.ll?rev=86042&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/indirectbr.ll (added) +++ llvm/trunk/test/CodeGen/ARM/indirectbr.ll Wed Nov 4 13:25:34 2009 @@ -0,0 +1,63 @@ +; RUN: llc < %s -relocation-model=pic -march=arm | FileCheck %s -check-prefix=ARM +; RUN: llc < %s -relocation-model=pic -march=thumb | FileCheck %s -check-prefix=THUMB +; RUN: llc < %s -relocation-model=static -march=thumb -mattr=+thumb2 | FileCheck %s -check-prefix=THUMB2 + + at nextaddr = global i8* null ; [#uses=2] + at C.0.2070 = private constant [5 x i8*] [i8* blockaddress(@foo, %L1), i8* blockaddress(@foo, %L2), i8* blockaddress(@foo, %L3), i8* blockaddress(@foo, %L4), i8* blockaddress(@foo, %L5)] ; <[5 x i8*]*> [#uses=1] + +define internal arm_apcscc i32 @foo(i32 %i) nounwind { +; ARM: foo: +; THUMB: foo: +; THUMB2: foo: +entry: + %0 = load i8** @nextaddr, align 4 ; [#uses=2] + %1 = icmp eq i8* %0, null ; [#uses=1] + br i1 %1, label %bb3, label %bb2 + +bb2: ; preds = %entry, %bb3 + %gotovar.4.0 = phi i8* [ %gotovar.4.0.pre, %bb3 ], [ %0, %entry ] ; [#uses=1] +; ARM: bx +; THUMB: mov pc, r1 +; THUMB2: mov pc, r1 + indirectbr i8* %gotovar.4.0, [label %L5, label %L4, label %L3, label %L2, label %L1] + +bb3: ; preds = %entry + %2 = getelementptr inbounds [5 x i8*]* @C.0.2070, i32 0, i32 %i ; [#uses=1] + %gotovar.4.0.pre = load i8** %2, align 4 ; [#uses=1] + br label %bb2 + +L5: ; preds = %bb2 + br label %L4 + +L4: ; preds = %L5, %bb2 + %res.0 = phi i32 [ 385, %L5 ], [ 35, %bb2 ] ; [#uses=1] + br label %L3 + +L3: ; preds = %L4, %bb2 + %res.1 = phi i32 [ %res.0, %L4 ], [ 5, %bb2 ] ; [#uses=1] + br label %L2 + +L2: ; preds = %L3, %bb2 + %res.2 = phi i32 [ %res.1, %L3 ], [ 1, %bb2 ] ; [#uses=1] + %phitmp = mul i32 %res.2, 6 ; [#uses=1] + br label %L1 + +L1: ; preds = %L2, %bb2 + %res.3 = phi i32 [ %phitmp, %L2 ], [ 2, %bb2 ] ; [#uses=1] +; ARM: ldr r1, LCPI1_2 +; ARM: add r1, pc, r1 +; ARM: str r1 +; THUMB: ldr r2, LCPI1_4 +; THUMB: add r2, pc +; THUMB: str r2 +; THUMB2: ldr r2, LCPI1_2 +; THUMB2-NEXT: str r2 + store i8* blockaddress(@foo, %L5), i8** @nextaddr, align 4 + ret i32 %res.3 +} +; ARM: LCPI1_2: +; ARM-NEXT: .long L_foo_L5-(LPC2+8) +; THUMB: LCPI1_4: +; THUMB-NEXT: .long L_foo_L5-(LPC2+4) +; THUMB2: LCPI1_2: +; THUMB2-NEXT: .long L_foo_L5 From gohman at apple.com Wed Nov 4 13:28:19 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 4 Nov 2009 11:28:19 -0800 Subject: [llvm-commits] [llvm] r85922 - /llvm/trunk/lib/Support/MemoryBuffer.cpp In-Reply-To: <4AF08DBF.7090005@free.fr> References: <200911031910.nA3JAM5b022573@zion.cs.uiuc.edu> <4AF08DBF.7090005@free.fr> Message-ID: On Nov 3, 2009, at 12:08 PM, Duncan Sands wrote: > Hi Dan, > >>> --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) >>> +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Tue Nov 3 13:10:22 2009 >>> @@ -226,7 +226,7 @@ >>> size_t BytesLeft = FileSize; >>> while (BytesLeft) { >>> ssize_t NumRead = ::read(FD, BufPtr, BytesLeft); >>> - if (NumRead != -1) { >>> + if (NumRead > 0) { >>> BytesLeft -= NumRead; >>> BufPtr += NumRead; >>> } else if (errno == EINTR) { >> Given this, the code should explicitly set errno to 0 so that it doesn't >> infinite loop if it reaches the end of the file and errno happens to >> have the value EINTR. > > if errno is EINTR, isn't it correct to go around again, even if zero bytes > were read? read could return 0 and leave errno unmodified. errno could be set to EINTR by unrelated code before the first read call. If read keeps returning 0 for some reason, the code wouldn't recover. Dan From dpatel at apple.com Wed Nov 4 13:37:40 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 04 Nov 2009 19:37:40 -0000 Subject: [llvm-commits] [llvm] r86043 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200911041937.nA4JbekB029552@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 4 13:37:40 2009 New Revision: 86043 URL: http://llvm.org/viewvc/llvm-project?rev=86043&view=rev Log: Array element size does not match array size but array is not a bitfield. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86043&r1=86042&r2=86043&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Nov 4 13:37:40 2009 @@ -1138,7 +1138,9 @@ AddSourceLine(MemberDie, &DT); uint64_t Size = DT.getSizeInBits(); - uint64_t FieldSize = DT.getOriginalTypeSize(); + uint64_t FieldSize = Size; + if (DT.getTypeDerivedFrom().getTag() != dwarf::DW_TAG_array_type) + FieldSize = DT.getOriginalTypeSize(); if (Size != FieldSize) { // Handle bitfield. From echristo at apple.com Wed Nov 4 13:57:50 2009 From: echristo at apple.com (Eric Christopher) Date: Wed, 04 Nov 2009 19:57:50 -0000 Subject: [llvm-commits] [llvm] r86044 - /llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Message-ID: <200911041957.nA4Jvo3g030547@zion.cs.uiuc.edu> Author: echristo Date: Wed Nov 4 13:57:50 2009 New Revision: 86044 URL: http://llvm.org/viewvc/llvm-project?rev=86044&view=rev Log: Add some options to disable various code gen optimizations. Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=86044&r1=86043&r2=86044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Wed Nov 4 13:57:50 2009 @@ -31,6 +31,22 @@ bool EnableFastISel; } +static cl::opt DisablePostRA("disable-post-ra", cl::Hidden, + cl::desc("Disable Post Regalloc")); +static cl::opt DisableBranchFold("disable-branch-fold", cl::Hidden, + cl::desc("Disable branch folding")); +static cl::opt DisableCodePlace("disable-code-place", cl::Hidden, + cl::desc("Disable code placement")); +static cl::opt DisableSSC("disable-ssc", cl::Hidden, + cl::desc("Disable Stack Slot Coloring")); +static cl::opt DisableMachineLICM("disable-machine-licm", cl::Hidden, + cl::desc("Disable Machine LICM")); +static cl::opt DisableMachineSink("disable-machine-sink", cl::Hidden, + cl::desc("Disable Machine Sinking")); +static cl::opt DisableLSR("disable-lsr", cl::Hidden, + cl::desc("Disable Loop Strength Reduction Pass")); +static cl::opt DisableCGP("disable-cgp", cl::Hidden, + cl::desc("Disable Codegen Prepare")); static cl::opt PrintLSR("print-lsr-output", cl::Hidden, cl::desc("Print LLVM IR produced by the loop-reduce pass")); static cl::opt PrintISelInput("print-isel-input", cl::Hidden, @@ -208,7 +224,7 @@ // Standard LLVM-Level Passes. // Run loop strength reduction before anything else. - if (OptLevel != CodeGenOpt::None) { + if (OptLevel != CodeGenOpt::None && !DisableLSR) { PM.add(createLoopStrengthReducePass(getTargetLowering())); if (PrintLSR) PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &errs())); @@ -236,7 +252,7 @@ // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); - if (OptLevel != CodeGenOpt::None) + if (OptLevel != CodeGenOpt::None && !DisableCGP) PM.add(createCodeGenPreparePass(getTargetLowering())); PM.add(createStackProtectorPass(getTargetLowering())); @@ -265,8 +281,10 @@ /* allowDoubleDefs= */ true); if (OptLevel != CodeGenOpt::None) { - PM.add(createMachineLICMPass()); - PM.add(createMachineSinkingPass()); + if (!DisableMachineLICM) + PM.add(createMachineLICMPass()); + if (!DisableMachineSink) + PM.add(createMachineSinkingPass()); printAndVerify(PM, "After MachineLICM and MachineSinking", /* allowDoubleDefs= */ true); } @@ -281,7 +299,7 @@ printAndVerify(PM, "After Register Allocation"); // Perform stack slot coloring. - if (OptLevel != CodeGenOpt::None) { + if (OptLevel != CodeGenOpt::None && !DisableSSC) { // FIXME: Re-enable coloring with register when it's capable of adding // kill markers. PM.add(createStackSlotColoringPass(false)); @@ -304,13 +322,13 @@ printAndVerify(PM, "After PreSched2 passes"); // Second pass scheduler. - if (OptLevel != CodeGenOpt::None) { + if (OptLevel != CodeGenOpt::None && !DisablePostRA) { PM.add(createPostRAScheduler(OptLevel)); printAndVerify(PM, "After PostRAScheduler"); } // Branch folding must be run after regalloc and prolog/epilog insertion. - if (OptLevel != CodeGenOpt::None) { + if (OptLevel != CodeGenOpt::None && !DisableBranchFold) { PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); printAndVerify(PM, "After BranchFolding"); } @@ -327,7 +345,7 @@ if (addPreEmitPass(PM, OptLevel)) printAndVerify(PM, "After PreEmit passes"); - if (OptLevel != CodeGenOpt::None) { + if (OptLevel != CodeGenOpt::None && !DisableCodePlace) { PM.add(createCodePlacementOptPass()); printAndVerify(PM, "After CodePlacementOpt"); } From bob.wilson at apple.com Wed Nov 4 14:04:11 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 04 Nov 2009 20:04:11 -0000 Subject: [llvm-commits] [llvm] r86045 - /llvm/trunk/test/CodeGen/ARM/indirectbr.ll Message-ID: <200911042004.nA4K4BGq030757@zion.cs.uiuc.edu> Author: bwilson Date: Wed Nov 4 14:04:11 2009 New Revision: 86045 URL: http://llvm.org/viewvc/llvm-project?rev=86045&view=rev Log: Fix broken test. Modified: llvm/trunk/test/CodeGen/ARM/indirectbr.ll Modified: llvm/trunk/test/CodeGen/ARM/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/indirectbr.ll?rev=86045&r1=86044&r2=86045&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/indirectbr.ll (original) +++ llvm/trunk/test/CodeGen/ARM/indirectbr.ll Wed Nov 4 14:04:11 2009 @@ -47,10 +47,10 @@ ; ARM: ldr r1, LCPI1_2 ; ARM: add r1, pc, r1 ; ARM: str r1 -; THUMB: ldr r2, LCPI1_4 +; THUMB: ldr.n r2, LCPI1_4 ; THUMB: add r2, pc ; THUMB: str r2 -; THUMB2: ldr r2, LCPI1_2 +; THUMB2: ldr.n r2, LCPI1_2 ; THUMB2-NEXT: str r2 store i8* blockaddress(@foo, %L5), i8** @nextaddr, align 4 ret i32 %res.3 From baldrick at free.fr Wed Nov 4 14:50:24 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 04 Nov 2009 20:50:24 -0000 Subject: [llvm-commits] [llvm] r86046 - /llvm/trunk/lib/Support/MemoryBuffer.cpp Message-ID: <200911042050.nA4KoOlV032343@zion.cs.uiuc.edu> Author: baldrick Date: Wed Nov 4 14:50:23 2009 New Revision: 86046 URL: http://llvm.org/viewvc/llvm-project?rev=86046&view=rev Log: A value is only assigned to errno if NumRead equals -1, so do not reason based on errno if NumRead has a different value. Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryBuffer.cpp?rev=86046&r1=86045&r2=86046&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Wed Nov 4 14:50:23 2009 @@ -229,7 +229,7 @@ if (NumRead > 0) { BytesLeft -= NumRead; BufPtr += NumRead; - } else if (errno == EINTR) { + } else if (NumRead == -1 && errno == EINTR) { // try again } else { // error reading. From baldrick at free.fr Wed Nov 4 14:50:58 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 04 Nov 2009 21:50:58 +0100 Subject: [llvm-commits] [llvm] r85922 - /llvm/trunk/lib/Support/MemoryBuffer.cpp In-Reply-To: References: <200911031910.nA3JAM5b022573@zion.cs.uiuc.edu> <4AF08DBF.7090005@free.fr> Message-ID: <4AF1E932.2010301@free.fr> Hi Dan, >> if errno is EINTR, isn't it correct to go around again, even if zero bytes >> were read? > > read could return 0 and leave errno unmodified. errno could be set to > EINTR by unrelated code before the first read call. If read keeps > returning 0 for some reason, the code wouldn't recover. fair enough. Fixed in commit 86046. Ciao, Duncan. From lhames at gmail.com Wed Nov 4 15:24:16 2009 From: lhames at gmail.com (Lang Hames) Date: Wed, 04 Nov 2009 21:24:16 -0000 Subject: [llvm-commits] [llvm] r86049 - in /llvm/trunk: include/llvm/CodeGen/SlotIndexes.h lib/CodeGen/SlotIndexes.cpp Message-ID: <200911042124.nA4LOGUs001039@zion.cs.uiuc.edu> Author: lhames Date: Wed Nov 4 15:24:15 2009 New Revision: 86049 URL: http://llvm.org/viewvc/llvm-project?rev=86049&view=rev Log: Handle empty/tombstone keys for LiveIndex more cleanly. Check for index sanity when constructing index list entries. Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h llvm/trunk/lib/CodeGen/SlotIndexes.cpp Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SlotIndexes.h?rev=86049&r1=86048&r2=86049&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Wed Nov 4 15:24:15 2009 @@ -28,6 +28,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/ErrorHandling.h" namespace llvm { @@ -38,14 +39,35 @@ class IndexListEntry { private: + static std::auto_ptr emptyKeyEntry, + tombstoneKeyEntry; + typedef enum { EMPTY_KEY, TOMBSTONE_KEY } ReservedEntryType; + static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U, + TOMBSTONE_KEY_INDEX = ~0U & ~7U; + IndexListEntry *next, *prev; MachineInstr *mi; unsigned index; + // This constructor is only to be used by getEmptyKeyEntry + // & getTombstoneKeyEntry. It sets index to the given + // value and mi to zero. + IndexListEntry(ReservedEntryType r) : mi(0) { + switch(r) { + case EMPTY_KEY: index = EMPTY_KEY_INDEX; break; + case TOMBSTONE_KEY: index = TOMBSTONE_KEY_INDEX; break; + default: assert(false && "Invalid value for constructor."); + } + } + public: - IndexListEntry(MachineInstr *mi, unsigned index) - : mi(mi), index(index) {} + IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) { + if (index == EMPTY_KEY_INDEX || index == TOMBSTONE_KEY_INDEX) { + llvm_report_error("Attempt to create invalid index. " + "Available indexes may have been exhausted?."); + } + } MachineInstr* getInstr() const { return mi; } void setInstr(MachineInstr *mi) { this->mi = mi; } @@ -60,6 +82,24 @@ IndexListEntry* getPrev() { return prev; } const IndexListEntry* getPrev() const { return prev; } void setPrev(IndexListEntry *prev) { this->prev = prev; } + + // This function returns the index list entry that is to be used for empty + // SlotIndex keys. + static IndexListEntry* getEmptyKeyEntry() { + if (emptyKeyEntry.get() == 0) { + emptyKeyEntry.reset(new IndexListEntry(EMPTY_KEY)); + } + return emptyKeyEntry.get(); + } + + // This function returns the index list entry that is to be used for + // tombstone SlotIndex keys. + static IndexListEntry* getTombstoneKeyEntry() { + if (tombstoneKeyEntry.get() == 0) { + tombstoneKeyEntry.reset(new IndexListEntry(TOMBSTONE_KEY)); + } + return tombstoneKeyEntry.get(); + } }; // Specialize PointerLikeTypeTraits for IndexListEntry. @@ -81,10 +121,6 @@ friend class DenseMapInfo; private: - - // FIXME: Is there any way to statically allocate these things and have - // them 8-byte aligned? - static std::auto_ptr emptyKeyPtr, tombstoneKeyPtr; static const unsigned PHI_BIT = 1 << 2; PointerIntPair lie; @@ -116,21 +152,11 @@ enum Slot { LOAD, USE, DEF, STORE, NUM }; static inline SlotIndex getEmptyKey() { - // FIXME: How do we guarantee these numbers don't get allocated to - // legit indexes? - if (emptyKeyPtr.get() == 0) - emptyKeyPtr.reset(new IndexListEntry(0, ~0U & ~3U)); - - return SlotIndex(emptyKeyPtr.get(), 0); + return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0); } static inline SlotIndex getTombstoneKey() { - // FIXME: How do we guarantee these numbers don't get allocated to - // legit indexes? - if (tombstoneKeyPtr.get() == 0) - tombstoneKeyPtr.reset(new IndexListEntry(0, ~0U & ~7U)); - - return SlotIndex(tombstoneKeyPtr.get(), 0); + return SlotIndex(IndexListEntry::getTombstoneKeyEntry(), 0); } /// Construct an invalid index. Modified: llvm/trunk/lib/CodeGen/SlotIndexes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SlotIndexes.cpp?rev=86049&r1=86048&r2=86049&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SlotIndexes.cpp (original) +++ llvm/trunk/lib/CodeGen/SlotIndexes.cpp Wed Nov 4 15:24:15 2009 @@ -16,8 +16,8 @@ using namespace llvm; -std::auto_ptr SlotIndex::emptyKeyPtr(0), - SlotIndex::tombstoneKeyPtr(0); +std::auto_ptr IndexListEntry::emptyKeyEntry, + IndexListEntry::tombstoneKeyEntry; char SlotIndexes::ID = 0; static RegisterPass X("slotindexes", "Slot index numbering"); From bob.wilson at apple.com Wed Nov 4 15:31:18 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 04 Nov 2009 21:31:18 -0000 Subject: [llvm-commits] [llvm] r86050 - in /llvm/trunk: lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/PowerPC/PPCInstr64Bit.td lib/Target/PowerPC/PPCInstrInfo.td test/CodeGen/PowerPC/indirectbr.ll Message-ID: <200911042131.nA4LVJqT001280@zion.cs.uiuc.edu> Author: bwilson Date: Wed Nov 4 15:31:18 2009 New Revision: 86050 URL: http://llvm.org/viewvc/llvm-project?rev=86050&view=rev Log: Add PowerPC codegen for indirect branches. Added: llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=86050&r1=86049&r2=86050&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Wed Nov 4 15:31:18 2009 @@ -414,6 +414,9 @@ O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' << MO.getIndex(); return; + case MachineOperand::MO_BlockAddress: + GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI); + return; case MachineOperand::MO_ExternalSymbol: { // Computing the address of an external symbol, not calling it. std::string Name(MAI->getGlobalPrefix()); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=86050&r1=86049&r2=86050&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Nov 4 15:31:18 2009 @@ -196,10 +196,12 @@ // appropriate instructions to materialize the address. setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); + setOperationAction(ISD::BlockAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); setOperationAction(ISD::JumpTable, MVT::i32, Custom); setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom); + setOperationAction(ISD::BlockAddress, MVT::i64, Custom); setOperationAction(ISD::ConstantPool, MVT::i64, Custom); setOperationAction(ISD::JumpTable, MVT::i64, Custom); @@ -1167,6 +1169,36 @@ return SDValue(); // Not reached } +SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) { + EVT PtrVT = Op.getValueType(); + DebugLoc DL = Op.getDebugLoc(); + + BlockAddress *BA = cast(Op)->getBlockAddress(); + SDValue TgtBA = DAG.getBlockAddress(BA, DL, /*isTarget=*/true); + SDValue Zero = DAG.getConstant(0, PtrVT); + SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, TgtBA, Zero); + SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, TgtBA, Zero); + + // If this is a non-darwin platform, we don't support non-static relo models + // yet. + const TargetMachine &TM = DAG.getTarget(); + if (TM.getRelocationModel() == Reloc::Static || + !TM.getSubtarget().isDarwin()) { + // Generate non-pic code that has direct accesses to globals. + // The address of the global is just (hi(&g)+lo(&g)). + return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo); + } + + if (TM.getRelocationModel() == Reloc::PIC_) { + // With PIC, the first instruction is actually "GR+hi(&G)". + Hi = DAG.getNode(ISD::ADD, DL, PtrVT, + DAG.getNode(PPCISD::GlobalBaseReg, + DebugLoc::getUnknownLoc(), PtrVT), Hi); + } + + return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo); +} + SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { EVT PtrVT = Op.getValueType(); @@ -4181,6 +4213,7 @@ switch (Op.getOpcode()) { default: llvm_unreachable("Wasn't expecting to be able to lower this!"); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); + case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=86050&r1=86049&r2=86050&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Wed Nov 4 15:31:18 2009 @@ -361,6 +361,7 @@ SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG); SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG); SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG); + SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=86050&r1=86049&r2=86050&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Wed Nov 4 15:31:18 2009 @@ -731,9 +731,13 @@ def : Pat<(PPClo tconstpool:$in , 0), (LI8 tconstpool:$in)>; def : Pat<(PPChi tjumptable:$in , 0), (LIS8 tjumptable:$in)>; def : Pat<(PPClo tjumptable:$in , 0), (LI8 tjumptable:$in)>; +def : Pat<(PPChi tblockaddress:$in, 0), (LIS8 tblockaddress:$in)>; +def : Pat<(PPClo tblockaddress:$in, 0), (LI8 tblockaddress:$in)>; def : Pat<(add G8RC:$in, (PPChi tglobaladdr:$g, 0)), (ADDIS8 G8RC:$in, tglobaladdr:$g)>; def : Pat<(add G8RC:$in, (PPChi tconstpool:$g, 0)), (ADDIS8 G8RC:$in, tconstpool:$g)>; def : Pat<(add G8RC:$in, (PPChi tjumptable:$g, 0)), (ADDIS8 G8RC:$in, tjumptable:$g)>; +def : Pat<(add G8RC:$in, (PPChi tblockaddress:$g, 0)), + (ADDIS8 G8RC:$in, tblockaddress:$g)>; Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=86050&r1=86049&r2=86050&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Wed Nov 4 15:31:18 2009 @@ -1436,12 +1436,16 @@ def : Pat<(PPClo tconstpool:$in, 0), (LI tconstpool:$in)>; def : Pat<(PPChi tjumptable:$in, 0), (LIS tjumptable:$in)>; def : Pat<(PPClo tjumptable:$in, 0), (LI tjumptable:$in)>; +def : Pat<(PPChi tblockaddress:$in, 0), (LIS tblockaddress:$in)>; +def : Pat<(PPClo tblockaddress:$in, 0), (LI tblockaddress:$in)>; def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), (ADDIS GPRC:$in, tglobaladdr:$g)>; def : Pat<(add GPRC:$in, (PPChi tconstpool:$g, 0)), (ADDIS GPRC:$in, tconstpool:$g)>; def : Pat<(add GPRC:$in, (PPChi tjumptable:$g, 0)), (ADDIS GPRC:$in, tjumptable:$g)>; +def : Pat<(add GPRC:$in, (PPChi tblockaddress:$g, 0)), + (ADDIS GPRC:$in, tblockaddress:$g)>; // Fused negative multiply subtract, alternate pattern def : Pat<(fsub F8RC:$B, (fmul F8RC:$A, F8RC:$C)), Added: llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll?rev=86050&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll Wed Nov 4 15:31:18 2009 @@ -0,0 +1,55 @@ +; RUN: llc < %s -relocation-model=pic -march=ppc32 | FileCheck %s -check-prefix=PIC +; RUN: llc < %s -relocation-model=static -march=ppc32 | FileCheck %s -check-prefix=STATIC + + at nextaddr = global i8* null ; [#uses=2] + at C.0.2070 = private constant [5 x i8*] [i8* blockaddress(@foo, %L1), i8* blockaddress(@foo, %L2), i8* blockaddress(@foo, %L3), i8* blockaddress(@foo, %L4), i8* blockaddress(@foo, %L5)] ; <[5 x i8*]*> [#uses=1] + +define internal i32 @foo(i32 %i) nounwind { +; PIC: foo: +; STATIC: foo: +entry: + %0 = load i8** @nextaddr, align 4 ; [#uses=2] + %1 = icmp eq i8* %0, null ; [#uses=1] + br i1 %1, label %bb3, label %bb2 + +bb2: ; preds = %entry, %bb3 + %gotovar.4.0 = phi i8* [ %gotovar.4.0.pre, %bb3 ], [ %0, %entry ] ; [#uses=1] +; PIC: mtctr +; PIC-NEXT: bctr +; STATIC: mtctr +; STATIC-NEXT: bctr + indirectbr i8* %gotovar.4.0, [label %L5, label %L4, label %L3, label %L2, label %L1] + +bb3: ; preds = %entry + %2 = getelementptr inbounds [5 x i8*]* @C.0.2070, i32 0, i32 %i ; [#uses=1] + %gotovar.4.0.pre = load i8** %2, align 4 ; [#uses=1] + br label %bb2 + +L5: ; preds = %bb2 + br label %L4 + +L4: ; preds = %L5, %bb2 + %res.0 = phi i32 [ 385, %L5 ], [ 35, %bb2 ] ; [#uses=1] + br label %L3 + +L3: ; preds = %L4, %bb2 + %res.1 = phi i32 [ %res.0, %L4 ], [ 5, %bb2 ] ; [#uses=1] + br label %L2 + +L2: ; preds = %L3, %bb2 + %res.2 = phi i32 [ %res.1, %L3 ], [ 1, %bb2 ] ; [#uses=1] + %phitmp = mul i32 %res.2, 6 ; [#uses=1] + br label %L1 + +L1: ; preds = %L2, %bb2 + %res.3 = phi i32 [ %phitmp, %L2 ], [ 2, %bb2 ] ; [#uses=1] +; PIC: addis r4, r2, ha16(L_foo_L5-"L1$pb") +; PIC: li r5, lo16(L_foo_L5-"L1$pb") +; PIC: add r4, r4, r5 +; PIC: stw r4 +; STATIC: li r2, lo16(L_foo_L5) +; STATIC: addis r2, r2, ha16(L_foo_L5) +; STATIC: stw r2 + store i8* blockaddress(@foo, %L5), i8** @nextaddr, align 4 + ret i32 %res.3 +} From dpatel at apple.com Wed Nov 4 16:06:12 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 04 Nov 2009 22:06:12 -0000 Subject: [llvm-commits] [llvm] r86054 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200911042206.nA4M6DMe002888@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 4 16:06:12 2009 New Revision: 86054 URL: http://llvm.org/viewvc/llvm-project?rev=86054&view=rev Log: Fix DW_AT_data_member_location for bit-fields. It points to the location of annonymous field that covers respective field. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86054&r1=86053&r2=86054&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Nov 4 16:06:12 2009 @@ -1137,6 +1137,9 @@ AddSourceLine(MemberDie, &DT); + DIEBlock *MemLocationDie = new DIEBlock(); + AddUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); + uint64_t Size = DT.getSizeInBits(); uint64_t FieldSize = Size; if (DT.getTypeDerivedFrom().getTag() != dwarf::DW_TAG_array_type) @@ -1157,12 +1160,16 @@ // Maybe we need to work from the other end. if (TD->isLittleEndian()) Offset = FieldSize - (Offset + Size); AddUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset); - } - DIEBlock *Block = new DIEBlock(); - AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); - AddUInt(Block, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3); - AddBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, Block); + // Here WD_AT_data_member_location points to the anonymous + // field that includes this bit field. + AddUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3); + + } else + // This is not a bitfield. + AddUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3); + + AddBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie); if (DT.isProtected()) AddUInt(MemberDie, dwarf::DW_AT_accessibility, 0, From grosbach at apple.com Wed Nov 4 16:41:00 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 04 Nov 2009 22:41:00 -0000 Subject: [llvm-commits] [llvm] r86056 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Message-ID: <200911042241.nA4Mf05G004255@zion.cs.uiuc.edu> Author: grosbach Date: Wed Nov 4 16:41:00 2009 New Revision: 86056 URL: http://llvm.org/viewvc/llvm-project?rev=86056&view=rev Log: dynamic stack realignment necessitates scanning the floating point callee- saved instructions even if no stack adjustment for those saves is needed. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=86056&r1=86055&r2=86056&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Wed Nov 4 16:41:00 2009 @@ -1339,10 +1339,10 @@ AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); + movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 0, 3, STI); NumBytes = DPRCSOffset; if (NumBytes) { - // Insert it after all the callee-save spills. - movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 0, 3, STI); + // Adjust SP after all the callee-save spills. emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes); } From grosbach at apple.com Wed Nov 4 16:41:52 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 04 Nov 2009 22:41:52 -0000 Subject: [llvm-commits] [llvm] r86057 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Message-ID: <200911042241.nA4Mfq40004297@zion.cs.uiuc.edu> Author: grosbach Date: Wed Nov 4 16:41:51 2009 New Revision: 86057 URL: http://llvm.org/viewvc/llvm-project?rev=86057&view=rev Log: If a function has no stack frame at all, dynamic realignment isn't necessary. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=86057&r1=86056&r2=86057&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Wed Nov 4 16:41:51 2009 @@ -514,6 +514,7 @@ unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); return (RealignStack && !AFI->isThumb1OnlyFunction() && + AFI->hasStackFrame() && (MFI->getMaxAlignment() > StackAlign) && !MFI->hasVarSizedObjects()); } From clattner at apple.com Wed Nov 4 16:44:49 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 4 Nov 2009 14:44:49 -0800 Subject: [llvm-commits] [llvm] r86049 - in /llvm/trunk: include/llvm/CodeGen/SlotIndexes.h lib/CodeGen/SlotIndexes.cpp In-Reply-To: <200911042124.nA4LOGUs001039@zion.cs.uiuc.edu> References: <200911042124.nA4LOGUs001039@zion.cs.uiuc.edu> Message-ID: <2FD10997-0651-440E-82AB-1DEA6ACB0C52@apple.com> On Nov 4, 2009, at 1:24 PM, Lang Hames wrote: > Author: lhames > Date: Wed Nov 4 15:24:15 2009 > New Revision: 86049 > > URL: http://llvm.org/viewvc/llvm-project?rev=86049&view=rev > Log: > Handle empty/tombstone keys for LiveIndex more cleanly. Check for > index sanity when constructing index list entries. Hi Lang, > +++ llvm/trunk/lib/CodeGen/SlotIndexes.cpp Wed Nov 4 15:24:15 2009 > @@ -16,8 +16,8 @@ > > using namespace llvm; > > -std::auto_ptr SlotIndex::emptyKeyPtr(0), > - SlotIndex::tombstoneKeyPtr(0); > +std::auto_ptr IndexListEntry::emptyKeyEntry, > + IndexListEntry::tombstoneKeyEntry; Why are you using global variables (with static ctors/dtors in particular) for this? This does not appear to be thread safe. Can these be made instance variables of the class? -Chris From espindola at google.com Wed Nov 4 16:45:37 2009 From: espindola at google.com (Rafael Espindola) Date: Wed, 4 Nov 2009 17:45:37 -0500 Subject: [llvm-commits] [patch] Make compiler-rt build on linux Message-ID: <38a0d8450911041445q25c909ctbb92caa9b3dc402f@mail.gmail.com> I tried to build compiler-rt with cmake and got lost. I must say I like make better :-) This patch adds support for Building shared libraries and changes some files so that it builds on linux. Tested with make TargetArch=i386 make TargetArch=x86_64 I skipped the fat binary bits, since they are OS X specific and it looks like OS X doesn't care about .so. Cheers, -- Rafael ?vila de Esp?ndola -------------- next part -------------- A non-text attachment was scrubbed... Name: shared.patch Type: text/x-diff Size: 5262 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091104/e77f36da/attachment.bin From grosbach at apple.com Wed Nov 4 17:11:07 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 04 Nov 2009 23:11:07 -0000 Subject: [llvm-commits] [llvm] r86064 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Message-ID: <200911042311.nA4NB777005594@zion.cs.uiuc.edu> Author: grosbach Date: Wed Nov 4 17:11:07 2009 New Revision: 86064 URL: http://llvm.org/viewvc/llvm-project?rev=86064&view=rev Log: Now that the memory leak from McCat/08-main has been fixed (86056), re-enable aggressive testing of dynamic stack alignment. Note that this is off by default, and enabled for LLCBETA nightly results. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=86064&r1=86063&r2=86064&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Wed Nov 4 17:11:07 2009 @@ -476,7 +476,11 @@ } static unsigned calculateMaxStackAlignment(const MachineFrameInfo *FFI) { - unsigned MaxAlign = 0; + // FIXME: For now, force at least 128-bit alignment. This will push the + // nightly tester harder for making sure things work correctly. When + // we're ready to enable this for real, this goes back to starting at zero. + unsigned MaxAlign = 16; +// unsigned MaxAlign = 0; for (int i = FFI->getObjectIndexBegin(), e = FFI->getObjectIndexEnd(); i != e; ++i) { @@ -509,13 +513,15 @@ if (!ARMDynamicStackAlign) return false; + // FIXME: To force more brutal testing, realign whether we need to or not. + // Change this to be more selective when we turn it on for real, of course. const MachineFrameInfo *MFI = MF.getFrameInfo(); const ARMFunctionInfo *AFI = MF.getInfo(); - unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); +// unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); return (RealignStack && !AFI->isThumb1OnlyFunction() && AFI->hasStackFrame() && - (MFI->getMaxAlignment() > StackAlign) && +// (MFI->getMaxAlignment() > StackAlign) && !MFI->hasVarSizedObjects()); } From sabre at nondot.org Wed Nov 4 17:20:12 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 04 Nov 2009 23:20:12 -0000 Subject: [llvm-commits] [llvm] r86067 - in /llvm/trunk: lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/DeadStoreElimination/no-targetdata.ll Message-ID: <200911042320.nA4NKCcG005965@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 4 17:20:12 2009 New Revision: 86067 URL: http://llvm.org/viewvc/llvm-project?rev=86067&view=rev Log: improve DSE when TargetData is not around, based on work by Hans Wennborg! Added: llvm/trunk/test/Transforms/DeadStoreElimination/no-targetdata.ll Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=86067&r1=86066&r2=86067&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Wed Nov 4 17:20:12 2009 @@ -78,6 +78,21 @@ FunctionPass *llvm::createDeadStoreEliminationPass() { return new DSE(); } +/// isValueAtLeastAsBigAs - Return true if V1 is greater than or equal to the +/// stored size of V2. This returns false if we don't know. +/// +static bool isValueAtLeastAsBigAs(Value *V1, Value *V2, const TargetData *TD) { + const Type *V1Ty = V1->getType(), *V2Ty = V2->getType(); + + // Exactly the same type, must have exactly the same size. + if (V1Ty == V2Ty) return true; + + // If we don't have target data, we don't know. + if (TD == 0) return false; + + return TD->getTypeStoreSize(V1Ty) >= TD->getTypeStoreSize(V2Ty); +} + bool DSE::runOnBasicBlock(BasicBlock &BB) { MemoryDependenceAnalysis& MD = getAnalysis(); TD = getAnalysisIfAvailable(); @@ -118,9 +133,7 @@ // If this is a store-store dependence, then the previous store is dead so // long as this store is at least as big as it. if (StoreInst *DepStore = dyn_cast(InstDep.getInst())) - if (TD && - TD->getTypeStoreSize(DepStore->getOperand(0)->getType()) <= - TD->getTypeStoreSize(SI->getOperand(0)->getType())) { + if (isValueAtLeastAsBigAs(SI->getOperand(0), DepStore->getOperand(0),TD)){ // Delete the store and now-dead instructions that feed it. DeleteDeadInstruction(DepStore); NumFastStores++; Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=86067&r1=86066&r2=86067&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Nov 4 17:20:12 2009 @@ -68,9 +68,6 @@ static char ID; // Pass identification JumpThreading() : FunctionPass(&ID) {} - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - } - bool runOnFunction(Function &F); void FindLoopHeaders(Function &F); Added: llvm/trunk/test/Transforms/DeadStoreElimination/no-targetdata.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/no-targetdata.ll?rev=86067&view=auto ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/no-targetdata.ll (added) +++ llvm/trunk/test/Transforms/DeadStoreElimination/no-targetdata.ll Wed Nov 4 17:20:12 2009 @@ -0,0 +1,15 @@ +; RUN: opt %s -dse -S | FileCheck %s + +declare void @test1f() + +define void @test1(i32* noalias %p) { + store i32 1, i32* %p; + call void @test1f() + store i32 2, i32 *%p + ret void +; CHECK: define void @test1 +; CHECK-NOT: store +; CHECK-NEXT: call void +; CHECK-NEXT: store i32 2 +; CHECK-NEXT: ret void +} \ No newline at end of file From grosbach at apple.com Wed Nov 4 17:20:42 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 04 Nov 2009 23:20:42 -0000 Subject: [llvm-commits] [llvm] r86068 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Message-ID: <200911042320.nA4NKgjg005995@zion.cs.uiuc.edu> Author: grosbach Date: Wed Nov 4 17:20:40 2009 New Revision: 86068 URL: http://llvm.org/viewvc/llvm-project?rev=86068&view=rev Log: Grammar. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=86068&r1=86067&r2=86068&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Wed Nov 4 17:20:40 2009 @@ -1212,7 +1212,7 @@ return ScratchReg; } -/// Move iterator pass the next bunch of callee save load / store ops for +/// Move iterator past the next bunch of callee save load / store ops for /// the particular spill area (1: integer area 1, 2: integer area 2, /// 3: fp area, 0: don't care). static void movePastCSLoadStoreOps(MachineBasicBlock &MBB, From espindola at google.com Wed Nov 4 17:34:59 2009 From: espindola at google.com (Rafael Espindola) Date: Wed, 4 Nov 2009 18:34:59 -0500 Subject: [llvm-commits] [patch] Make compiler-rt build on linux In-Reply-To: <38a0d8450911041445q25c909ctbb92caa9b3dc402f@mail.gmail.com> References: <38a0d8450911041445q25c909ctbb92caa9b3dc402f@mail.gmail.com> Message-ID: <38a0d8450911041534r75a6cbb5w2f82d3a83a4a7979@mail.gmail.com> > make TargetArch=i386 Which is incorrect since -m32 is missing. The attached patch makes it build in 32 bit too. Cheers, -- Rafael ?vila de Esp?ndola -------------- next part -------------- A non-text attachment was scrubbed... Name: shared.patch Type: text/x-diff Size: 6459 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091104/cfb8da49/attachment.bin From dpatel at apple.com Wed Nov 4 17:48:01 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 04 Nov 2009 23:48:01 -0000 Subject: [llvm-commits] [llvm] r86073 - in /llvm/trunk/lib: Analysis/DebugInfo.cpp CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200911042348.nA4Nm1cc007091@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 4 17:48:00 2009 New Revision: 86073 URL: http://llvm.org/viewvc/llvm-project?rev=86073&view=rev Log: While calculating original type size for a derived type, handle type variants encoded as DIDerivedType appropriately. This improves bitfield support. Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=86073&r1=86072&r2=86073&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Wed Nov 4 17:48:00 2009 @@ -401,12 +401,18 @@ /// getOriginalTypeSize - If this type is derived from a base type then /// return base type size. uint64_t DIDerivedType::getOriginalTypeSize() const { - DIType BT = getTypeDerivedFrom(); - if (!BT.isNull() && BT.isDerivedType()) - return DIDerivedType(BT.getNode()).getOriginalTypeSize(); - if (BT.isNull()) - return getSizeInBits(); - return BT.getSizeInBits(); + unsigned Tag = getTag(); + if (Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef || + Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type || + Tag == dwarf::DW_TAG_restrict_type) { + DIType BaseType = getTypeDerivedFrom(); + if (BaseType.isDerivedType()) + return DIDerivedType(BaseType.getNode()).getOriginalTypeSize(); + else + return BaseType.getSizeInBits(); + } + + return getSizeInBits(); } /// describes - Return true if this subprogram provides debugging Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=86073&r1=86072&r2=86073&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Nov 4 17:48:00 2009 @@ -1141,9 +1141,7 @@ AddUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); uint64_t Size = DT.getSizeInBits(); - uint64_t FieldSize = Size; - if (DT.getTypeDerivedFrom().getTag() != dwarf::DW_TAG_array_type) - FieldSize = DT.getOriginalTypeSize(); + uint64_t FieldSize = DT.getOriginalTypeSize(); if (Size != FieldSize) { // Handle bitfield. From eocallaghan at auroraux.org Wed Nov 4 17:52:52 2009 From: eocallaghan at auroraux.org (Edward O'Callaghan) Date: Wed, 04 Nov 2009 23:52:52 -0000 Subject: [llvm-commits] [compiler-rt] r86075 - in /compiler-rt/trunk/lib: i386/floatdidf.S i386/floatdixf.S i386/floatundidf.S i386/floatundisf.S i386/floatundixf.S x86_64/floatundidf.S x86_64/floatundisf.S x86_64/floatundixf.S Message-ID: <200911042352.nA4Nqqqe007264@zion.cs.uiuc.edu> Author: evocallaghan Date: Wed Nov 4 17:52:51 2009 New Revision: 86075 URL: http://llvm.org/viewvc/llvm-project?rev=86075&view=rev Log: Fix x86/x64 on Linux, Credit to Rafael Espindola. Modified: compiler-rt/trunk/lib/i386/floatdidf.S compiler-rt/trunk/lib/i386/floatdixf.S compiler-rt/trunk/lib/i386/floatundidf.S compiler-rt/trunk/lib/i386/floatundisf.S compiler-rt/trunk/lib/i386/floatundixf.S compiler-rt/trunk/lib/x86_64/floatundidf.S compiler-rt/trunk/lib/x86_64/floatundisf.S compiler-rt/trunk/lib/x86_64/floatundixf.S Modified: compiler-rt/trunk/lib/i386/floatdidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdidf.S?rev=86075&r1=86074&r2=86075&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatdidf.S (original) +++ compiler-rt/trunk/lib/i386/floatdidf.S Wed Nov 4 17:52:51 2009 @@ -7,7 +7,9 @@ #ifdef __i386__ +#ifndef __ELF__ .const +#endif .align 4 twop52: .quad 0x4330000000000000 twop32: .quad 0x41f0000000000000 Modified: compiler-rt/trunk/lib/i386/floatdixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdixf.S?rev=86075&r1=86074&r2=86075&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatdixf.S (original) +++ compiler-rt/trunk/lib/i386/floatdixf.S Wed Nov 4 17:52:51 2009 @@ -26,4 +26,4 @@ fildll 4(%esp) ret -#endif // __i386__ \ No newline at end of file +#endif // __i386__ Modified: compiler-rt/trunk/lib/i386/floatundidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundidf.S?rev=86075&r1=86074&r2=86075&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundidf.S (original) +++ compiler-rt/trunk/lib/i386/floatundidf.S Wed Nov 4 17:52:51 2009 @@ -17,7 +17,9 @@ #ifdef __i386__ +#ifndef __ELF__ .const +#endif .align 4 twop52: .quad 0x4330000000000000 twop84_plus_twop52: Modified: compiler-rt/trunk/lib/i386/floatundisf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundisf.S?rev=86075&r1=86074&r2=86075&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundisf.S (original) +++ compiler-rt/trunk/lib/i386/floatundisf.S Wed Nov 4 17:52:51 2009 @@ -51,8 +51,12 @@ #ifdef __i386__ +#ifndef __ELF__ .const .align 3 +#else +.align 8 +#endif twop52: .quad 0x4330000000000000 .quad 0x0000000000000fff sticky: .quad 0x0000000000000000 Modified: compiler-rt/trunk/lib/i386/floatundixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundixf.S?rev=86075&r1=86074&r2=86075&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundixf.S (original) +++ compiler-rt/trunk/lib/i386/floatundixf.S Wed Nov 4 17:52:51 2009 @@ -7,7 +7,9 @@ #ifdef __i386__ +#ifndef __ELF__ .const +#endif .align 4 twop52: .quad 0x4330000000000000 twop84_plus_twop52_neg: @@ -32,4 +34,4 @@ faddl 4(%esp) ret -#endif // __i386__ \ No newline at end of file +#endif // __i386__ Modified: compiler-rt/trunk/lib/x86_64/floatundidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundidf.S?rev=86075&r1=86074&r2=86075&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundidf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundidf.S Wed Nov 4 17:52:51 2009 @@ -17,7 +17,9 @@ #ifdef __x86_64__ +#ifndef __ELF__ .const +#endif .align 4 twop52: .quad 0x4330000000000000 twop84_plus_twop52: @@ -38,4 +40,4 @@ addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here) ret -#endif // __x86_64__ \ No newline at end of file +#endif // __x86_64__ Modified: compiler-rt/trunk/lib/x86_64/floatundisf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundisf.S?rev=86075&r1=86074&r2=86075&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundisf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundisf.S Wed Nov 4 17:52:51 2009 @@ -7,7 +7,9 @@ #ifdef __x86_64__ +#ifndef __ELF__ .literal4 +#endif two: .single 2.0 #define REL_ADDR(_a) (_a)(%rip) @@ -28,4 +30,4 @@ mulss REL_ADDR(two), %xmm0 ret -#endif // __x86_64__ \ No newline at end of file +#endif // __x86_64__ Modified: compiler-rt/trunk/lib/x86_64/floatundixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundixf.S?rev=86075&r1=86074&r2=86075&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundixf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundixf.S Wed Nov 4 17:52:51 2009 @@ -7,7 +7,9 @@ #ifdef __x86_64__ +#ifndef __ELF__ .const +#endif .align 4 twop64: .quad 0x43f0000000000000 @@ -57,4 +59,4 @@ #endif // __x86_64__ -*/ \ No newline at end of file +*/ From ssen at apple.com Wed Nov 4 17:57:44 2009 From: ssen at apple.com (Shantonu Sen) Date: Wed, 4 Nov 2009 15:57:44 -0800 Subject: [llvm-commits] [compiler-rt] r86075 - in /compiler-rt/trunk/lib: i386/floatdidf.S i386/floatdixf.S i386/floatundidf.S i386/floatundisf.S i386/floatundixf.S x86_64/floatundidf.S x86_64/floatundisf.S x86_64/floatundixf.S In-Reply-To: <200911042352.nA4Nqqqe007264@zion.cs.uiuc.edu> References: <200911042352.nA4Nqqqe007264@zion.cs.uiuc.edu> Message-ID: If newer binutils supports ".p2align 3", you can use that too. That should work on Darwin as well without requiring a conditional. Shantonu Sen ssen at apple.com Sent from my Mac Pro On Nov 4, 2009, at 3:52 PM, Edward O'Callaghan wrote: > Author: evocallaghan > Date: Wed Nov 4 17:52:51 2009 > New Revision: 86075 > > URL: http://llvm.org/viewvc/llvm-project?rev=86075&view=rev > Log: > Fix x86/x64 on Linux, Credit to Rafael Espindola. > > Modified: > compiler-rt/trunk/lib/i386/floatdidf.S > compiler-rt/trunk/lib/i386/floatdixf.S > compiler-rt/trunk/lib/i386/floatundidf.S > compiler-rt/trunk/lib/i386/floatundisf.S > compiler-rt/trunk/lib/i386/floatundixf.S > compiler-rt/trunk/lib/x86_64/floatundidf.S > compiler-rt/trunk/lib/x86_64/floatundisf.S > compiler-rt/trunk/lib/x86_64/floatundixf.S > > Modified: compiler-rt/trunk/lib/i386/floatdidf.S > URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdidf.S?rev=86075&r1=86074&r2=86075&view=diff > > ============================================================================== > --- compiler-rt/trunk/lib/i386/floatdidf.S (original) > +++ compiler-rt/trunk/lib/i386/floatdidf.S Wed Nov 4 17:52:51 2009 > @@ -7,7 +7,9 @@ > > #ifdef __i386__ > > +#ifndef __ELF__ > .const > +#endif > .align 4 > twop52: .quad 0x4330000000000000 > twop32: .quad 0x41f0000000000000 > > Modified: compiler-rt/trunk/lib/i386/floatdixf.S > URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdixf.S?rev=86075&r1=86074&r2=86075&view=diff > > ============================================================================== > --- compiler-rt/trunk/lib/i386/floatdixf.S (original) > +++ compiler-rt/trunk/lib/i386/floatdixf.S Wed Nov 4 17:52:51 2009 > @@ -26,4 +26,4 @@ > fildll 4(%esp) > ret > > -#endif // __i386__ > \ No newline at end of file > +#endif // __i386__ > > Modified: compiler-rt/trunk/lib/i386/floatundidf.S > URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundidf.S?rev=86075&r1=86074&r2=86075&view=diff > > ============================================================================== > --- compiler-rt/trunk/lib/i386/floatundidf.S (original) > +++ compiler-rt/trunk/lib/i386/floatundidf.S Wed Nov 4 17:52:51 2009 > @@ -17,7 +17,9 @@ > > #ifdef __i386__ > > +#ifndef __ELF__ > .const > +#endif > .align 4 > twop52: .quad 0x4330000000000000 > twop84_plus_twop52: > > Modified: compiler-rt/trunk/lib/i386/floatundisf.S > URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundisf.S?rev=86075&r1=86074&r2=86075&view=diff > > ============================================================================== > --- compiler-rt/trunk/lib/i386/floatundisf.S (original) > +++ compiler-rt/trunk/lib/i386/floatundisf.S Wed Nov 4 17:52:51 2009 > @@ -51,8 +51,12 @@ > > #ifdef __i386__ > > +#ifndef __ELF__ > .const > .align 3 > +#else > +.align 8 > +#endif > twop52: .quad 0x4330000000000000 > .quad 0x0000000000000fff > sticky: .quad 0x0000000000000000 > > Modified: compiler-rt/trunk/lib/i386/floatundixf.S > URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundixf.S?rev=86075&r1=86074&r2=86075&view=diff > > ============================================================================== > --- compiler-rt/trunk/lib/i386/floatundixf.S (original) > +++ compiler-rt/trunk/lib/i386/floatundixf.S Wed Nov 4 17:52:51 2009 > @@ -7,7 +7,9 @@ > > #ifdef __i386__ > > +#ifndef __ELF__ > .const > +#endif > .align 4 > twop52: .quad 0x4330000000000000 > twop84_plus_twop52_neg: > @@ -32,4 +34,4 @@ > faddl 4(%esp) > ret > > -#endif // __i386__ > \ No newline at end of file > +#endif // __i386__ > > Modified: compiler-rt/trunk/lib/x86_64/floatundidf.S > URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundidf.S?rev=86075&r1=86074&r2=86075&view=diff > > ============================================================================== > --- compiler-rt/trunk/lib/x86_64/floatundidf.S (original) > +++ compiler-rt/trunk/lib/x86_64/floatundidf.S Wed Nov 4 17:52:51 2009 > @@ -17,7 +17,9 @@ > > #ifdef __x86_64__ > > +#ifndef __ELF__ > .const > +#endif > .align 4 > twop52: .quad 0x4330000000000000 > twop84_plus_twop52: > @@ -38,4 +40,4 @@ > addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here) > ret > > -#endif // __x86_64__ > \ No newline at end of file > +#endif // __x86_64__ > > Modified: compiler-rt/trunk/lib/x86_64/floatundisf.S > URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundisf.S?rev=86075&r1=86074&r2=86075&view=diff > > ============================================================================== > --- compiler-rt/trunk/lib/x86_64/floatundisf.S (original) > +++ compiler-rt/trunk/lib/x86_64/floatundisf.S Wed Nov 4 17:52:51 2009 > @@ -7,7 +7,9 @@ > > #ifdef __x86_64__ > > +#ifndef __ELF__ > .literal4 > +#endif > two: .single 2.0 > > #define REL_ADDR(_a) (_a)(%rip) > @@ -28,4 +30,4 @@ > mulss REL_ADDR(two), %xmm0 > ret > > -#endif // __x86_64__ > \ No newline at end of file > +#endif // __x86_64__ > > Modified: compiler-rt/trunk/lib/x86_64/floatundixf.S > URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundixf.S?rev=86075&r1=86074&r2=86075&view=diff > > ============================================================================== > --- compiler-rt/trunk/lib/x86_64/floatundixf.S (original) > +++ compiler-rt/trunk/lib/x86_64/floatundixf.S Wed Nov 4 17:52:51 2009 > @@ -7,7 +7,9 @@ > > #ifdef __x86_64__ > > +#ifndef __ELF__ > .const > +#endif > .align 4 > twop64: .quad 0x43f0000000000000 > > @@ -57,4 +59,4 @@ > > #endif // __x86_64__ > > -*/ > \ No newline at end of file > +*/ > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From eocallaghan at auroraux.org Wed Nov 4 17:58:33 2009 From: eocallaghan at auroraux.org (Edward O'Callaghan) Date: Wed, 4 Nov 2009 23:58:33 +0000 Subject: [llvm-commits] [patch] Make compiler-rt build on linux In-Reply-To: <38a0d8450911041534r75a6cbb5w2f82d3a83a4a7979@mail.gmail.com> References: <38a0d8450911041445q25c909ctbb92caa9b3dc402f@mail.gmail.com> <38a0d8450911041534r75a6cbb5w2f82d3a83a4a7979@mail.gmail.com> Message-ID: <521640720911041558m5d890cc5y22d050267966599e@mail.gmail.com> Second patch was committed in revision 86075. However the patching to: * 'make/config.mk' * 'Makefile' was left out, as we take patches for the new *portable* cmake build system and I am not reasonable nor do I have a way to test patches to the old apple makefiles as they don't work on all hosts. In future, please make patches to the cmake system, Many thanks, Edward. 2009/11/4 Rafael Espindola : >> make TargetArch=i386 > > Which is incorrect since -m32 is missing. The attached patch makes it > build in 32 bit too. > > Cheers, > -- > Rafael ?vila de Esp?ndola > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -- -- Edward O'Callaghan http://www.auroraux.org/ eocallaghan at auroraux dot org From vhernandez at apple.com Wed Nov 4 18:03:03 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Thu, 05 Nov 2009 00:03:03 -0000 Subject: [llvm-commits] [llvm] r86077 - in /llvm/trunk: examples/BrainF/ include/llvm/ include/llvm/Analysis/ lib/Analysis/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Transforms/IPO/ lib/VMCore/ test/Analysis/PointerTracking/ test/Transforms/GlobalOpt/ Message-ID: <200911050003.nA5034uP007663@zion.cs.uiuc.edu> Author: hernande Date: Wed Nov 4 18:03:03 2009 New Revision: 86077 URL: http://llvm.org/viewvc/llvm-project?rev=86077&view=rev Log: Update CreateMalloc so that its callers specify the size to allocate: MallocInst-autoupgrade users use non-TargetData-computed allocation sizes. Optimization uses use TargetData to compute the allocation size. Now that malloc calls can have constant sizes, update isArrayMallocHelper() to use TargetData to determine the size of the malloced type and the size of malloced arrays. Extend getMallocType() to support malloc calls that have non-bitcast uses. Update OptimizeGlobalAddressOfMalloc() to optimize malloc calls that have non-bitcast uses. The bitcast use of a malloc call has to be treated specially here because the uses of the bitcast need to be replaced and the bitcast needs to be erased (just like the malloc call) for OptimizeGlobalAddressOfMalloc() to work correctly. Update PerformHeapAllocSRoA() to optimize malloc calls that have non-bitcast uses. The bitcast use of the malloc is not handled specially here because ReplaceUsesOfMallocWithGlobal replaces through the bitcast use. Update OptimizeOnceStoredGlobal() to not care about the malloc calls' bitcast use. Update all globalopt malloc tests to not rely on autoupgraded-MallocInsts, but instead use explicit malloc calls with correct allocation sizes. Modified: llvm/trunk/examples/BrainF/BrainF.cpp llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/lib/Analysis/MemoryBuiltins.cpp llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/lib/VMCore/Core.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/test/Analysis/PointerTracking/sizes.ll llvm/trunk/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll llvm/trunk/test/Transforms/GlobalOpt/heap-sra-1.ll llvm/trunk/test/Transforms/GlobalOpt/heap-sra-2.ll llvm/trunk/test/Transforms/GlobalOpt/heap-sra-3.ll llvm/trunk/test/Transforms/GlobalOpt/heap-sra-4.ll llvm/trunk/test/Transforms/GlobalOpt/heap-sra-phi.ll llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-2.ll llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-3.ll Modified: llvm/trunk/examples/BrainF/BrainF.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/BrainF/BrainF.cpp?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/examples/BrainF/BrainF.cpp (original) +++ llvm/trunk/examples/BrainF/BrainF.cpp Wed Nov 4 18:03:03 2009 @@ -81,8 +81,11 @@ ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal)); BasicBlock* BB = builder->GetInsertBlock(); const Type* IntPtrTy = IntegerType::getInt32Ty(C); - ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, IntegerType::getInt8Ty(C), - val_mem, NULL, "arr"); + const Type* Int8Ty = IntegerType::getInt8Ty(C); + Constant* allocsize = ConstantExpr::getSizeOf(Int8Ty); + allocsize = ConstantExpr::getTruncOrBitCast(allocsize, IntPtrTy); + ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, Int8Ty, allocsize, val_mem, + NULL, "arr"); BB->getInstList().push_back(cast(ptr_arr)); //call void @llvm.memset.i32(i8 *%arr, i8 0, i32 %d, i32 1) Modified: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h Wed Nov 4 18:03:03 2009 @@ -50,13 +50,17 @@ const TargetData* TD); /// getMallocType - Returns the PointerType resulting from the malloc call. -/// This PointerType is the result type of the call's only bitcast use. -/// If there is no unique bitcast use, then return NULL. +/// The PointerType depends on the number of bitcast uses of the malloc call: +/// 0: PointerType is the malloc calls' return type. +/// 1: PointerType is the bitcast's result type. +/// >1: Unique PointerType cannot be determined, return NULL. const PointerType* getMallocType(const CallInst* CI); -/// getMallocAllocatedType - Returns the Type allocated by malloc call. This -/// Type is the result type of the call's only bitcast use. If there is no -/// unique bitcast use, then return NULL. +/// getMallocAllocatedType - Returns the Type allocated by malloc call. +/// The Type depends on the number of bitcast uses of the malloc call: +/// 0: PointerType is the malloc calls' return type. +/// 1: PointerType is the bitcast's result type. +/// >1: Unique PointerType cannot be determined, return NULL. const Type* getMallocAllocatedType(const CallInst* CI); /// getMallocArraySize - Returns the array size of a malloc call. If the Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Wed Nov 4 18:03:03 2009 @@ -899,11 +899,12 @@ /// 3. Bitcast the result of the malloc call to the specified type. static Instruction *CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy, const Type *AllocTy, - Value *ArraySize = 0, + Value *AllocSize, Value *ArraySize = 0, const Twine &Name = ""); static Instruction *CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy, const Type *AllocTy, - Value *ArraySize = 0, Function* MallocF = 0, + Value *AllocSize, Value *ArraySize = 0, + Function* MallocF = 0, const Twine &Name = ""); /// CreateFree - Generate the IR for a call to the builtin free function. static void CreateFree(Value* Source, Instruction *InsertBefore); Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Wed Nov 4 18:03:03 2009 @@ -17,6 +17,7 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Target/TargetData.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -96,45 +97,47 @@ if (!CI) return NULL; - // Type must be known to determine array size. + // The size of the malloc's result type must be known to determine array size. const Type *T = getMallocAllocatedType(CI); - if (!T) + if (!T || !T->isSized() || !TD) return NULL; Value *MallocArg = CI->getOperand(1); + const Type *ArgType = MallocArg->getType(); ConstantExpr *CO = dyn_cast(MallocArg); BinaryOperator *BO = dyn_cast(MallocArg); - Constant *ElementSize = ConstantExpr::getSizeOf(T); - ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, - MallocArg->getType()); - Constant *FoldedElementSize = - ConstantFoldConstantExpression(cast(ElementSize), Context, TD); + unsigned ElementSizeInt = TD->getTypeAllocSize(T); + if (const StructType *ST = dyn_cast(T)) + ElementSizeInt = TD->getStructLayout(ST)->getSizeInBytes(); + Constant *ElementSize = ConstantInt::get(ArgType, ElementSizeInt); // First, check if CI is a non-array malloc. - if (CO && ((CO == ElementSize) || - (FoldedElementSize && (CO == FoldedElementSize)))) + if (CO && CO == ElementSize) // Match CreateMalloc's use of constant 1 array-size for non-array mallocs. - return ConstantInt::get(MallocArg->getType(), 1); + return ConstantInt::get(ArgType, 1); // Second, check if CI is an array malloc whose array size can be determined. - if (isConstantOne(ElementSize) || - (FoldedElementSize && isConstantOne(FoldedElementSize))) + if (isConstantOne(ElementSize)) return MallocArg; + if (ConstantInt *CInt = dyn_cast(MallocArg)) + if (CInt->getZExtValue() % ElementSizeInt == 0) + return ConstantInt::get(ArgType, CInt->getZExtValue() / ElementSizeInt); + if (!CO && !BO) return NULL; Value *Op0 = NULL; Value *Op1 = NULL; unsigned Opcode = 0; - if (CO && ((CO->getOpcode() == Instruction::Mul) || + if (CO && ((CO->getOpcode() == Instruction::Mul) || (CO->getOpcode() == Instruction::Shl))) { Op0 = CO->getOperand(0); Op1 = CO->getOperand(1); Opcode = CO->getOpcode(); } - if (BO && ((BO->getOpcode() == Instruction::Mul) || + if (BO && ((BO->getOpcode() == Instruction::Mul) || (BO->getOpcode() == Instruction::Shl))) { Op0 = BO->getOperand(0); Op1 = BO->getOperand(1); @@ -144,12 +147,10 @@ // Determine array size if malloc's argument is the product of a mul or shl. if (Op0) { if (Opcode == Instruction::Mul) { - if ((Op1 == ElementSize) || - (FoldedElementSize && (Op1 == FoldedElementSize))) + if (Op1 == ElementSize) // ArraySize * ElementSize return Op0; - if ((Op0 == ElementSize) || - (FoldedElementSize && (Op0 == FoldedElementSize))) + if (Op0 == ElementSize) // ElementSize * ArraySize return Op1; } @@ -161,11 +162,10 @@ uint64_t BitToSet = Op1Int.getLimitedValue(Op1Int.getBitWidth() - 1); Value *Op1Pow = ConstantInt::get(Context, APInt(Op1Int.getBitWidth(), 0).set(BitToSet)); - if (Op0 == ElementSize || (FoldedElementSize && Op0 == FoldedElementSize)) + if (Op0 == ElementSize) // ArraySize << log2(ElementSize) return Op1Pow; - if (Op1Pow == ElementSize || - (FoldedElementSize && Op1Pow == FoldedElementSize)) + if (Op1Pow == ElementSize) // ElementSize << log2(ArraySize) return Op0; } @@ -205,35 +205,41 @@ } /// getMallocType - Returns the PointerType resulting from the malloc call. -/// This PointerType is the result type of the call's only bitcast use. -/// If there is no unique bitcast use, then return NULL. +/// The PointerType depends on the number of bitcast uses of the malloc call: +/// 0: PointerType is the calls' return type. +/// 1: PointerType is the bitcast's result type. +/// >1: Unique PointerType cannot be determined, return NULL. const PointerType *llvm::getMallocType(const CallInst *CI) { assert(isMalloc(CI) && "GetMallocType and not malloc call"); - const BitCastInst *BCI = NULL; - + const PointerType *MallocType = NULL; + unsigned NumOfBitCastUses = 0; + // Determine if CallInst has a bitcast use. for (Value::use_const_iterator UI = CI->use_begin(), E = CI->use_end(); UI != E; ) - if ((BCI = dyn_cast(cast(*UI++)))) - break; + if (const BitCastInst *BCI = dyn_cast(*UI++)) { + MallocType = cast(BCI->getDestTy()); + NumOfBitCastUses++; + } - // Malloc call has 1 bitcast use and no other uses, so type is the bitcast's - // destination type. - if (BCI && CI->hasOneUse()) - return cast(BCI->getDestTy()); + // Malloc call has 1 bitcast use, so type is the bitcast's destination type. + if (NumOfBitCastUses == 1) + return MallocType; // Malloc call was not bitcast, so type is the malloc function's return type. - if (!BCI) + if (NumOfBitCastUses == 0) return cast(CI->getType()); // Type could not be determined. return NULL; } -/// getMallocAllocatedType - Returns the Type allocated by malloc call. This -/// Type is the result type of the call's only bitcast use. If there is no -/// unique bitcast use, then return NULL. +/// getMallocAllocatedType - Returns the Type allocated by malloc call. +/// The Type depends on the number of bitcast uses of the malloc call: +/// 0: PointerType is the malloc calls' return type. +/// 1: PointerType is the bitcast's result type. +/// >1: Unique PointerType cannot be determined, return NULL. const Type *llvm::getMallocAllocatedType(const CallInst *CI) { const PointerType *PT = getMallocType(CI); return PT ? PT->getElementType() : NULL; Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Nov 4 18:03:03 2009 @@ -3619,12 +3619,14 @@ // Autoupgrade old malloc instruction to malloc call. // FIXME: Remove in LLVM 3.0. const Type *IntPtrTy = Type::getInt32Ty(Context); + Constant *AllocSize = ConstantExpr::getSizeOf(Ty); + AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, IntPtrTy); if (!MallocF) // Prototype malloc as "void *(int32)". // This function is renamed as "malloc" in ValidateEndOfModule(). MallocF = cast( M->getOrInsertFunction("", Type::getInt8PtrTy(Context), IntPtrTy, NULL)); - Inst = CallInst::CreateMalloc(BB, IntPtrTy, Ty, Size, MallocF); + Inst = CallInst::CreateMalloc(BB, IntPtrTy, Ty, AllocSize, Size, MallocF); return false; } Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Wed Nov 4 18:03:03 2009 @@ -2101,8 +2101,10 @@ if (!Ty || !Size) return Error("Invalid MALLOC record"); if (!CurBB) return Error("Invalid malloc instruction with no BB"); const Type *Int32Ty = IntegerType::getInt32Ty(CurBB->getContext()); + Constant *AllocSize = ConstantExpr::getSizeOf(Ty->getElementType()); + AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, Int32Ty); I = CallInst::CreateMalloc(CurBB, Int32Ty, Ty->getElementType(), - Size, NULL); + AllocSize, Size, NULL); InstructionList.push_back(I); break; } Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Wed Nov 4 18:03:03 2009 @@ -822,32 +822,42 @@ /// malloc into a global, and any loads of GV as uses of the new global. static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, - BitCastInst *BCI, + const Type *AllocTy, Value* NElems, LLVMContext &Context, TargetData* TD) { - DEBUG(errs() << "PROMOTING MALLOC GLOBAL: " << *GV - << " CALL = " << *CI << " BCI = " << *BCI << '\n'); + DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n'); const Type *IntPtrTy = TD->getIntPtrType(Context); + // CI has either 0 or 1 bitcast uses (getMallocType() would otherwise have + // returned NULL and we would not be here). + BitCastInst *BCI = NULL; + for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); UI != E; ) + if ((BCI = dyn_cast(cast(*UI++)))) + break; + ConstantInt *NElements = cast(NElems); if (NElements->getZExtValue() != 1) { // If we have an array allocation, transform it to a single element // allocation to make the code below simpler. - Type *NewTy = ArrayType::get(getMallocAllocatedType(CI), - NElements->getZExtValue()); - Value* NewM = CallInst::CreateMalloc(CI, IntPtrTy, NewTy); - Instruction* NewMI = cast(NewM); + Type *NewTy = ArrayType::get(AllocTy, NElements->getZExtValue()); + unsigned TypeSize = TD->getTypeAllocSize(NewTy); + if (const StructType *ST = dyn_cast(NewTy)) + TypeSize = TD->getStructLayout(ST)->getSizeInBytes(); + Instruction *NewCI = CallInst::CreateMalloc(CI, IntPtrTy, NewTy, + ConstantInt::get(IntPtrTy, TypeSize)); Value* Indices[2]; Indices[0] = Indices[1] = Constant::getNullValue(IntPtrTy); - Value *NewGEP = GetElementPtrInst::Create(NewMI, Indices, Indices + 2, - NewMI->getName()+".el0", CI); - BCI->replaceAllUsesWith(NewGEP); - BCI->eraseFromParent(); + Value *NewGEP = GetElementPtrInst::Create(NewCI, Indices, Indices + 2, + NewCI->getName()+".el0", CI); + Value *Cast = new BitCastInst(NewGEP, CI->getType(), "el0", CI); + if (BCI) BCI->replaceAllUsesWith(NewGEP); + CI->replaceAllUsesWith(Cast); + if (BCI) BCI->eraseFromParent(); CI->eraseFromParent(); - BCI = cast(NewMI); - CI = extractMallocCallFromBitCast(NewMI); + BCI = dyn_cast(NewCI); + CI = BCI ? extractMallocCallFromBitCast(BCI) : cast(NewCI); } // Create the new global variable. The contents of the malloc'd memory is @@ -861,8 +871,9 @@ GV, GV->isThreadLocal()); - // Anything that used the malloc now uses the global directly. - BCI->replaceAllUsesWith(NewGV); + // Anything that used the malloc or its bitcast now uses the global directly. + if (BCI) BCI->replaceAllUsesWith(NewGV); + CI->replaceAllUsesWith(new BitCastInst(NewGV, CI->getType(), "newgv", CI)); Constant *RepValue = NewGV; if (NewGV->getType() != GV->getType()->getElementType()) @@ -930,9 +941,9 @@ GV->getParent()->getGlobalList().insert(GV, InitBool); - // Now the GV is dead, nuke it and the malloc. + // Now the GV is dead, nuke it and the malloc (both CI and BCI). GV->eraseFromParent(); - BCI->eraseFromParent(); + if (BCI) BCI->eraseFromParent(); CI->eraseFromParent(); // To further other optimizations, loop over all users of NewGV and try to @@ -1273,13 +1284,10 @@ /// PerformHeapAllocSRoA - CI is an allocation of an array of structures. Break /// it up into multiple allocations of arrays of the fields. -static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, - CallInst *CI, BitCastInst* BCI, - Value* NElems, - LLVMContext &Context, +static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI, + Value* NElems, LLVMContext &Context, TargetData *TD) { - DEBUG(errs() << "SROA HEAP ALLOC: " << *GV << " MALLOC CALL = " << *CI - << " BITCAST = " << *BCI << '\n'); + DEBUG(errs() << "SROA HEAP ALLOC: " << *GV << " MALLOC = " << *CI << '\n'); const Type* MAT = getMallocAllocatedType(CI); const StructType *STy = cast(MAT); @@ -1287,8 +1295,8 @@ // it into GV). If there are other uses, change them to be uses of // the global to simplify later code. This also deletes the store // into GV. - ReplaceUsesOfMallocWithGlobal(BCI, GV); - + ReplaceUsesOfMallocWithGlobal(CI, GV); + // Okay, at this point, there are no users of the malloc. Insert N // new mallocs at the same place as CI, and N globals. std::vector FieldGlobals; @@ -1306,11 +1314,16 @@ GV->isThreadLocal()); FieldGlobals.push_back(NGV); - Value *NMI = CallInst::CreateMalloc(CI, TD->getIntPtrType(Context), - FieldTy, NElems, - BCI->getName() + ".f" + Twine(FieldNo)); + unsigned TypeSize = TD->getTypeAllocSize(FieldTy); + if (const StructType* ST = dyn_cast(FieldTy)) + TypeSize = TD->getStructLayout(ST)->getSizeInBytes(); + const Type* IntPtrTy = TD->getIntPtrType(Context); + Value *NMI = CallInst::CreateMalloc(CI, IntPtrTy, FieldTy, + ConstantInt::get(IntPtrTy, TypeSize), + NElems, + CI->getName() + ".f" + Twine(FieldNo)); FieldMallocs.push_back(NMI); - new StoreInst(NMI, NGV, BCI); + new StoreInst(NMI, NGV, CI); } // The tricky aspect of this transformation is handling the case when malloc @@ -1327,18 +1340,18 @@ // } Value *RunningOr = 0; for (unsigned i = 0, e = FieldMallocs.size(); i != e; ++i) { - Value *Cond = new ICmpInst(BCI, ICmpInst::ICMP_EQ, FieldMallocs[i], - Constant::getNullValue(FieldMallocs[i]->getType()), - "isnull"); + Value *Cond = new ICmpInst(CI, ICmpInst::ICMP_EQ, FieldMallocs[i], + Constant::getNullValue(FieldMallocs[i]->getType()), + "isnull"); if (!RunningOr) RunningOr = Cond; // First seteq else - RunningOr = BinaryOperator::CreateOr(RunningOr, Cond, "tmp", BCI); + RunningOr = BinaryOperator::CreateOr(RunningOr, Cond, "tmp", CI); } // Split the basic block at the old malloc. - BasicBlock *OrigBB = BCI->getParent(); - BasicBlock *ContBB = OrigBB->splitBasicBlock(BCI, "malloc_cont"); + BasicBlock *OrigBB = CI->getParent(); + BasicBlock *ContBB = OrigBB->splitBasicBlock(CI, "malloc_cont"); // Create the block to check the first condition. Put all these blocks at the // end of the function as they are unlikely to be executed. @@ -1374,9 +1387,8 @@ } BranchInst::Create(ContBB, NullPtrBlock); - - // CI and BCI are no longer needed, remove them. - BCI->eraseFromParent(); + + // CI is no longer needed, remove it. CI->eraseFromParent(); /// InsertedScalarizedLoads - As we process loads, if we can't immediately @@ -1463,14 +1475,10 @@ /// cast of malloc. static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, CallInst *CI, - BitCastInst *BCI, + const Type *AllocTy, Module::global_iterator &GVI, TargetData *TD, LLVMContext &Context) { - // If we can't figure out the type being malloced, then we can't optimize. - const Type *AllocTy = getMallocAllocatedType(CI); - assert(AllocTy); - // If this is a malloc of an abstract type, don't touch it. if (!AllocTy->isSized()) return false; @@ -1491,7 +1499,7 @@ // for. { SmallPtrSet PHIs; - if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(BCI, GV, PHIs)) + if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(CI, GV, PHIs)) return false; } @@ -1499,16 +1507,16 @@ // transform the program to use global memory instead of malloc'd memory. // This eliminates dynamic allocation, avoids an indirection accessing the // data, and exposes the resultant global to further GlobalOpt. - Value *NElems = getMallocArraySize(CI, Context, TD); // We cannot optimize the malloc if we cannot determine malloc array size. - if (NElems) { + if (Value *NElems = getMallocArraySize(CI, Context, TD)) { if (ConstantInt *NElements = dyn_cast(NElems)) // Restrict this transformation to only working on small allocations // (2048 bytes currently), as we don't want to introduce a 16M global or // something. if (TD && NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) { - GVI = OptimizeGlobalAddressOfMalloc(GV, CI, BCI, NElems, Context, TD); + GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElems, + Context, TD); return true; } @@ -1526,26 +1534,29 @@ // This the structure has an unreasonable number of fields, leave it // alone. if (AllocSTy->getNumElements() <= 16 && AllocSTy->getNumElements() != 0 && - AllGlobalLoadUsesSimpleEnoughForHeapSRA(GV, BCI)) { + AllGlobalLoadUsesSimpleEnoughForHeapSRA(GV, CI)) { // If this is a fixed size array, transform the Malloc to be an alloc of // structs. malloc [100 x struct],1 -> malloc struct, 100 if (const ArrayType *AT = dyn_cast(getMallocAllocatedType(CI))) { - Value* NumElements = ConstantInt::get(Type::getInt32Ty(Context), - AT->getNumElements()); - Value* NewMI = CallInst::CreateMalloc(CI, TD->getIntPtrType(Context), - AllocSTy, NumElements, - BCI->getName()); - Value *Cast = new BitCastInst(NewMI, getMallocType(CI), "tmp", CI); - BCI->replaceAllUsesWith(Cast); - BCI->eraseFromParent(); + const Type *IntPtrTy = TD->getIntPtrType(Context); + unsigned TypeSize = TD->getStructLayout(AllocSTy)->getSizeInBytes(); + Value *AllocSize = ConstantInt::get(IntPtrTy, TypeSize); + Value *NumElements = ConstantInt::get(IntPtrTy, AT->getNumElements()); + Instruction *Malloc = CallInst::CreateMalloc(CI, IntPtrTy, AllocSTy, + AllocSize, NumElements, + CI->getName()); + Instruction *Cast = new BitCastInst(Malloc, CI->getType(), "tmp", CI); + CI->replaceAllUsesWith(Cast); CI->eraseFromParent(); - BCI = cast(NewMI); - CI = extractMallocCallFromBitCast(NewMI); + CI = dyn_cast(Malloc) ? + extractMallocCallFromBitCast(Malloc): + cast(Malloc); } - GVI = PerformHeapAllocSRoA(GV, CI, BCI, NElems, Context, TD); + GVI = PerformHeapAllocSRoA(GV, CI, getMallocArraySize(CI, Context, TD), + Context, TD); return true; } } @@ -1577,15 +1588,10 @@ if (OptimizeAwayTrappingUsesOfLoads(GV, SOVC, Context)) return true; } else if (CallInst *CI = extractMallocCall(StoredOnceVal)) { - if (getMallocAllocatedType(CI)) { - BitCastInst* BCI = NULL; - for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); - UI != E; ) - BCI = dyn_cast(cast(*UI++)); - if (BCI && - TryToOptimizeStoreOfMallocToGlobal(GV, CI, BCI, GVI, TD, Context)) - return true; - } + const Type* MallocType = getMallocAllocatedType(CI); + if (MallocType && TryToOptimizeStoreOfMallocToGlobal(GV, CI, MallocType, + GVI, TD, Context)) + return true; } } Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Wed Nov 4 18:03:03 2009 @@ -1699,18 +1699,24 @@ LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { - const Type* IntPtrT = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); - return wrap(unwrap(B)->Insert(CallInst::CreateMalloc( - unwrap(B)->GetInsertBlock(), IntPtrT, unwrap(Ty), 0, 0, ""), - Twine(Name))); + const Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); + Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); + AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); + Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), + ITy, unwrap(Ty), AllocSize, + 0, 0, ""); + return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Val, const char *Name) { - const Type* IntPtrT = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); - return wrap(unwrap(B)->Insert(CallInst::CreateMalloc( - unwrap(B)->GetInsertBlock(), IntPtrT, unwrap(Ty), unwrap(Val), 0, ""), - Twine(Name))); + const Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); + Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); + AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); + Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), + ITy, unwrap(Ty), AllocSize, + unwrap(Val), 0, ""); + return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Wed Nov 4 18:03:03 2009 @@ -24,6 +24,7 @@ #include "llvm/Support/CallSite.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Target/TargetData.h" using namespace llvm; @@ -448,22 +449,11 @@ return isa(val) && cast(val)->isOne(); } -static Value *checkArraySize(Value *Amt, const Type *IntPtrTy) { - if (!Amt) - Amt = ConstantInt::get(IntPtrTy, 1); - else { - assert(!isa(Amt) && - "Passed basic block into malloc size parameter! Use other ctor"); - assert(Amt->getType() == IntPtrTy && - "Malloc array size is not an intptr!"); - } - return Amt; -} - static Instruction *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd, const Type *IntPtrTy, - const Type *AllocTy, Value *ArraySize, - Function *MallocF, const Twine &NameStr) { + const Type *AllocTy, Value *AllocSize, + Value *ArraySize, Function *MallocF, + const Twine &Name) { assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) && "createMalloc needs either InsertBefore or InsertAtEnd"); @@ -471,10 +461,14 @@ // bitcast (i8* malloc(typeSize)) to type* // malloc(type, arraySize) becomes: // bitcast (i8 *malloc(typeSize*arraySize)) to type* - Value *AllocSize = ConstantExpr::getSizeOf(AllocTy); - AllocSize = ConstantExpr::getTruncOrBitCast(cast(AllocSize), - IntPtrTy); - ArraySize = checkArraySize(ArraySize, IntPtrTy); + if (!ArraySize) + ArraySize = ConstantInt::get(IntPtrTy, 1); + else if (ArraySize->getType() != IntPtrTy) { + if (InsertBefore) + ArraySize = CastInst::CreateIntegerCast(ArraySize, IntPtrTy, false, "", InsertBefore); + else + ArraySize = CastInst::CreateIntegerCast(ArraySize, IntPtrTy, false, "", InsertAtEnd); + } if (!IsConstantOne(ArraySize)) { if (IsConstantOne(AllocSize)) { @@ -513,14 +507,14 @@ Result = MCall; if (Result->getType() != AllocPtrType) // Create a cast instruction to convert to the right type... - Result = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore); + Result = new BitCastInst(MCall, AllocPtrType, Name, InsertBefore); } else { MCall = CallInst::Create(MallocF, AllocSize, "malloccall"); Result = MCall; if (Result->getType() != AllocPtrType) { InsertAtEnd->getInstList().push_back(MCall); // Create a cast instruction to convert to the right type... - Result = new BitCastInst(MCall, AllocPtrType, NameStr); + Result = new BitCastInst(MCall, AllocPtrType, Name); } } MCall->setTailCall(); @@ -538,8 +532,9 @@ /// 3. Bitcast the result of the malloc call to the specified type. Instruction *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy, const Type *AllocTy, - Value *ArraySize, const Twine &Name) { - return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, + Value *AllocSize, Value *ArraySize, + const Twine &Name) { + return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, AllocSize, ArraySize, NULL, Name); } @@ -553,9 +548,9 @@ /// responsibility of the caller. Instruction *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy, const Type *AllocTy, - Value *ArraySize, Function* MallocF, - const Twine &Name) { - return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, + Value *AllocSize, Value *ArraySize, + Function *MallocF, const Twine &Name) { + return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, AllocSize, ArraySize, MallocF, Name); } Modified: llvm/trunk/test/Analysis/PointerTracking/sizes.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/PointerTracking/sizes.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Analysis/PointerTracking/sizes.ll (original) +++ llvm/trunk/test/Analysis/PointerTracking/sizes.ll Wed Nov 4 18:03:03 2009 @@ -31,6 +31,7 @@ } declare i32 @bar(i8*) +declare i32 @bar2(i64*) define i32 @foo1(i32 %n) nounwind { entry: @@ -60,11 +61,16 @@ ret i32 %add16 } -define i32 @foo2(i32 %n) nounwind { +define i32 @foo2(i64 %n) nounwind { entry: - %call = malloc i8, i32 %n ; [#uses=1] + %call = tail call i8* @malloc(i64 %n) ; [#uses=1] ; CHECK: %call = ; CHECK: ==> %n elements, %n bytes allocated + %mallocsize = mul i64 %n, 8 ; [#uses=1] + %malloccall = tail call i8* @malloc(i64 %mallocsize) ; [#uses=1] + %call3 = bitcast i8* %malloccall to i64* ; [#uses=1] +; CHECK: %malloccall = +; CHECK: ==> (8 * %n) elements, (8 * %n) bytes allocated %call2 = tail call i8* @calloc(i64 2, i64 4) nounwind ; [#uses=1] ; CHECK: %call2 = ; CHECK: ==> 8 elements, 8 bytes allocated @@ -72,13 +78,17 @@ ; CHECK: %call4 = ; CHECK: ==> 16 elements, 16 bytes allocated %call6 = tail call i32 @bar(i8* %call) nounwind ; [#uses=1] + %call7 = tail call i32 @bar2(i64* %call3) nounwind ; [#uses=1] %call8 = tail call i32 @bar(i8* %call2) nounwind ; [#uses=1] %call10 = tail call i32 @bar(i8* %call4) nounwind ; [#uses=1] - %add = add i32 %call8, %call6 ; [#uses=1] - %add11 = add i32 %add, %call10 ; [#uses=1] + %add = add i32 %call8, %call6 ; [#uses=1] + %add10 = add i32 %add, %call7 ; [#uses=1] + %add11 = add i32 %add10, %call10 ; [#uses=1] ret i32 %add11 } +declare noalias i8* @malloc(i64) nounwind + declare noalias i8* @calloc(i64, i64) nounwind declare noalias i8* @realloc(i8* nocapture, i64) nounwind Modified: llvm/trunk/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll Wed Nov 4 18:03:03 2009 @@ -1,4 +1,5 @@ ; RUN: opt < %s -globalopt +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" %struct.s_annealing_sched = type { i32, float, float, float, float } %struct.s_bb = type { i32, i32, i32, i32 } @@ -96,7 +97,9 @@ unreachable bb1.i38: ; preds = %bb - %0 = malloc %struct.s_net, i32 undef ; <%struct.s_net*> [#uses=1] + %mallocsize = mul i64 28, undef ; [#uses=1] + %malloccall = tail call i8* @malloc(i64 %mallocsize) ; [#uses=1] + %0 = bitcast i8* %malloccall to %struct.s_net* ; <%struct.s_net*> [#uses=1] br i1 undef, label %bb.i1.i39, label %my_malloc.exit2.i bb.i1.i39: ; preds = %bb1.i38 @@ -115,3 +118,5 @@ bb7: ; preds = %bb6.preheader unreachable } + +declare noalias i8* @malloc(i64) Modified: llvm/trunk/test/Transforms/GlobalOpt/heap-sra-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/heap-sra-1.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/heap-sra-1.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/heap-sra-1.ll Wed Nov 4 18:03:03 2009 @@ -1,18 +1,22 @@ -; RUN: opt < %s -globalopt -S | grep {@X.f0} -; RUN: opt < %s -globalopt -S | grep {@X.f1} -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i386-apple-darwin7" +; RUN: opt < %s -globalopt -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" %struct.foo = type { i32, i32 } @X = internal global %struct.foo* null +; CHECK: @X.f0 +; CHECK: @X.f1 -define void @bar(i32 %Size) nounwind noinline { +define void @bar(i64 %Size) nounwind noinline { entry: - %.sub = malloc %struct.foo, i32 %Size + %mallocsize = mul i64 %Size, 8 ; [#uses=1] + %malloccall = tail call i8* @malloc(i64 %mallocsize) ; [#uses=1] + %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1] store %struct.foo* %.sub, %struct.foo** @X, align 4 ret void } +declare noalias i8* @malloc(i64) + define i32 @baz() nounwind readonly noinline { bb1.thread: %0 = load %struct.foo** @X, align 4 Modified: llvm/trunk/test/Transforms/GlobalOpt/heap-sra-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/heap-sra-2.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/heap-sra-2.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/heap-sra-2.ll Wed Nov 4 18:03:03 2009 @@ -1,20 +1,22 @@ -; RUN: opt < %s -globalopt -S | grep {@X.f0} -; RUN: opt < %s -globalopt -S | grep {@X.f1} +; RUN: opt < %s -globalopt -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i386-apple-darwin7" %struct.foo = type { i32, i32 } @X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2] +; CHECK: @X.f0 +; CHECK: @X.f1 define void @bar(i32 %Size) nounwind noinline { entry: - %0 = malloc [1000000 x %struct.foo] - ;%.sub = bitcast [1000000 x %struct.foo]* %0 to %struct.foo* + %malloccall = tail call i8* @malloc(i64 8000000) ; [#uses=1] + %0 = bitcast i8* %malloccall to [1000000 x %struct.foo]* ; <[1000000 x %struct.foo]*> [#uses=1] %.sub = getelementptr [1000000 x %struct.foo]* %0, i32 0, i32 0 ; <%struct.foo*> [#uses=1] store %struct.foo* %.sub, %struct.foo** @X, align 4 ret void } +declare noalias i8* @malloc(i64) + define i32 @baz() nounwind readonly noinline { bb1.thread: %0 = load %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1] Modified: llvm/trunk/test/Transforms/GlobalOpt/heap-sra-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/heap-sra-3.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/heap-sra-3.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/heap-sra-3.ll Wed Nov 4 18:03:03 2009 @@ -1,24 +1,22 @@ ; RUN: opt < %s -globalopt -S | FileCheck %s - -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i386-apple-darwin10" +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" %struct.foo = type { i32, i32 } @X = internal global %struct.foo* null ; CHECK: @X.f0 ; CHECK: @X.f1 -define void @bar(i32 %Size) nounwind noinline { +define void @bar(i64 %Size) nounwind noinline { entry: - %mallocsize = mul i32 ptrtoint (%struct.foo* getelementptr (%struct.foo* null, i32 1) to i32), %Size, ; [#uses=1] -; CHECK: mul i32 %Size - %malloccall = tail call i8* @malloc(i32 %mallocsize) ; [#uses=1] + %mallocsize = mul i64 8, %Size, ; [#uses=1] +; CHECK: mul i64 %Size, 4 + %malloccall = tail call i8* @malloc(i64 %mallocsize) ; [#uses=1] %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1] store %struct.foo* %.sub, %struct.foo** @X, align 4 ret void } -declare noalias i8* @malloc(i32) +declare noalias i8* @malloc(i64) define i32 @baz() nounwind readonly noinline { bb1.thread: Modified: llvm/trunk/test/Transforms/GlobalOpt/heap-sra-4.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/heap-sra-4.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/heap-sra-4.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/heap-sra-4.ll Wed Nov 4 18:03:03 2009 @@ -1,24 +1,22 @@ ; RUN: opt < %s -globalopt -S | FileCheck %s - -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i386-apple-darwin7" +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" %struct.foo = type { i32, i32 } @X = internal global %struct.foo* null ; CHECK: @X.f0 ; CHECK: @X.f1 -define void @bar(i32 %Size) nounwind noinline { +define void @bar(i64 %Size) nounwind noinline { entry: - %mallocsize = shl i32 ptrtoint (%struct.foo* getelementptr (%struct.foo* null, i32 1) to i32), 9, ; [#uses=1] - %malloccall = tail call i8* @malloc(i32 %mallocsize) ; [#uses=1] -; CHECK: @malloc(i32 mul (i32 512 + %mallocsize = shl i64 %Size, 3 ; [#uses=1] + %malloccall = tail call i8* @malloc(i64 %mallocsize) ; [#uses=1] +; CHECK: mul i64 %Size, 4 %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1] store %struct.foo* %.sub, %struct.foo** @X, align 4 ret void } -declare noalias i8* @malloc(i32) +declare noalias i8* @malloc(i64) define i32 @baz() nounwind readonly noinline { bb1.thread: Modified: llvm/trunk/test/Transforms/GlobalOpt/heap-sra-phi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/heap-sra-phi.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/heap-sra-phi.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/heap-sra-phi.ll Wed Nov 4 18:03:03 2009 @@ -1,19 +1,21 @@ ; RUN: opt < %s -globalopt -S | grep {tmp.f1 = phi i32. } ; RUN: opt < %s -globalopt -S | grep {tmp.f0 = phi i32. } +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i386-apple-darwin7" %struct.foo = type { i32, i32 } @X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2] define void @bar(i32 %Size) nounwind noinline { entry: - %tmp = malloc [1000000 x %struct.foo] ; <[1000000 x %struct.foo]*> [#uses=1] + %malloccall = tail call i8* @malloc(i64 8000000) ; [#uses=1] + %tmp = bitcast i8* %malloccall to [1000000 x %struct.foo]* ; <[1000000 x %struct.foo]*> [#uses=1] %.sub = getelementptr [1000000 x %struct.foo]* %tmp, i32 0, i32 0 ; <%struct.foo*> [#uses=1] store %struct.foo* %.sub, %struct.foo** @X, align 4 ret void } +declare noalias i8* @malloc(i64) + define i32 @baz() nounwind readonly noinline { bb1.thread: %tmpLD1 = load %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1] Modified: llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-1.ll Wed Nov 4 18:03:03 2009 @@ -1,19 +1,24 @@ -; RUN: opt < %s -globalopt -S | not grep global +; RUN: opt < %s -globalopt -S | FileCheck %s target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @G = internal global i32* null ; [#uses=3] +; CHECK-NOT: global define void @init() { - %P = malloc i32 ; [#uses=1] + %malloccall = tail call i8* @malloc(i64 4) ; [#uses=1] + %P = bitcast i8* %malloccall to i32* ; [#uses=1] store i32* %P, i32** @G %GV = load i32** @G ; [#uses=1] store i32 0, i32* %GV ret void } +declare noalias i8* @malloc(i64) + define i32 @get() { %GV = load i32** @G ; [#uses=1] %V = load i32* %GV ; [#uses=1] ret i32 %V +; CHECK: ret i32 0 } Modified: llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-2.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-2.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-2.ll Wed Nov 4 18:03:03 2009 @@ -1,11 +1,11 @@ ; RUN: opt < %s -globalopt -globaldce -S | not grep malloc -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i686-apple-darwin8" +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @G = internal global i32* null ; [#uses=3] define void @init() { - %P = malloc i32, i32 100 ; [#uses=1] + %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4)) ; [#uses=1] + %P = bitcast i8* %malloccall to i32* ; [#uses=1] store i32* %P, i32** @G %GV = load i32** @G ; [#uses=1] %GVe = getelementptr i32* %GV, i32 40 ; [#uses=1] @@ -13,6 +13,8 @@ ret void } +declare noalias i8* @malloc(i64) + define i32 @get() { %GV = load i32** @G ; [#uses=1] %GVe = getelementptr i32* %GV, i32 40 ; [#uses=1] Modified: llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-3.ll?rev=86077&r1=86076&r2=86077&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-3.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/malloc-promote-3.ll Wed Nov 4 18:03:03 2009 @@ -1,11 +1,11 @@ ; RUN: opt < %s -globalopt -globaldce -S | not grep malloc -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i686-apple-darwin8" +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @G = internal global i32* null ; [#uses=4] define void @init() { - %P = malloc i32, i32 100 ; [#uses=1] + %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4)) ; [#uses=1] + %P = bitcast i8* %malloccall to i32* ; [#uses=1] store i32* %P, i32** @G %GV = load i32** @G ; [#uses=1] %GVe = getelementptr i32* %GV, i32 40 ; [#uses=1] @@ -13,6 +13,8 @@ ret void } +declare noalias i8* @malloc(i64) + define i32 @get() { %GV = load i32** @G ; [#uses=1] %GVe = getelementptr i32* %GV, i32 40 ; [#uses=1] From david_goodwin at apple.com Wed Nov 4 18:16:45 2009 From: david_goodwin at apple.com (David Goodwin) Date: Thu, 05 Nov 2009 00:16:45 -0000 Subject: [llvm-commits] [llvm] r86080 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200911050016.nA50Gju1008135@zion.cs.uiuc.edu> Author: david_goodwin Date: Wed Nov 4 18:16:44 2009 New Revision: 86080 URL: http://llvm.org/viewvc/llvm-project?rev=86080&view=rev Log: Correctly add chain dependencies around calls and unknown-side-effect instructions. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=86080&r1=86079&r2=86080&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Wed Nov 4 18:16:44 2009 @@ -367,6 +367,7 @@ for (unsigned i = 0, e = I->second.size(); i != e; ++i) I->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency)); I->second.clear(); + I->second.push_back(SU); } // See if it is known to just have a single memory reference. MachineInstr *ChainMI = Chain->getInstr(); @@ -413,7 +414,7 @@ if (Chain) Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0)); } - } else if (MayAlias) { + } else { // Treat all other stores conservatively. goto new_chain; } @@ -439,7 +440,7 @@ // Treat volatile loads conservatively. Note that this includes // cases where memoperand information is unavailable. goto new_chain; - } else if (MayAlias) { + } else { // A "MayAlias" load. Depend on the general chain, as well as on // all stores. In the absense of MachineMemOperand information, // we can't even assume that the load doesn't alias well-behaved From bob.wilson at apple.com Wed Nov 4 18:30:36 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 05 Nov 2009 00:30:36 -0000 Subject: [llvm-commits] [llvm] r86081 - /llvm/trunk/test/CodeGen/ARM/indirectbr.ll Message-ID: <200911050030.nA50UaeI008603@zion.cs.uiuc.edu> Author: bwilson Date: Wed Nov 4 18:30:35 2009 New Revision: 86081 URL: http://llvm.org/viewvc/llvm-project?rev=86081&view=rev Log: Attempt again to fix buildbot failures: make expected output less specific and compile with -mtriple to specify *-apple-darwin targets. Modified: llvm/trunk/test/CodeGen/ARM/indirectbr.ll Modified: llvm/trunk/test/CodeGen/ARM/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/indirectbr.ll?rev=86081&r1=86080&r2=86081&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/indirectbr.ll (original) +++ llvm/trunk/test/CodeGen/ARM/indirectbr.ll Wed Nov 4 18:30:35 2009 @@ -1,6 +1,6 @@ -; RUN: llc < %s -relocation-model=pic -march=arm | FileCheck %s -check-prefix=ARM -; RUN: llc < %s -relocation-model=pic -march=thumb | FileCheck %s -check-prefix=THUMB -; RUN: llc < %s -relocation-model=static -march=thumb -mattr=+thumb2 | FileCheck %s -check-prefix=THUMB2 +; RUN: llc < %s -relocation-model=pic -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=ARM +; RUN: llc < %s -relocation-model=pic -mtriple=thumb-apple-darwin | FileCheck %s -check-prefix=THUMB +; RUN: llc < %s -relocation-model=static -mtriple=thumbv7-apple-darwin | FileCheck %s -check-prefix=THUMB2 @nextaddr = global i8* null ; [#uses=2] @C.0.2070 = private constant [5 x i8*] [i8* blockaddress(@foo, %L1), i8* blockaddress(@foo, %L2), i8* blockaddress(@foo, %L3), i8* blockaddress(@foo, %L4), i8* blockaddress(@foo, %L5)] ; <[5 x i8*]*> [#uses=1] @@ -44,20 +44,17 @@ L1: ; preds = %L2, %bb2 %res.3 = phi i32 [ %phitmp, %L2 ], [ 2, %bb2 ] ; [#uses=1] -; ARM: ldr r1, LCPI1_2 +; ARM: ldr r1, LCPI ; ARM: add r1, pc, r1 ; ARM: str r1 -; THUMB: ldr.n r2, LCPI1_4 +; THUMB: ldr.n r2, LCPI ; THUMB: add r2, pc ; THUMB: str r2 -; THUMB2: ldr.n r2, LCPI1_2 +; THUMB2: ldr.n r2, LCPI ; THUMB2-NEXT: str r2 store i8* blockaddress(@foo, %L5), i8** @nextaddr, align 4 ret i32 %res.3 } -; ARM: LCPI1_2: -; ARM-NEXT: .long L_foo_L5-(LPC2+8) -; THUMB: LCPI1_4: -; THUMB-NEXT: .long L_foo_L5-(LPC2+4) -; THUMB2: LCPI1_2: -; THUMB2-NEXT: .long L_foo_L5 +; ARM: .long L_foo_L5-(LPC{{.*}}+8) +; THUMB: .long L_foo_L5-(LPC{{.*}}+4) +; THUMB2: .long L_foo_L5 From evan.cheng at apple.com Wed Nov 4 18:51:14 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 05 Nov 2009 00:51:14 -0000 Subject: [llvm-commits] [llvm] r86085 - /llvm/trunk/lib/CodeGen/MachineLICM.cpp Message-ID: <200911050051.nA50pEAs009370@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 4 18:51:13 2009 New Revision: 86085 URL: http://llvm.org/viewvc/llvm-project?rev=86085&view=rev Log: Code refactoring. Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=86085&r1=86084&r2=86085&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Wed Nov 4 18:51:13 2009 @@ -111,6 +111,13 @@ /// be hoistable. MachineInstr *ExtractHoistableLoad(MachineInstr *MI); + /// EliminateCSE - Given a LICM'ed instruction, look for an instruction on + /// the preheader that compute the same value. If it's found, do a RAU on + /// with the definition of the existing instruction rather than hoisting + /// the instruction to the preheader. + bool EliminateCSE(MachineInstr *MI, + DenseMap >::iterator &CI); + /// Hoist - When an instruction is found to only use loop invariant operands /// that is safe to hoist, this instruction is called to do the dirty work. /// @@ -349,37 +356,6 @@ return true; } -static const MachineInstr *LookForDuplicate(const MachineInstr *MI, - std::vector &PrevMIs, - MachineRegisterInfo *RegInfo) { - unsigned NumOps = MI->getNumOperands(); - for (unsigned i = 0, e = PrevMIs.size(); i != e; ++i) { - const MachineInstr *PrevMI = PrevMIs[i]; - unsigned NumOps2 = PrevMI->getNumOperands(); - if (NumOps != NumOps2) - continue; - bool IsSame = true; - for (unsigned j = 0; j != NumOps; ++j) { - const MachineOperand &MO = MI->getOperand(j); - if (MO.isReg() && MO.isDef()) { - if (RegInfo->getRegClass(MO.getReg()) != - RegInfo->getRegClass(PrevMI->getOperand(j).getReg())) { - IsSame = false; - break; - } - continue; - } - if (!MO.isIdenticalTo(PrevMI->getOperand(j))) { - IsSame = false; - break; - } - } - if (IsSame) - return PrevMI; - } - return 0; -} - MachineInstr *MachineLICM::ExtractHoistableLoad(MachineInstr *MI) { // If not, we may be able to unfold a load and hoist that. // First test whether the instruction is loading from an amenable @@ -456,6 +432,55 @@ } } +static const MachineInstr *LookForDuplicate(const MachineInstr *MI, + std::vector &PrevMIs, + MachineRegisterInfo *RegInfo) { + unsigned NumOps = MI->getNumOperands(); + for (unsigned i = 0, e = PrevMIs.size(); i != e; ++i) { + const MachineInstr *PrevMI = PrevMIs[i]; + unsigned NumOps2 = PrevMI->getNumOperands(); + if (NumOps != NumOps2) + continue; + bool IsSame = true; + for (unsigned j = 0; j != NumOps; ++j) { + const MachineOperand &MO = MI->getOperand(j); + if (MO.isReg() && MO.isDef()) { + if (RegInfo->getRegClass(MO.getReg()) != + RegInfo->getRegClass(PrevMI->getOperand(j).getReg())) { + IsSame = false; + break; + } + continue; + } + if (!MO.isIdenticalTo(PrevMI->getOperand(j))) { + IsSame = false; + break; + } + } + if (IsSame) + return PrevMI; + } + return 0; +} + +bool MachineLICM::EliminateCSE(MachineInstr *MI, + DenseMap >::iterator &CI) { + if (CI != CSEMap.end()) { + if (const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo)) { + DEBUG(errs() << "CSEing " << *MI << " with " << *Dup); + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (MO.isReg() && MO.isDef()) + RegInfo->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg()); + } + MI->eraseFromParent(); + ++NumCSEed; + return true; + } + } + return false; +} + /// Hoist - When an instruction is found to use only loop invariant operands /// that are safe to hoist, this instruction is called to do the dirty work. /// @@ -488,24 +513,8 @@ unsigned Opcode = MI->getOpcode(); DenseMap >::iterator CI = CSEMap.find(Opcode); - bool DoneCSE = false; - if (CI != CSEMap.end()) { - const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo); - if (Dup) { - DEBUG(errs() << "CSEing " << *MI << " with " << *Dup); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - if (MO.isReg() && MO.isDef()) - RegInfo->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg()); - } - MI->eraseFromParent(); - DoneCSE = true; - ++NumCSEed; - } - } - - // Otherwise, splice the instruction to the preheader. - if (!DoneCSE) { + if (!EliminateCSE(MI, CI)) { + // Otherwise, splice the instruction to the preheader. CurPreheader->splice(CurPreheader->getFirstTerminator(),MI->getParent(),MI); // Add to the CSE map. From bob.wilson at apple.com Wed Nov 4 18:51:31 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 05 Nov 2009 00:51:31 -0000 Subject: [llvm-commits] [llvm] r86086 - /llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll Message-ID: <200911050051.nA50pV25009393@zion.cs.uiuc.edu> Author: bwilson Date: Wed Nov 4 18:51:31 2009 New Revision: 86086 URL: http://llvm.org/viewvc/llvm-project?rev=86086&view=rev Log: Add -mtriple to llc commands, attempting to fix buildbot failures. Modified: llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll Modified: llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll?rev=86086&r1=86085&r2=86086&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/indirectbr.ll Wed Nov 4 18:51:31 2009 @@ -1,5 +1,5 @@ -; RUN: llc < %s -relocation-model=pic -march=ppc32 | FileCheck %s -check-prefix=PIC -; RUN: llc < %s -relocation-model=static -march=ppc32 | FileCheck %s -check-prefix=STATIC +; RUN: llc < %s -relocation-model=pic -march=ppc32 -mtriple=powerpc-apple-darwin | FileCheck %s -check-prefix=PIC +; RUN: llc < %s -relocation-model=static -march=ppc32 -mtriple=powerpc-apple-darwin | FileCheck %s -check-prefix=STATIC @nextaddr = global i8* null ; [#uses=2] @C.0.2070 = private constant [5 x i8*] [i8* blockaddress(@foo, %L1), i8* blockaddress(@foo, %L2), i8* blockaddress(@foo, %L3), i8* blockaddress(@foo, %L4), i8* blockaddress(@foo, %L5)] ; <[5 x i8*]*> [#uses=1] From lhames at gmail.com Wed Nov 4 18:52:28 2009 From: lhames at gmail.com (Lang Hames) Date: Thu, 05 Nov 2009 00:52:28 -0000 Subject: [llvm-commits] [llvm] r86088 - /llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Message-ID: <200911050052.nA50qSF2009447@zion.cs.uiuc.edu> Author: lhames Date: Wed Nov 4 18:52:28 2009 New Revision: 86088 URL: http://llvm.org/viewvc/llvm-project?rev=86088&view=rev Log: Removed an assert which was causing significant slowdowns in debug builds. This assert was very conservative to begin with (the error condition is well covered by tests elsewhere in the code) so we won't miss much by removing it. Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SlotIndexes.h?rev=86088&r1=86087&r2=86088&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Wed Nov 4 18:52:28 2009 @@ -131,7 +131,6 @@ } IndexListEntry& entry() const { - assert(lie.getPointer() != 0 && "Use of invalid index."); return *lie.getPointer(); } From dpatel at apple.com Wed Nov 4 19:13:02 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 05 Nov 2009 01:13:02 -0000 Subject: [llvm-commits] [llvm] r86091 - in /llvm/trunk/lib/AsmParser: LLParser.cpp LLParser.h Message-ID: <200911050113.nA51D2He010220@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 4 19:13:02 2009 New Revision: 86091 URL: http://llvm.org/viewvc/llvm-project?rev=86091&view=rev Log: Use WeakVH while storing metadata in containers. This fixes PR5393. Modified: llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/AsmParser/LLParser.h Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=86091&r1=86090&r2=86091&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Nov 4 19:13:02 2009 @@ -480,17 +480,17 @@ if (ParseUInt32(MID)) return true; // Check existing MDNode. - std::map::iterator I = MetadataCache.find(MID); + std::map::iterator I = MetadataCache.find(MID); if (I != MetadataCache.end()) { - Node = I->second; + Node = cast(I->second); return false; } // Check known forward references. - std::map >::iterator + std::map >::iterator FI = ForwardRefMDNodes.find(MID); if (FI != ForwardRefMDNodes.end()) { - Node = FI->second.first; + Node = cast(FI->second.first); return false; } @@ -570,7 +570,7 @@ MDNode *Init = MDNode::get(Context, Elts.data(), Elts.size()); MetadataCache[MetadataID] = Init; - std::map >::iterator + std::map >::iterator FI = ForwardRefMDNodes.find(MetadataID); if (FI != ForwardRefMDNodes.end()) { MDNode *FwdNode = cast(FI->second.first); Modified: llvm/trunk/lib/AsmParser/LLParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=86091&r1=86090&r2=86091&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.h (original) +++ llvm/trunk/lib/AsmParser/LLParser.h Wed Nov 4 19:13:02 2009 @@ -79,8 +79,8 @@ std::map > ForwardRefTypeIDs; std::vector NumberedTypes; /// MetadataCache - This map keeps track of parsed metadata constants. - std::map MetadataCache; - std::map > ForwardRefMDNodes; + std::map MetadataCache; + std::map > ForwardRefMDNodes; SmallVector, 2> MDsOnInst; struct UpRefRecord { /// Loc - This is the location of the upref. From evan.cheng at apple.com Wed Nov 4 19:16:59 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 05 Nov 2009 01:16:59 -0000 Subject: [llvm-commits] [llvm] r86092 - /llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Message-ID: <200911050116.nA51GxHR010359@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 4 19:16:59 2009 New Revision: 86092 URL: http://llvm.org/viewvc/llvm-project?rev=86092&view=rev Log: Now that code placement optimization pass is run for JIT, make sure it