Date: Thu, 5 Nov 2009 17:17:44 +0000 (UTC) From: Roman Divacky <rdivacky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r198953 - in vendor/llvm/dist: docs/CommandGuide examples/BrainF include/llvm include/llvm/Analysis include/llvm/CodeGen include/llvm/Support include/llvm/Target lib/Analysis lib/AsmPar... Message-ID: <200911051717.nA5HHijb084729@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rdivacky Date: Thu Nov 5 17:17:44 2009 New Revision: 198953 URL: http://svn.freebsd.org/changeset/base/198953 Log: Update LLVM to r86140. Added: vendor/llvm/dist/test/CodeGen/ARM/indirectbr.ll vendor/llvm/dist/test/CodeGen/PowerPC/indirectbr.ll vendor/llvm/dist/test/Transforms/DeadStoreElimination/no-targetdata.ll Modified: vendor/llvm/dist/docs/CommandGuide/lit.pod vendor/llvm/dist/examples/BrainF/BrainF.cpp vendor/llvm/dist/include/llvm/Analysis/MemoryBuiltins.h vendor/llvm/dist/include/llvm/CodeGen/AsmPrinter.h vendor/llvm/dist/include/llvm/CodeGen/SlotIndexes.h vendor/llvm/dist/include/llvm/Instructions.h vendor/llvm/dist/include/llvm/Support/ConstantFolder.h vendor/llvm/dist/include/llvm/Support/Format.h vendor/llvm/dist/include/llvm/Support/LeakDetector.h vendor/llvm/dist/include/llvm/Support/OutputBuffer.h vendor/llvm/dist/include/llvm/Support/PassNameParser.h vendor/llvm/dist/include/llvm/Support/RecyclingAllocator.h vendor/llvm/dist/include/llvm/Support/TargetFolder.h vendor/llvm/dist/include/llvm/Target/TargetIntrinsicInfo.h vendor/llvm/dist/lib/Analysis/DebugInfo.cpp vendor/llvm/dist/lib/Analysis/MemoryBuiltins.cpp vendor/llvm/dist/lib/AsmParser/LLParser.cpp vendor/llvm/dist/lib/AsmParser/LLParser.h vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp vendor/llvm/dist/lib/CodeGen/AggressiveAntiDepBreaker.cpp vendor/llvm/dist/lib/CodeGen/AggressiveAntiDepBreaker.h vendor/llvm/dist/lib/CodeGen/AsmPrinter/AsmPrinter.cpp vendor/llvm/dist/lib/CodeGen/AsmPrinter/DwarfDebug.cpp vendor/llvm/dist/lib/CodeGen/LLVMTargetMachine.cpp vendor/llvm/dist/lib/CodeGen/MachineLICM.cpp vendor/llvm/dist/lib/CodeGen/PostRASchedulerList.cpp vendor/llvm/dist/lib/CodeGen/ScheduleDAGInstrs.cpp vendor/llvm/dist/lib/CodeGen/SlotIndexes.cpp vendor/llvm/dist/lib/Support/MemoryBuffer.cpp vendor/llvm/dist/lib/System/Win32/Path.inc vendor/llvm/dist/lib/Target/ARM/ARMBaseRegisterInfo.cpp vendor/llvm/dist/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp vendor/llvm/dist/lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp vendor/llvm/dist/lib/Target/Blackfin/BlackfinIntrinsicInfo.h vendor/llvm/dist/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp vendor/llvm/dist/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.cpp vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.h vendor/llvm/dist/lib/Target/PowerPC/PPCInstr64Bit.td vendor/llvm/dist/lib/Target/PowerPC/PPCInstrInfo.td vendor/llvm/dist/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp vendor/llvm/dist/lib/Transforms/IPO/GlobalOpt.cpp vendor/llvm/dist/lib/Transforms/Scalar/DeadStoreElimination.cpp vendor/llvm/dist/lib/Transforms/Scalar/JumpThreading.cpp vendor/llvm/dist/lib/Transforms/Scalar/SCCP.cpp vendor/llvm/dist/lib/VMCore/Core.cpp vendor/llvm/dist/lib/VMCore/Instructions.cpp vendor/llvm/dist/test/Analysis/PointerTracking/sizes.ll vendor/llvm/dist/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll vendor/llvm/dist/test/Transforms/GlobalOpt/heap-sra-1.ll vendor/llvm/dist/test/Transforms/GlobalOpt/heap-sra-2.ll vendor/llvm/dist/test/Transforms/GlobalOpt/heap-sra-3.ll vendor/llvm/dist/test/Transforms/GlobalOpt/heap-sra-4.ll vendor/llvm/dist/test/Transforms/GlobalOpt/heap-sra-phi.ll vendor/llvm/dist/test/Transforms/GlobalOpt/malloc-promote-1.ll vendor/llvm/dist/test/Transforms/GlobalOpt/malloc-promote-2.ll vendor/llvm/dist/test/Transforms/GlobalOpt/malloc-promote-3.ll vendor/llvm/dist/test/Transforms/JumpThreading/crash.ll vendor/llvm/dist/utils/lit/LitConfig.py vendor/llvm/dist/utils/lit/lit.py Modified: vendor/llvm/dist/docs/CommandGuide/lit.pod ============================================================================== --- vendor/llvm/dist/docs/CommandGuide/lit.pod Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/docs/CommandGuide/lit.pod Thu Nov 5 17:17:44 2009 (r198953) @@ -54,6 +54,12 @@ number of detected available CPUs. Search for I<NAME.cfg> and I<NAME.site.cfg> when searching for test suites, instead I<lit.cfg> and I<lit.site.cfg>. +=item B<--param> I<NAME>, B<--param> I<NAME>=I<VALUE> + +Add a user defined parameter I<NAME> with the given I<VALUE> (or the empty +string if not given). The meaning and use of these parameters is test suite +dependent. + =back =head1 OUTPUT OPTIONS Modified: vendor/llvm/dist/examples/BrainF/BrainF.cpp ============================================================================== --- vendor/llvm/dist/examples/BrainF/BrainF.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/examples/BrainF/BrainF.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -81,8 +81,11 @@ void BrainF::header(LLVMContext& C) { 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<Instruction>(ptr_arr)); //call void @llvm.memset.i32(i8 *%arr, i8 0, i32 %d, i32 1) Modified: vendor/llvm/dist/include/llvm/Analysis/MemoryBuiltins.h ============================================================================== --- vendor/llvm/dist/include/llvm/Analysis/MemoryBuiltins.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Analysis/MemoryBuiltins.h Thu Nov 5 17:17:44 2009 (r198953) @@ -50,13 +50,17 @@ const CallInst* isArrayMalloc(const Valu 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: vendor/llvm/dist/include/llvm/CodeGen/AsmPrinter.h ============================================================================== --- vendor/llvm/dist/include/llvm/CodeGen/AsmPrinter.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/CodeGen/AsmPrinter.h Thu Nov 5 17:17:44 2009 (r198953) @@ -374,8 +374,10 @@ namespace llvm { /// 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: vendor/llvm/dist/include/llvm/CodeGen/SlotIndexes.h ============================================================================== --- vendor/llvm/dist/include/llvm/CodeGen/SlotIndexes.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/CodeGen/SlotIndexes.h Thu Nov 5 17:17:44 2009 (r198953) @@ -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 @@ namespace llvm { class IndexListEntry { private: + static std::auto_ptr<IndexListEntry> 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 @@ namespace llvm { 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 @@ namespace llvm { friend class DenseMapInfo<SlotIndex>; private: - - // FIXME: Is there any way to statically allocate these things and have - // them 8-byte aligned? - static std::auto_ptr<IndexListEntry> emptyKeyPtr, tombstoneKeyPtr; static const unsigned PHI_BIT = 1 << 2; PointerIntPair<IndexListEntry*, 3, unsigned> lie; @@ -95,7 +131,6 @@ namespace llvm { } IndexListEntry& entry() const { - assert(lie.getPointer() != 0 && "Use of invalid index."); return *lie.getPointer(); } @@ -116,25 +151,15 @@ namespace llvm { 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. - SlotIndex() : lie(&getEmptyKey().entry(), 0) {} + SlotIndex() : lie(IndexListEntry::getEmptyKeyEntry(), 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. Modified: vendor/llvm/dist/include/llvm/Instructions.h ============================================================================== --- vendor/llvm/dist/include/llvm/Instructions.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Instructions.h Thu Nov 5 17:17:44 2009 (r198953) @@ -899,11 +899,12 @@ public: /// 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: vendor/llvm/dist/include/llvm/Support/ConstantFolder.h ============================================================================== --- vendor/llvm/dist/include/llvm/Support/ConstantFolder.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Support/ConstantFolder.h Thu Nov 5 17:17:44 2009 (r198953) @@ -18,6 +18,8 @@ #define LLVM_SUPPORT_CONSTANTFOLDER_H #include "llvm/Constants.h" +#include "llvm/Instruction.h" +#include "llvm/InstrTypes.h" namespace llvm { Modified: vendor/llvm/dist/include/llvm/Support/Format.h ============================================================================== --- vendor/llvm/dist/include/llvm/Support/Format.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Support/Format.h Thu Nov 5 17:17:44 2009 (r198953) @@ -23,6 +23,7 @@ #ifndef LLVM_SUPPORT_FORMAT_H #define LLVM_SUPPORT_FORMAT_H +#include <cassert> #include <cstdio> #ifdef WIN32 #define snprintf _snprintf Modified: vendor/llvm/dist/include/llvm/Support/LeakDetector.h ============================================================================== --- vendor/llvm/dist/include/llvm/Support/LeakDetector.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Support/LeakDetector.h Thu Nov 5 17:17:44 2009 (r198953) @@ -26,6 +26,7 @@ namespace llvm { +class LLVMContext; class Value; struct LeakDetector { Modified: vendor/llvm/dist/include/llvm/Support/OutputBuffer.h ============================================================================== --- vendor/llvm/dist/include/llvm/Support/OutputBuffer.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Support/OutputBuffer.h Thu Nov 5 17:17:44 2009 (r198953) @@ -14,6 +14,7 @@ #ifndef LLVM_SUPPORT_OUTPUTBUFFER_H #define LLVM_SUPPORT_OUTPUTBUFFER_H +#include <cassert> #include <string> #include <vector> Modified: vendor/llvm/dist/include/llvm/Support/PassNameParser.h ============================================================================== --- vendor/llvm/dist/include/llvm/Support/PassNameParser.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Support/PassNameParser.h Thu Nov 5 17:17:44 2009 (r198953) @@ -25,6 +25,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Pass.h" #include <algorithm> #include <cstring> Modified: vendor/llvm/dist/include/llvm/Support/RecyclingAllocator.h ============================================================================== --- vendor/llvm/dist/include/llvm/Support/RecyclingAllocator.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Support/RecyclingAllocator.h Thu Nov 5 17:17:44 2009 (r198953) @@ -41,7 +41,7 @@ public: /// SubClass. The storage may be either newly allocated or recycled. /// template<class SubClass> - SubClass *Allocate() { return Base.Allocate<SubClass>(Allocator); } + SubClass *Allocate() { return Base.template Allocate<SubClass>(Allocator); } T *Allocate() { return Base.Allocate(Allocator); } Modified: vendor/llvm/dist/include/llvm/Support/TargetFolder.h ============================================================================== --- vendor/llvm/dist/include/llvm/Support/TargetFolder.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Support/TargetFolder.h Thu Nov 5 17:17:44 2009 (r198953) @@ -20,6 +20,8 @@ #define LLVM_SUPPORT_TARGETFOLDER_H #include "llvm/Constants.h" +#include "llvm/Instruction.h" +#include "llvm/InstrTypes.h" #include "llvm/Analysis/ConstantFolding.h" namespace llvm { Modified: vendor/llvm/dist/include/llvm/Target/TargetIntrinsicInfo.h ============================================================================== --- vendor/llvm/dist/include/llvm/Target/TargetIntrinsicInfo.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/include/llvm/Target/TargetIntrinsicInfo.h Thu Nov 5 17:17:44 2009 (r198953) @@ -14,6 +14,8 @@ #ifndef LLVM_TARGET_TARGETINTRINSICINFO_H #define LLVM_TARGET_TARGETINTRINSICINFO_H +#include <string> + namespace llvm { class Function; @@ -32,7 +34,13 @@ public: virtual ~TargetIntrinsicInfo(); /// Return the name of a target intrinsic, e.g. "llvm.bfin.ssync". - virtual const char *getName(unsigned IntrID) const =0; + /// The Tys and numTys parameters are for intrinsics with overloaded types + /// (e.g., those using iAny or fAny). For a declaration for an overloaded + /// intrinsic, Tys should point to an array of numTys pointers to Type, + /// and must provide exactly one type for each overloaded type in the + /// intrinsic. + virtual std::string getName(unsigned IID, const Type **Tys = 0, + unsigned numTys = 0) const = 0; /// Look up target intrinsic by name. Return intrinsic ID or 0 for unknown /// names. @@ -40,6 +48,15 @@ public: /// Return the target intrinsic ID of a function, or 0. virtual unsigned getIntrinsicID(Function *F) const; + + /// Returns true if the intrinsic can be overloaded. + virtual bool isOverloaded(unsigned IID) const = 0; + + /// Create or insert an LLVM Function declaration for an intrinsic, + /// and return it. The Tys and numTys are for intrinsics with overloaded + /// types. See above for more information. + virtual Function *getDeclaration(Module *M, unsigned ID, const Type **Tys = 0, + unsigned numTys = 0) const = 0; }; } // End llvm namespace Modified: vendor/llvm/dist/lib/Analysis/DebugInfo.cpp ============================================================================== --- vendor/llvm/dist/lib/Analysis/DebugInfo.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/Analysis/DebugInfo.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -401,12 +401,18 @@ bool DIVariable::Verify() const { /// 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: vendor/llvm/dist/lib/Analysis/MemoryBuiltins.cpp ============================================================================== --- vendor/llvm/dist/lib/Analysis/MemoryBuiltins.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/Analysis/MemoryBuiltins.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -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 @@ static Value *isArrayMallocHelper(const 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<ConstantExpr>(MallocArg); BinaryOperator *BO = dyn_cast<BinaryOperator>(MallocArg); - Constant *ElementSize = ConstantExpr::getSizeOf(T); - ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, - MallocArg->getType()); - Constant *FoldedElementSize = - ConstantFoldConstantExpression(cast<ConstantExpr>(ElementSize), Context, TD); + unsigned ElementSizeInt = TD->getTypeAllocSize(T); + if (const StructType *ST = dyn_cast<StructType>(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<ConstantInt>(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 @@ static Value *isArrayMallocHelper(const // 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 @@ static Value *isArrayMallocHelper(const 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 @@ const CallInst *llvm::isArrayMalloc(cons } /// 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<BitCastInst>(cast<Instruction>(*UI++)))) - break; + if (const BitCastInst *BCI = dyn_cast<BitCastInst>(*UI++)) { + MallocType = cast<PointerType>(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<PointerType>(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<PointerType>(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: vendor/llvm/dist/lib/AsmParser/LLParser.cpp ============================================================================== --- vendor/llvm/dist/lib/AsmParser/LLParser.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/AsmParser/LLParser.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -480,17 +480,17 @@ bool LLParser::ParseMDNode(MetadataBase if (ParseUInt32(MID)) return true; // Check existing MDNode. - std::map<unsigned, MetadataBase *>::iterator I = MetadataCache.find(MID); + std::map<unsigned, WeakVH>::iterator I = MetadataCache.find(MID); if (I != MetadataCache.end()) { - Node = I->second; + Node = cast<MetadataBase>(I->second); return false; } // Check known forward references. - std::map<unsigned, std::pair<MetadataBase *, LocTy> >::iterator + std::map<unsigned, std::pair<WeakVH, LocTy> >::iterator FI = ForwardRefMDNodes.find(MID); if (FI != ForwardRefMDNodes.end()) { - Node = FI->second.first; + Node = cast<MetadataBase>(FI->second.first); return false; } @@ -570,7 +570,7 @@ bool LLParser::ParseStandaloneMetadata() MDNode *Init = MDNode::get(Context, Elts.data(), Elts.size()); MetadataCache[MetadataID] = Init; - std::map<unsigned, std::pair<MetadataBase *, LocTy> >::iterator + std::map<unsigned, std::pair<WeakVH, LocTy> >::iterator FI = ForwardRefMDNodes.find(MetadataID); if (FI != ForwardRefMDNodes.end()) { MDNode *FwdNode = cast<MDNode>(FI->second.first); @@ -3619,12 +3619,14 @@ bool LLParser::ParseAlloc(Instruction *& // 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<Function>( 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: vendor/llvm/dist/lib/AsmParser/LLParser.h ============================================================================== --- vendor/llvm/dist/lib/AsmParser/LLParser.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/AsmParser/LLParser.h Thu Nov 5 17:17:44 2009 (r198953) @@ -79,8 +79,8 @@ namespace llvm { std::map<unsigned, std::pair<PATypeHolder, LocTy> > ForwardRefTypeIDs; std::vector<PATypeHolder> NumberedTypes; /// MetadataCache - This map keeps track of parsed metadata constants. - std::map<unsigned, MetadataBase *> MetadataCache; - std::map<unsigned, std::pair<MetadataBase *, LocTy> > ForwardRefMDNodes; + std::map<unsigned, WeakVH> MetadataCache; + std::map<unsigned, std::pair<WeakVH, LocTy> > ForwardRefMDNodes; SmallVector<std::pair<unsigned, MDNode *>, 2> MDsOnInst; struct UpRefRecord { /// Loc - This is the location of the upref. Modified: vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp ============================================================================== --- vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -2101,8 +2101,10 @@ bool BitcodeReader::ParseFunctionBody(Fu 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: vendor/llvm/dist/lib/CodeGen/AggressiveAntiDepBreaker.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/AggressiveAntiDepBreaker.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/CodeGen/AggressiveAntiDepBreaker.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -491,8 +491,9 @@ BitVector AggressiveAntiDepBreaker::GetR } bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( - unsigned AntiDepGroupIndex, - std::map<unsigned, unsigned> &RenameMap) { + unsigned AntiDepGroupIndex, + RenameOrderType& RenameOrder, + std::map<unsigned, unsigned> &RenameMap) { unsigned *KillIndices = State->GetKillIndices(); unsigned *DefIndices = State->GetDefIndices(); std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& @@ -547,22 +548,41 @@ bool AggressiveAntiDepBreaker::FindSuita if (Regs.size() > 1) return false; - // Check each possible rename register for SuperReg. If that register - // is available, and the corresponding registers are available for - // the other group subregisters, then we can use those registers to - // rename. - DEBUG(errs() << "\tFind Register:"); + // Check each possible rename register for SuperReg in round-robin + // order. If that register is available, and the corresponding + // registers are available for the other group subregisters, then we + // can use those registers to rename. BitVector SuperBV = RenameRegisterMap[SuperReg]; - for (int r = SuperBV.find_first(); r != -1; r = SuperBV.find_next(r)) { - const unsigned Reg = (unsigned)r; + const TargetRegisterClass *SuperRC = + TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other); + + const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF); + const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF); + if (RB == RE) { + DEBUG(errs() << "\tEmpty Regclass!!\n"); + return false; + } + + if (RenameOrder.count(SuperRC) == 0) + RenameOrder.insert(RenameOrderType::value_type(SuperRC, RE)); + + DEBUG(errs() << "\tFind Register:"); + + const TargetRegisterClass::iterator OrigR = RenameOrder[SuperRC]; + const TargetRegisterClass::iterator EndR = ((OrigR == RE) ? RB : OrigR); + TargetRegisterClass::iterator R = OrigR; + do { + if (R == RB) R = RE; + --R; + const unsigned Reg = *R; // Don't replace a register with itself. if (Reg == SuperReg) continue; - + DEBUG(errs() << " " << TRI->getName(Reg)); - + // If Reg is dead and Reg's most recent def is not before - // SuperRegs's kill, it's safe to replace SuperReg with - // Reg. We must also check all subregisters of Reg. + // SuperRegs's kill, it's safe to replace SuperReg with Reg. We + // must also check all subregisters of Reg. if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { DEBUG(errs() << "(live)"); continue; @@ -580,13 +600,15 @@ bool AggressiveAntiDepBreaker::FindSuita if (found) continue; } - + if (Reg != 0) { DEBUG(errs() << '\n'); + RenameOrder.erase(SuperRC); + RenameOrder.insert(RenameOrderType::value_type(SuperRC, R)); RenameMap.insert(std::pair<unsigned, unsigned>(SuperReg, Reg)); return true; } - } + } while (R != EndR); DEBUG(errs() << '\n'); @@ -627,6 +649,9 @@ unsigned AggressiveAntiDepBreaker::Break State = new AggressiveAntiDepState(*SavedState); } } + + // For each regclass the next register to use for renaming. + RenameOrderType RenameOrder; // ...need a map from MI to SUnit. std::map<MachineInstr *, SUnit *> MISUnitMap; @@ -738,7 +763,7 @@ unsigned AggressiveAntiDepBreaker::Break // Look for a suitable register to use to break the anti-dependence. std::map<unsigned, unsigned> RenameMap; - if (FindSuitableFreeRegisters(GroupIndex, RenameMap)) { + if (FindSuitableFreeRegisters(GroupIndex, RenameOrder, RenameMap)) { DEBUG(errs() << "\tBreaking anti-dependence edge on " << TRI->getName(AntiDepReg) << ":"); Modified: vendor/llvm/dist/lib/CodeGen/AggressiveAntiDepBreaker.h ============================================================================== --- vendor/llvm/dist/lib/CodeGen/AggressiveAntiDepBreaker.h Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/CodeGen/AggressiveAntiDepBreaker.h Thu Nov 5 17:17:44 2009 (r198953) @@ -155,6 +155,9 @@ namespace llvm { void FinishBlock(); private: + typedef std::map<const TargetRegisterClass *, + TargetRegisterClass::const_iterator> RenameOrderType; + /// IsImplicitDefUse - Return true if MO represents a register /// that is both implicitly used and defined in MI bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO); @@ -169,6 +172,7 @@ namespace llvm { void ScanInstruction(MachineInstr *MI, unsigned Count); BitVector GetRenameRegisters(unsigned Reg); bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex, + RenameOrderType& RenameOrder, std::map<unsigned, unsigned> &RenameMap); }; } Modified: vendor/llvm/dist/lib/CodeGen/AsmPrinter/AsmPrinter.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -1590,6 +1590,17 @@ void AsmPrinter::printImplicitDef(const << 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() ? "<def>" : "<kill>"); + } +} + /// printLabel - This method prints a local label used by debug and /// exception handling tables. void AsmPrinter::printLabel(const MachineInstr *MI) const { Modified: vendor/llvm/dist/lib/CodeGen/AsmPrinter/DwarfDebug.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -1137,6 +1137,9 @@ DIE *DwarfDebug::CreateMemberDIE(Compile 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 = DT.getOriginalTypeSize(); @@ -1155,12 +1158,16 @@ DIE *DwarfDebug::CreateMemberDIE(Compile // 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, Modified: vendor/llvm/dist/lib/CodeGen/LLVMTargetMachine.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/LLVMTargetMachine.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/CodeGen/LLVMTargetMachine.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -31,6 +31,22 @@ namespace llvm { bool EnableFastISel; } +static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden, + cl::desc("Disable Post Regalloc")); +static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden, + cl::desc("Disable branch folding")); +static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden, + cl::desc("Disable code placement")); +static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden, + cl::desc("Disable Stack Slot Coloring")); +static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden, + cl::desc("Disable Machine LICM")); +static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden, + cl::desc("Disable Machine Sinking")); +static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden, + cl::desc("Disable Loop Strength Reduction Pass")); +static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden, + cl::desc("Disable Codegen Prepare")); static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden, cl::desc("Print LLVM IR produced by the loop-reduce pass")); static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden, @@ -208,7 +224,7 @@ bool LLVMTargetMachine::addCommonCodeGen // 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 @@ bool LLVMTargetMachine::addCommonCodeGen // 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 @@ bool LLVMTargetMachine::addCommonCodeGen /* 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 @@ bool LLVMTargetMachine::addCommonCodeGen 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 @@ bool LLVMTargetMachine::addCommonCodeGen 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"); } @@ -324,13 +342,13 @@ bool LLVMTargetMachine::addCommonCodeGen PM.add(createDebugLabelFoldingPass()); printAndVerify(PM, "After DebugLabelFolding"); - 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"); } + if (addPreEmitPass(PM, OptLevel)) + printAndVerify(PM, "After PreEmit passes"); + return false; } Modified: vendor/llvm/dist/lib/CodeGen/MachineLICM.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/MachineLICM.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/CodeGen/MachineLICM.cpp Thu Nov 5 17:17:44 2009 (r198953) @@ -111,6 +111,13 @@ namespace { /// 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<unsigned, std::vector<const MachineInstr*> >::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 @@ bool MachineLICM::IsProfitableToHoist(Ma return true; } -static const MachineInstr *LookForDuplicate(const MachineInstr *MI, - std::vector<const MachineInstr*> &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 @@ void MachineLICM::InitCSEMap(MachineBasi } } +static const MachineInstr *LookForDuplicate(const MachineInstr *MI, + std::vector<const MachineInstr*> &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<unsigned, std::vector<const MachineInstr*> >::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 @@ void MachineLICM::Hoist(MachineInstr *MI unsigned Opcode = MI->getOpcode(); DenseMap<unsigned, std::vector<const MachineInstr*> >::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. Modified: vendor/llvm/dist/lib/CodeGen/PostRASchedulerList.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/PostRASchedulerList.cpp Thu Nov 5 16:30:16 2009 (r198952) +++ vendor/llvm/dist/lib/CodeGen/PostRASchedulerList.cpp Thu Nov 5 17:17:44 2009 (r198953) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911051717.nA5HHijb084729>