diff options
316 files changed, 7088 insertions, 14172 deletions
diff --git a/contrib/llvm/include/llvm-c/lto.h b/contrib/llvm/include/llvm-c/lto.h index 5d9cecb..f43d365 100644 --- a/contrib/llvm/include/llvm-c/lto.h +++ b/contrib/llvm/include/llvm-c/lto.h @@ -251,12 +251,6 @@ lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args, int nargs); /** - * Enables the internalize pass during LTO optimizations. - */ -extern void -lto_codegen_set_whole_program_optimization(lto_code_gen_t cg); - -/** * Adds to a list of all global symbols that must exist in the final * generated code. If a function is not listed, it might be * inlined into every usage and optimized away. diff --git a/contrib/llvm/include/llvm/ADT/SmallPtrSet.h b/contrib/llvm/include/llvm/ADT/SmallPtrSet.h index 70693d5..498a034 100644 --- a/contrib/llvm/include/llvm/ADT/SmallPtrSet.h +++ b/contrib/llvm/include/llvm/ADT/SmallPtrSet.h @@ -126,9 +126,6 @@ protected: private: bool isSmall() const { return CurArray == SmallArray; } - unsigned Hash(const void *Ptr) const { - return static_cast<unsigned>(((uintptr_t)Ptr >> 4) & (CurArraySize-1)); - } const void * const *FindBucketFor(const void *Ptr) const; void shrink_and_clear(); diff --git a/contrib/llvm/include/llvm/ADT/StringMap.h b/contrib/llvm/include/llvm/ADT/StringMap.h index 097418e..b4497a2 100644 --- a/contrib/llvm/include/llvm/ADT/StringMap.h +++ b/contrib/llvm/include/llvm/ADT/StringMap.h @@ -239,7 +239,7 @@ public: explicit StringMap(AllocatorTy A) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {} - explicit StringMap(const StringMap &RHS) + StringMap(const StringMap &RHS) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { assert(RHS.empty() && "Copy ctor from non-empty stringmap not implemented yet!"); diff --git a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h index 2d2db78..ee1ed07 100644 --- a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h +++ b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h @@ -28,7 +28,6 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/ADT/DenseMap.h" -#include <map> namespace llvm { @@ -37,7 +36,7 @@ class MachineInstr; class MachineLoopInfo; class MachineDominatorTree; class InstrItineraryData; -class DefaultVLIWScheduler; +class ScheduleDAGInstrs; class SUnit; class DFAPacketizer { @@ -78,8 +77,6 @@ public: // reserveResources - Reserve the resources occupied by a machine // instruction and change the current state to reflect that change. void reserveResources(llvm::MachineInstr *MI); - - const InstrItineraryData *getInstrItins() const { return InstrItins; } }; // VLIWPacketizerList - Implements a simple VLIW packetizer using DFA. The @@ -90,21 +87,20 @@ public: // and machine resource is marked as taken. If any dependency is found, a target // API call is made to prune the dependence. class VLIWPacketizerList { -protected: const TargetMachine &TM; const MachineFunction &MF; const TargetInstrInfo *TII; - // The VLIW Scheduler. - DefaultVLIWScheduler *VLIWScheduler; + // Encapsulate data types not exposed to the target interface. + ScheduleDAGInstrs *SchedulerImpl; +protected: // Vector of instructions assigned to the current packet. std::vector<MachineInstr*> CurrentPacketMIs; // DFA resource tracker. DFAPacketizer *ResourceTracker; - - // Generate MI -> SU map. - std::map<MachineInstr*, SUnit*> MIToSUnit; + // Scheduling units. + std::vector<SUnit> SUnits; public: VLIWPacketizerList( @@ -122,32 +118,17 @@ public: DFAPacketizer *getResourceTracker() {return ResourceTracker;} // addToPacket - Add MI to the current packet. - virtual MachineBasicBlock::iterator addToPacket(MachineInstr *MI) { - MachineBasicBlock::iterator MII = MI; - CurrentPacketMIs.push_back(MI); - ResourceTracker->reserveResources(MI); - return MII; - } + void addToPacket(MachineInstr *MI); // endPacket - End the current packet. - void endPacket(MachineBasicBlock *MBB, MachineInstr *MI); - - // initPacketizerState - perform initialization before packetizing - // an instruction. This function is supposed to be overrided by - // the target dependent packetizer. - virtual void initPacketizerState(void) { return; } + void endPacket(MachineBasicBlock *MBB, MachineInstr *I); // ignorePseudoInstruction - Ignore bundling of pseudo instructions. - virtual bool ignorePseudoInstruction(MachineInstr *I, - MachineBasicBlock *MBB) { - return false; - } + bool ignorePseudoInstruction(MachineInstr *I, MachineBasicBlock *MBB); - // isSoloInstruction - return true if instruction MI can not be packetized - // with any other instruction, which means that MI itself is a packet. - virtual bool isSoloInstruction(MachineInstr *MI) { - return true; - } + // isSoloInstruction - return true if instruction I must end previous + // packet. + bool isSoloInstruction(MachineInstr *I); // isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ // together. @@ -160,7 +141,6 @@ public: virtual bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) { return false; } - }; } diff --git a/contrib/llvm/include/llvm/CodeGen/Passes.h b/contrib/llvm/include/llvm/CodeGen/Passes.h index 3b38199..e76fe99 100644 --- a/contrib/llvm/include/llvm/CodeGen/Passes.h +++ b/contrib/llvm/include/llvm/CodeGen/Passes.h @@ -56,7 +56,7 @@ public: protected: TargetMachine *TM; - PassManagerBase &PM; + PassManagerBase *PM; PassConfigImpl *Impl; // Internal data structures bool Initialized; // Flagged after all passes are configured. diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h index c8de7bc..4fee108 100644 --- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -181,6 +181,13 @@ namespace llvm { /// the def-side latency only. bool UnitLatencies; + /// The standard DAG builder does not normally include terminators as DAG + /// nodes because it does not create the necessary dependencies to prevent + /// reordering. A specialized scheduler can overide + /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate + /// it has taken responsibility for scheduling the terminator correctly. + bool CanHandleTerminators; + /// State specific to the current scheduling region. /// ------------------------------------------------ diff --git a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h index d868cb8..0457e43 100644 --- a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h +++ b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h @@ -23,6 +23,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/ilist.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" @@ -33,8 +34,7 @@ namespace llvm { /// SlotIndexes pass. It should not be used directly. See the /// SlotIndex & SlotIndexes classes for the public interface to this /// information. - class IndexListEntry { - IndexListEntry *next, *prev; + class IndexListEntry : public ilist_node<IndexListEntry> { MachineInstr *mi; unsigned index; @@ -51,31 +51,26 @@ namespace llvm { 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; - } }; - // Specialize PointerLikeTypeTraits for IndexListEntry. template <> - class PointerLikeTypeTraits<IndexListEntry*> { + struct ilist_traits<IndexListEntry> : public ilist_default_traits<IndexListEntry> { + private: + mutable ilist_half_node<IndexListEntry> Sentinel; public: - static inline void* getAsVoidPointer(IndexListEntry *p) { - return p; + IndexListEntry *createSentinel() const { + return static_cast<IndexListEntry*>(&Sentinel); } - static inline IndexListEntry* getFromVoidPointer(void *p) { - return static_cast<IndexListEntry*>(p); - } - enum { NumLowBitsAvailable = 3 }; + void destroySentinel(IndexListEntry *) const {} + + IndexListEntry *provideInitialHead() const { return createSentinel(); } + IndexListEntry *ensureHead(IndexListEntry*) const { return createSentinel(); } + static void noteHead(IndexListEntry*, IndexListEntry*) {} + void deleteNode(IndexListEntry *N) {} + + private: + void createNode(const IndexListEntry &); }; /// SlotIndex - An opaque wrapper around machine indexes. @@ -112,13 +107,13 @@ namespace llvm { SlotIndex(IndexListEntry *entry, unsigned slot) : lie(entry, slot) {} - IndexListEntry& entry() const { + IndexListEntry* listEntry() const { assert(isValid() && "Attempt to compare reserved index."); - return *lie.getPointer(); + return lie.getPointer(); } int getIndex() const { - return entry().getIndex() | getSlot(); + return listEntry()->getIndex() | getSlot(); } /// Returns the slot for this SlotIndex. @@ -150,8 +145,7 @@ namespace llvm { SlotIndex() : lie(0, 0) {} // Construct a new slot index from the given one, and set the slot. - SlotIndex(const SlotIndex &li, Slot s) - : lie(&li.entry(), unsigned(s)) { + SlotIndex(const SlotIndex &li, Slot s) : lie(li.listEntry(), unsigned(s)) { assert(lie.getPointer() != 0 && "Attempt to construct index with 0 pointer."); } @@ -179,7 +173,7 @@ namespace llvm { bool operator!=(SlotIndex other) const { return lie != other.lie; } - + /// Compare two SlotIndex objects. Return true if the first index /// is strictly lower than the second. bool operator<(SlotIndex other) const { @@ -211,7 +205,7 @@ namespace llvm { /// isEarlierInstr - Return true if A refers to an instruction earlier than /// B. This is equivalent to A < B && !isSameInstr(A, B). static bool isEarlierInstr(SlotIndex A, SlotIndex B) { - return A.entry().getIndex() < B.entry().getIndex(); + return A.listEntry()->getIndex() < B.listEntry()->getIndex(); } /// Return the distance from this index to the given one. @@ -236,25 +230,25 @@ namespace llvm { /// is the one associated with the Slot_Block slot for the instruction /// pointed to by this index. SlotIndex getBaseIndex() const { - return SlotIndex(&entry(), Slot_Block); + return SlotIndex(listEntry(), Slot_Block); } /// Returns the boundary index for associated with this index. The boundary /// index is the one associated with the Slot_Block slot for the instruction /// pointed to by this index. SlotIndex getBoundaryIndex() const { - return SlotIndex(&entry(), Slot_Dead); + return SlotIndex(listEntry(), Slot_Dead); } /// Returns the register use/def slot in the current instruction for a /// normal or early-clobber def. SlotIndex getRegSlot(bool EC = false) const { - return SlotIndex(&entry(), EC ? Slot_EarlyClobber : Slot_Register); + return SlotIndex(listEntry(), EC ? Slot_EarlyClobber : Slot_Register); } /// Returns the dead def kill slot for the current instruction. SlotIndex getDeadSlot() const { - return SlotIndex(&entry(), Slot_Dead); + return SlotIndex(listEntry(), Slot_Dead); } /// Returns the next slot in the index list. This could be either the @@ -266,15 +260,15 @@ namespace llvm { SlotIndex getNextSlot() const { Slot s = getSlot(); if (s == Slot_Dead) { - return SlotIndex(entry().getNext(), Slot_Block); + return SlotIndex(listEntry()->getNextNode(), Slot_Block); } - return SlotIndex(&entry(), s + 1); + return SlotIndex(listEntry(), 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()); + return SlotIndex(listEntry()->getNextNode(), getSlot()); } /// Returns the previous slot in the index list. This could be either the @@ -286,15 +280,15 @@ namespace llvm { SlotIndex getPrevSlot() const { Slot s = getSlot(); if (s == Slot_Block) { - return SlotIndex(entry().getPrev(), Slot_Dead); + return SlotIndex(listEntry()->getPrevNode(), Slot_Dead); } - return SlotIndex(&entry(), s - 1); + return SlotIndex(listEntry(), 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()); + return SlotIndex(listEntry()->getPrevNode(), getSlot()); } }; @@ -315,7 +309,7 @@ namespace llvm { return (LHS == RHS); } }; - + template <> struct isPodLike<SlotIndex> { static const bool value = true; }; @@ -346,8 +340,10 @@ namespace llvm { class SlotIndexes : public MachineFunctionPass { private: + typedef ilist<IndexListEntry> IndexList; + IndexList indexList; + MachineFunction *mf; - IndexListEntry *indexListHead; unsigned functionSize; typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; @@ -374,84 +370,18 @@ namespace llvm { 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); - } - - /// Renumber locally after inserting newEntry. - void renumberIndexes(IndexListEntry *newEntry); + /// Renumber locally after inserting curItr. + void renumberIndexes(IndexList::iterator curItr); public: static char ID; - SlotIndexes() : MachineFunctionPass(ID), indexListHead(0) { + SlotIndexes() : MachineFunctionPass(ID) { initializeSlotIndexesPass(*PassRegistry::getPassRegistry()); } virtual void getAnalysisUsage(AnalysisUsage &au) const; - virtual void releaseMemory(); + virtual void releaseMemory(); virtual bool runOnMachineFunction(MachineFunction &fn); @@ -463,22 +393,21 @@ namespace llvm { /// Returns the zero index for this analysis. SlotIndex getZeroIndex() { - assert(front()->getIndex() == 0 && "First index is not 0?"); - return SlotIndex(front(), 0); + assert(indexList.front().getIndex() == 0 && "First index is not 0?"); + return SlotIndex(&indexList.front(), 0); } /// Returns the base index of the last slot in this analysis. SlotIndex getLastIndex() { - return SlotIndex(back(), 0); + return SlotIndex(&indexList.back(), 0); } /// Returns the distance between the highest and lowest indexes allocated /// so far. unsigned getIndexesLength() const { - assert(front()->getIndex() == 0 && + assert(indexList.front().getIndex() == 0 && "Initial index isn't zero?"); - - return back()->getIndex(); + return indexList.back().getIndex(); } /// Returns the number of instructions in the function. @@ -503,19 +432,15 @@ namespace llvm { /// 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.isValid() ? index.entry().getInstr() : 0; + return index.isValid() ? index.listEntry()->getInstr() : 0; } /// 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; + IndexList::iterator itr(index.listEntry()); + ++itr; + while (itr != indexList.end() && itr->getInstr() == 0) { ++itr; } + return SlotIndex(itr, index.getSlot()); } /// getIndexBefore - Returns the index of the last indexed instruction @@ -659,31 +584,31 @@ namespace llvm { assert(mi->getParent() != 0 && "Instr must be added to function."); // Get the entries where mi should be inserted. - IndexListEntry *prevEntry, *nextEntry; + IndexList::iterator prevItr, nextItr; if (Late) { // Insert mi's index immediately before the following instruction. - nextEntry = &getIndexAfter(mi).entry(); - prevEntry = nextEntry->getPrev(); + nextItr = getIndexAfter(mi).listEntry(); + prevItr = prior(nextItr); } else { // Insert mi's index immediately after the preceeding instruction. - prevEntry = &getIndexBefore(mi).entry(); - nextEntry = prevEntry->getNext(); + prevItr = getIndexBefore(mi).listEntry(); + nextItr = llvm::next(prevItr); } // Get a number for the new instr, or 0 if there's no room currently. // In the latter case we'll force a renumber later. - unsigned dist = ((nextEntry->getIndex() - prevEntry->getIndex())/2) & ~3u; - unsigned newNumber = prevEntry->getIndex() + dist; + unsigned dist = ((nextItr->getIndex() - prevItr->getIndex())/2) & ~3u; + unsigned newNumber = prevItr->getIndex() + dist; // Insert a new list entry for mi. - IndexListEntry *newEntry = createEntry(mi, newNumber); - insert(nextEntry, newEntry); + IndexList::iterator newItr = + indexList.insert(nextItr, createEntry(mi, newNumber)); // Renumber locally if we need to. if (dist == 0) - renumberIndexes(newEntry); + renumberIndexes(newItr); - SlotIndex newIndex(newEntry, SlotIndex::Slot_Block); + SlotIndex newIndex(&*newItr, SlotIndex::Slot_Block); mi2iMap.insert(std::make_pair(mi, newIndex)); return newIndex; } @@ -694,7 +619,7 @@ namespace llvm { // MachineInstr -> index mappings Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi); if (mi2iItr != mi2iMap.end()) { - IndexListEntry *miEntry(&mi2iItr->second.entry()); + IndexListEntry *miEntry(mi2iItr->second.listEntry()); assert(miEntry->getInstr() == mi && "Instruction indexes broken."); // FIXME: Eventually we want to actually delete these indexes. miEntry->setInstr(0); @@ -709,7 +634,7 @@ namespace llvm { if (mi2iItr == mi2iMap.end()) return; SlotIndex replaceBaseIndex = mi2iItr->second; - IndexListEntry *miEntry(&replaceBaseIndex.entry()); + IndexListEntry *miEntry(replaceBaseIndex.listEntry()); assert(miEntry->getInstr() == mi && "Mismatched instruction in index tables."); miEntry->setInstr(newMI); @@ -726,13 +651,13 @@ namespace llvm { IndexListEntry *nextEntry = 0; if (nextMBB == mbb->getParent()->end()) { - nextEntry = getTail(); + nextEntry = indexList.end(); } else { - nextEntry = &getMBBStartIdx(nextMBB).entry(); + nextEntry = getMBBStartIdx(nextMBB).listEntry(); } - insert(nextEntry, startEntry); - insert(nextEntry, stopEntry); + indexList.insert(nextEntry, startEntry); + indexList.insert(nextEntry, stopEntry); SlotIndex startIdx(startEntry, SlotIndex::Slot_Block); SlotIndex endIdx(nextEntry, SlotIndex::Slot_Block); @@ -766,4 +691,4 @@ namespace llvm { } -#endif // LLVM_CODEGEN_LIVEINDEX_H +#endif // LLVM_CODEGEN_SLOTINDEXES_H diff --git a/contrib/llvm/include/llvm/IntrinsicsX86.td b/contrib/llvm/include/llvm/IntrinsicsX86.td index a6fda4a..cb7b3ea 100644 --- a/contrib/llvm/include/llvm/IntrinsicsX86.td +++ b/contrib/llvm/include/llvm/IntrinsicsX86.td @@ -1091,20 +1091,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_vperm2f128_si256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx_vpermil_pd : - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vpermil_ps : - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx_vpermil_pd_256 : - Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vpermil_ps_256 : - Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, - llvm_i8_ty], [IntrNoMem]>; } // Vector blend @@ -1659,15 +1645,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_permd : GCCBuiltin<"__builtin_ia32_permvarsi256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; - def int_x86_avx2_permq : GCCBuiltin<"__builtin_ia32_permdi256">, - Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i8_ty], - [IntrNoMem]>; def int_x86_avx2_permps : GCCBuiltin<"__builtin_ia32_permvarsf256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; - def int_x86_avx2_permpd : GCCBuiltin<"__builtin_ia32_permdf256">, - Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i8_ty], - [IntrNoMem]>; def int_x86_avx2_vperm2i128 : GCCBuiltin<"__builtin_ia32_permti256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; diff --git a/contrib/llvm/include/llvm/LLVMContext.h b/contrib/llvm/include/llvm/LLVMContext.h index 18adcd1..a8306a9 100644 --- a/contrib/llvm/include/llvm/LLVMContext.h +++ b/contrib/llvm/include/llvm/LLVMContext.h @@ -42,7 +42,7 @@ public: MD_dbg = 0, // "dbg" MD_tbaa = 1, // "tbaa" MD_prof = 2, // "prof" - MD_fpaccuracy = 3, // "fpaccuracy" + MD_fpmath = 3, // "fpmath" MD_range = 4 // "range" }; diff --git a/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h b/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h index dcecfb6..9a8735f 100644 --- a/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h +++ b/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h @@ -16,14 +16,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCParser/MCAsmLexer.h" -#include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/DataTypes.h" #include <string> -#include <cassert> namespace llvm { class MemoryBuffer; -class SMLoc; class MCAsmInfo; /// AsmLexer - Lexer class for assembly files. diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h index ac04483..5e29ad4 100644 --- a/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h @@ -15,8 +15,6 @@ #include "llvm/Support/SMLoc.h" namespace llvm { -class MCAsmLexer; -class MCInst; /// AsmToken - Target independent representation for an assembler token. class AsmToken { @@ -53,6 +51,7 @@ public: Greater, GreaterEqual, GreaterGreater, At }; +private: TokenKind Kind; /// A reference to the entire token contents; this is always a pointer into diff --git a/contrib/llvm/include/llvm/Object/ELF.h b/contrib/llvm/include/llvm/Object/ELF.h index 0828985..e493f5b 100644 --- a/contrib/llvm/include/llvm/Object/ELF.h +++ b/contrib/llvm/include/llvm/Object/ELF.h @@ -33,6 +33,15 @@ namespace llvm { namespace object { +// Subclasses of ELFObjectFile may need this for template instantiation +inline std::pair<unsigned char, unsigned char> +getElfArchType(MemoryBuffer *Object) { + if (Object->getBufferSize() < ELF::EI_NIDENT) + return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE); + return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS] + , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]); +} + // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. template<support::endianness target_endianness> struct ELFDataTypeTypedefHelperCommon { diff --git a/contrib/llvm/include/llvm/Operator.h b/contrib/llvm/include/llvm/Operator.h index abd6a19..1e86980 100644 --- a/contrib/llvm/include/llvm/Operator.h +++ b/contrib/llvm/include/llvm/Operator.h @@ -15,8 +15,9 @@ #ifndef LLVM_OPERATOR_H #define LLVM_OPERATOR_H -#include "llvm/Instruction.h" #include "llvm/Constants.h" +#include "llvm/Instruction.h" +#include "llvm/Type.h" namespace llvm { @@ -129,14 +130,15 @@ public: IsExact = (1 << 0) }; +private: + ~PossiblyExactOperator(); // do not implement + friend class BinaryOperator; friend class ConstantExpr; void setIsExact(bool B) { SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); } -private: - ~PossiblyExactOperator(); // do not implement public: /// isExact - Test whether this division is known to be exact, with /// zero remainder. @@ -161,7 +163,28 @@ public: (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } }; - + +/// FPMathOperator - Utility class for floating point operations which can have +/// information about relaxed accuracy requirements attached to them. +class FPMathOperator : public Operator { +private: + ~FPMathOperator(); // do not implement + +public: + + /// \brief Get the maximum error permitted by this operation in ULPs. An + /// accuracy of 0.0 means that the operation should be performed with the + /// default precision. + float getFPAccuracy() const; + + static inline bool classof(const FPMathOperator *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getType()->isFPOrFPVectorTy(); + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; /// ConcreteOperator - A helper template for defining operators for individual diff --git a/contrib/llvm/include/llvm/Support/IRBuilder.h b/contrib/llvm/include/llvm/Support/IRBuilder.h index 7828001..ef00e8e 100644 --- a/contrib/llvm/include/llvm/Support/IRBuilder.h +++ b/contrib/llvm/include/llvm/Support/IRBuilder.h @@ -17,6 +17,7 @@ #include "llvm/Instructions.h" #include "llvm/BasicBlock.h" +#include "llvm/LLVMContext.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" @@ -331,49 +332,63 @@ template<bool preserveNames = true, typename T = ConstantFolder, typename Inserter = IRBuilderDefaultInserter<preserveNames> > class IRBuilder : public IRBuilderBase, public Inserter { T Folder; + MDNode *DefaultFPMathTag; public: - IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter()) - : IRBuilderBase(C), Inserter(I), Folder(F) { + IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(), + MDNode *FPMathTag = 0) + : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) { } - explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder() { + explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase(C), + Folder(), DefaultFPMathTag(FPMathTag) { } - explicit IRBuilder(BasicBlock *TheBB, const T &F) - : IRBuilderBase(TheBB->getContext()), Folder(F) { + explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0) + : IRBuilderBase(TheBB->getContext()), Folder(F), + DefaultFPMathTag(FPMathTag) { SetInsertPoint(TheBB); } - explicit IRBuilder(BasicBlock *TheBB) - : IRBuilderBase(TheBB->getContext()), Folder() { + explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0) + : IRBuilderBase(TheBB->getContext()), Folder(), + DefaultFPMathTag(FPMathTag) { SetInsertPoint(TheBB); } - explicit IRBuilder(Instruction *IP) - : IRBuilderBase(IP->getContext()), Folder() { + explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0) + : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag) { SetInsertPoint(IP); SetCurrentDebugLocation(IP->getDebugLoc()); } - explicit IRBuilder(Use &U) - : IRBuilderBase(U->getContext()), Folder() { + explicit IRBuilder(Use &U, MDNode *FPMathTag = 0) + : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) { SetInsertPoint(U); SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc()); } - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) - : IRBuilderBase(TheBB->getContext()), Folder(F) { + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F, + MDNode *FPMathTag = 0) + : IRBuilderBase(TheBB->getContext()), Folder(F), + DefaultFPMathTag(FPMathTag) { SetInsertPoint(TheBB, IP); } - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) - : IRBuilderBase(TheBB->getContext()), Folder() { + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0) + : IRBuilderBase(TheBB->getContext()), Folder(), + DefaultFPMathTag(FPMathTag) { SetInsertPoint(TheBB, IP); } /// getFolder - Get the constant folder being used. const T &getFolder() { return Folder; } + /// getDefaultFPMathTag - Get the floating point math metadata being used. + MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } + + /// SetDefaultFPMathTag - Set the floating point math metadata to be used. + void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; } + /// isNamePreserving - Return true if this builder is configured to actually /// add the requested names to IR created through it. bool isNamePreserving() const { return preserveNames; } @@ -496,6 +511,14 @@ private: if (HasNSW) BO->setHasNoSignedWrap(); return BO; } + + Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const { + if (!FPMathTag) + FPMathTag = DefaultFPMathTag; + if (FPMathTag) + I->setMetadata(LLVMContext::MD_fpmath, FPMathTag); + return I; + } public: Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -511,11 +534,13 @@ public: Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateAdd(LHS, RHS, Name, true, false); } - Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFAdd(LC, RC), Name); - return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFAdd(LHS, RHS), + FPMathTag), Name); } Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -531,11 +556,13 @@ public: Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateSub(LHS, RHS, Name, true, false); } - Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFSub(LC, RC), Name); - return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFSub(LHS, RHS), + FPMathTag), Name); } Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -551,11 +578,13 @@ public: Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateMul(LHS, RHS, Name, true, false); } - Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFMul(LC, RC), Name); - return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFMul(LHS, RHS), + FPMathTag), Name); } Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", bool isExact = false) { @@ -581,11 +610,13 @@ public: Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateSDiv(LHS, RHS, Name, true); } - Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFDiv(LC, RC), Name); - return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFDiv(LHS, RHS), + FPMathTag), Name); } Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) @@ -599,11 +630,13 @@ public: return Insert(Folder.CreateSRem(LC, RC), Name); return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name); } - Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFRem(LC, RC), Name); - return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFRem(LHS, RHS), + FPMathTag), Name); } Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", @@ -729,10 +762,10 @@ public: Value *CreateNUWNeg(Value *V, const Twine &Name = "") { return CreateNeg(V, Name, true, false); } - Value *CreateFNeg(Value *V, const Twine &Name = "") { + Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0) { if (Constant *VC = dyn_cast<Constant>(V)) return Insert(Folder.CreateFNeg(VC), Name); - return Insert(BinaryOperator::CreateFNeg(V), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFNeg(V), FPMathTag), Name); } Value *CreateNot(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) diff --git a/contrib/llvm/include/llvm/Support/JSONParser.h b/contrib/llvm/include/llvm/Support/JSONParser.h deleted file mode 100644 index 11149f1..0000000 --- a/contrib/llvm/include/llvm/Support/JSONParser.h +++ /dev/null @@ -1,448 +0,0 @@ -//===--- JSONParser.h - Simple JSON parser ----------------------*- 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 a JSON parser. -// -// See http://www.json.org/ for an overview. -// See http://www.ietf.org/rfc/rfc4627.txt for the full standard. -// -// FIXME: Currently this supports a subset of JSON. Specifically, support -// for numbers, booleans and null for values is missing. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_JSON_PARSER_H -#define LLVM_SUPPORT_JSON_PARSER_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/SourceMgr.h" - -namespace llvm { - -class JSONContainer; -class JSONString; -class JSONValue; -class JSONKeyValuePair; - -/// \brief Base class for a parsable JSON atom. -/// -/// This class has no semantics other than being a unit of JSON data which can -/// be parsed out of a JSON document. -class JSONAtom { -public: - /// \brief Possible types of JSON objects. - enum Kind { JK_KeyValuePair, JK_Array, JK_Object, JK_String }; - - /// \brief Returns the type of this value. - Kind getKind() const { return MyKind; } - - static bool classof(const JSONAtom *Atom) { return true; } - -protected: - JSONAtom(Kind MyKind) : MyKind(MyKind) {} - -private: - Kind MyKind; -}; - -/// \brief A parser for JSON text. -/// -/// Use an object of JSONParser to iterate over the values of a JSON text. -/// All objects are parsed during the iteration, so you can only iterate once -/// over the JSON text, but the cost of partial iteration is minimized. -/// Create a new JSONParser if you want to iterate multiple times. -class JSONParser { -public: - /// \brief Create a JSONParser for the given input. - /// - /// Parsing is started via parseRoot(). Access to the object returned from - /// parseRoot() will parse the input lazily. - JSONParser(StringRef Input, SourceMgr *SM); - - /// \brief Returns the outermost JSON value (either an array or an object). - /// - /// Can return NULL if the input does not start with an array or an object. - /// The object is not parsed yet - the caller must iterate over the - /// returned object to trigger parsing. - /// - /// A JSONValue can be either a JSONString, JSONObject or JSONArray. - JSONValue *parseRoot(); - - /// \brief Parses the JSON text and returns whether it is valid JSON. - /// - /// In case validate() return false, failed() will return true and - /// getErrorMessage() will return the parsing error. - bool validate(); - - /// \brief Returns true if an error occurs during parsing. - /// - /// If there was an error while parsing an object that was created by - /// iterating over the result of 'parseRoot', 'failed' will return true. - bool failed() const; - -private: - /// \brief These methods manage the implementation details of parsing new JSON - /// atoms. - /// @{ - JSONString *parseString(); - JSONValue *parseValue(); - JSONKeyValuePair *parseKeyValuePair(); - /// @} - - /// \brief Helpers to parse the elements out of both forms of containers. - /// @{ - const JSONAtom *parseElement(JSONAtom::Kind ContainerKind); - StringRef::iterator parseFirstElement(JSONAtom::Kind ContainerKind, - char StartChar, char EndChar, - const JSONAtom *&Element); - StringRef::iterator parseNextElement(JSONAtom::Kind ContainerKind, - char EndChar, - const JSONAtom *&Element); - /// @} - - /// \brief Whitespace parsing. - /// @{ - void nextNonWhitespace(); - bool isWhitespace(); - /// @} - - /// \brief These methods are used for error handling. - /// { - void setExpectedError(StringRef Expected, StringRef Found); - void setExpectedError(StringRef Expected, char Found); - bool errorIfAtEndOfFile(StringRef Message); - bool errorIfNotAt(char C, StringRef Message); - /// } - - /// \brief Skips all elements in the given container. - bool skipContainer(const JSONContainer &Container); - - /// \brief Skips to the next position behind the given JSON atom. - bool skip(const JSONAtom &Atom); - - /// All nodes are allocated by the parser and will be deallocated when the - /// parser is destroyed. - BumpPtrAllocator ValueAllocator; - - /// \brief The original input to the parser. - MemoryBuffer *InputBuffer; - - /// \brief The source manager used for diagnostics and buffer management. - SourceMgr *SM; - - /// \brief The current position in the parse stream. - StringRef::iterator Position; - - /// \brief The end position for fast EOF checks without introducing - /// unnecessary dereferences. - StringRef::iterator End; - - /// \brief If true, an error has occurred. - bool Failed; - - friend class JSONContainer; -}; - - -/// \brief Base class for JSON value objects. -/// -/// This object represents an abstract JSON value. It is the root node behind -/// the group of JSON entities that can represent top-level values in a JSON -/// document. It has no API, and is just a placeholder in the type hierarchy of -/// nodes. -class JSONValue : public JSONAtom { -protected: - JSONValue(Kind MyKind) : JSONAtom(MyKind) {} - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - switch (Atom->getKind()) { - case JK_Array: - case JK_Object: - case JK_String: - return true; - case JK_KeyValuePair: - return false; - } - llvm_unreachable("Invalid JSONAtom kind"); - } - static bool classof(const JSONValue *Value) { return true; } - ///@} -}; - -/// \brief Gives access to the text of a JSON string. -/// -/// FIXME: Implement a method to return the unescaped text. -class JSONString : public JSONValue { -public: - /// \brief Returns the underlying parsed text of the string. - /// - /// This is the unescaped content of the JSON text. - /// See http://www.ietf.org/rfc/rfc4627.txt for details. - StringRef getRawText() const { return RawText; } - -private: - JSONString(StringRef RawText) : JSONValue(JK_String), RawText(RawText) {} - - StringRef RawText; - - friend class JSONParser; - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - return Atom->getKind() == JK_String; - } - static bool classof(const JSONString *String) { return true; } - ///@} -}; - -/// \brief A (key, value) tuple of type (JSONString *, JSONValue *). -/// -/// Note that JSONKeyValuePair is not a JSONValue, it is a bare JSONAtom. -/// JSONKeyValuePairs can be elements of a JSONObject, but not of a JSONArray. -/// They are not viable as top-level values either. -class JSONKeyValuePair : public JSONAtom { -public: - const JSONString * const Key; - const JSONValue * const Value; - -private: - JSONKeyValuePair(const JSONString *Key, const JSONValue *Value) - : JSONAtom(JK_KeyValuePair), Key(Key), Value(Value) {} - - friend class JSONParser; - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - return Atom->getKind() == JK_KeyValuePair; - } - static bool classof(const JSONKeyValuePair *KeyValuePair) { return true; } - ///@} -}; - -/// \brief Implementation of JSON containers (arrays and objects). -/// -/// JSONContainers drive the lazy parsing of JSON arrays and objects via -/// forward iterators. -class JSONContainer : public JSONValue { -private: - /// \brief An iterator that parses the underlying container during iteration. - /// - /// Iterators on the same collection use shared state, so when multiple copies - /// of an iterator exist, only one is allowed to be used for iteration; - /// iterating multiple copies of an iterator of the same collection will lead - /// to undefined behavior. - class AtomIterator { - public: - AtomIterator(const AtomIterator &I) : Container(I.Container) {} - - /// \brief Iterator interface. - ///@{ - bool operator==(const AtomIterator &I) const { - if (isEnd() || I.isEnd()) - return isEnd() == I.isEnd(); - return Container->Position == I.Container->Position; - } - bool operator!=(const AtomIterator &I) const { - return !(*this == I); - } - AtomIterator &operator++() { - Container->parseNextElement(); - return *this; - } - const JSONAtom *operator*() { - return Container->Current; - } - ///@} - - private: - /// \brief Create an iterator for which 'isEnd' returns true. - AtomIterator() : Container(0) {} - - /// \brief Create an iterator for the given container. - AtomIterator(const JSONContainer *Container) : Container(Container) {} - - bool isEnd() const { - return Container == 0 || Container->Position == StringRef::iterator(); - } - - const JSONContainer * const Container; - - friend class JSONContainer; - }; - -protected: - /// \brief An iterator for the specified AtomT. - /// - /// Used for the implementation of iterators for JSONArray and JSONObject. - template <typename AtomT> - class IteratorTemplate : public std::iterator<std::forward_iterator_tag, - const AtomT*> { - public: - explicit IteratorTemplate(const AtomIterator& AtomI) - : AtomI(AtomI) {} - - bool operator==(const IteratorTemplate &I) const { - return AtomI == I.AtomI; - } - bool operator!=(const IteratorTemplate &I) const { return !(*this == I); } - - IteratorTemplate &operator++() { - ++AtomI; - return *this; - } - - const AtomT *operator*() { return dyn_cast<AtomT>(*AtomI); } - - private: - AtomIterator AtomI; - }; - - JSONContainer(JSONParser *Parser, char StartChar, char EndChar, - JSONAtom::Kind ContainerKind) - : JSONValue(ContainerKind), Parser(Parser), - Position(), Current(0), Started(false), - StartChar(StartChar), EndChar(EndChar) {} - - /// \brief Returns a lazy parsing iterator over the container. - /// - /// As the iterator drives the parse stream, begin() must only be called - /// once per container. - AtomIterator atom_begin() const { - if (Started) - report_fatal_error("Cannot parse container twice."); - Started = true; - // Set up the position and current element when we begin iterating over the - // container. - Position = Parser->parseFirstElement(getKind(), StartChar, EndChar, Current); - return AtomIterator(this); - } - AtomIterator atom_end() const { - return AtomIterator(); - } - -private: - AtomIterator atom_current() const { - if (!Started) - return atom_begin(); - - return AtomIterator(this); - } - - /// \brief Parse the next element in the container into the Current element. - /// - /// This routine is called as an iterator into this container walks through - /// its elements. It mutates the container's internal current node to point to - /// the next atom of the container. - void parseNextElement() const { - Parser->skip(*Current); - Position = Parser->parseNextElement(getKind(), EndChar, Current); - } - - // For parsing, JSONContainers call back into the JSONParser. - JSONParser * const Parser; - - // 'Position', 'Current' and 'Started' store the state of the parse stream - // for iterators on the container, they don't change the container's elements - // and are thus marked as mutable. - mutable StringRef::iterator Position; - mutable const JSONAtom *Current; - mutable bool Started; - - const char StartChar; - const char EndChar; - - friend class JSONParser; - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - switch (Atom->getKind()) { - case JK_Array: - case JK_Object: - return true; - case JK_KeyValuePair: - case JK_String: - return false; - } - llvm_unreachable("Invalid JSONAtom kind"); - } - static bool classof(const JSONContainer *Container) { return true; } - ///@} -}; - -/// \brief A simple JSON array. -class JSONArray : public JSONContainer { -public: - typedef IteratorTemplate<JSONValue> const_iterator; - - /// \brief Returns a lazy parsing iterator over the container. - /// - /// As the iterator drives the parse stream, begin() must only be called - /// once per container. - const_iterator begin() const { return const_iterator(atom_begin()); } - const_iterator end() const { return const_iterator(atom_end()); } - -private: - JSONArray(JSONParser *Parser) - : JSONContainer(Parser, '[', ']', JSONAtom::JK_Array) {} - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - return Atom->getKind() == JSONAtom::JK_Array; - } - static bool classof(const JSONArray *Array) { return true; } - ///@} - - friend class JSONParser; -}; - -/// \brief A JSON object: an iterable list of JSON key-value pairs. -class JSONObject : public JSONContainer { -public: - typedef IteratorTemplate<JSONKeyValuePair> const_iterator; - - /// \brief Returns a lazy parsing iterator over the container. - /// - /// As the iterator drives the parse stream, begin() must only be called - /// once per container. - const_iterator begin() const { return const_iterator(atom_begin()); } - const_iterator end() const { return const_iterator(atom_end()); } - -private: - JSONObject(JSONParser *Parser) - : JSONContainer(Parser, '{', '}', JSONAtom::JK_Object) {} - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - return Atom->getKind() == JSONAtom::JK_Object; - } - static bool classof(const JSONObject *Object) { return true; } - ///@} - - friend class JSONParser; -}; - -} // end namespace llvm - -#endif // LLVM_SUPPORT_JSON_PARSER_H diff --git a/contrib/llvm/include/llvm/Support/Locale.h b/contrib/llvm/include/llvm/Support/Locale.h new file mode 100644 index 0000000..b0f1295 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/Locale.h @@ -0,0 +1,17 @@ +#ifndef LLVM_SUPPORT_LOCALE +#define LLVM_SUPPORT_LOCALE + +#include "llvm/ADT/StringRef.h" + +namespace llvm { +namespace sys { +namespace locale { + +int columnWidth(StringRef s); +bool isPrint(int c); + +} +} +} + +#endif // LLVM_SUPPORT_LOCALE diff --git a/contrib/llvm/include/llvm/Support/MDBuilder.h b/contrib/llvm/include/llvm/Support/MDBuilder.h new file mode 100644 index 0000000..40f028a --- /dev/null +++ b/contrib/llvm/include/llvm/Support/MDBuilder.h @@ -0,0 +1,118 @@ +//===---- llvm/Support/MDBuilder.h - Builder for LLVM metadata --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MDBuilder class, which is used as a convenient way to +// create LLVM metadata with a consistent and simplified interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_MDBUILDER_H +#define LLVM_SUPPORT_MDBUILDER_H + +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" +#include "llvm/Metadata.h" +#include "llvm/ADT/APInt.h" + +namespace llvm { + + class MDBuilder { + LLVMContext &Context; + + public: + MDBuilder(LLVMContext &context) : Context(context) {} + + /// \brief Return the given string as metadata. + MDString *createString(StringRef Str) { + return MDString::get(Context, Str); + } + + //===------------------------------------------------------------------===// + // FPMath metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata with the given settings. The special value 0.0 + /// for the Accuracy parameter indicates the default (maximal precision) + /// setting. + MDNode *createFPMath(float Accuracy) { + if (Accuracy == 0.0) + return 0; + assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); + Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); + return MDNode::get(Context, Op); + } + + + //===------------------------------------------------------------------===// + // Range metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata describing the range [Lo, Hi). + MDNode *createRange(const APInt &Lo, const APInt &Hi) { + assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!"); + // If the range is everything then it is useless. + if (Hi == Lo) + return 0; + + // Return the range [Lo, Hi). + Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); + Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) }; + return MDNode::get(Context, Range); + } + + + //===------------------------------------------------------------------===// + // TBAA metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata appropriate for a TBAA root node. Each returned + /// node is distinct from all other metadata and will never be identified + /// (uniqued) with anything else. + MDNode *createAnonymousTBAARoot() { + // To ensure uniqueness the root node is self-referential. + MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>()); + MDNode *Root = MDNode::get(Context, Dummy); + // At this point we have + // !0 = metadata !{} <- dummy + // !1 = metadata !{metadata !0} <- root + // Replace the dummy operand with the root node itself and delete the dummy. + Root->replaceOperandWith(0, Root); + MDNode::deleteTemporary(Dummy); + // We now have + // !1 = metadata !{metadata !1} <- self-referential root + return Root; + } + + /// \brief Return metadata appropriate for a TBAA root node with the given + /// name. This may be identified (uniqued) with other roots with the same + /// name. + MDNode *createTBAARoot(StringRef Name) { + return MDNode::get(Context, createString(Name)); + } + + /// \brief Return metadata for a non-root TBAA node with the given name, + /// parent in the TBAA tree, and value for 'pointsToConstantMemory'. + MDNode *createTBAANode(StringRef Name, MDNode *Parent, + bool isConstant = false) { + if (isConstant) { + Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); + Value *Ops[3] = { createString(Name), Parent, Flags }; + return MDNode::get(Context, Ops); + } else { + Value *Ops[2] = { createString(Name), Parent }; + return MDNode::get(Context, Ops); + } + } + + }; + +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Support/Process.h b/contrib/llvm/include/llvm/Support/Process.h index 3379922..d796b79 100644 --- a/contrib/llvm/include/llvm/Support/Process.h +++ b/contrib/llvm/include/llvm/Support/Process.h @@ -136,6 +136,10 @@ namespace sys { /// Same as OutputColor, but only enables the bold attribute. static const char *OutputBold(bool bg); + /// This function returns the escape sequence to reverse forground and + /// background colors. + static const char *OutputReverse(); + /// Resets the terminals colors, or returns an escape sequence to do so. static const char *ResetColor(); /// @} diff --git a/contrib/llvm/include/llvm/Support/SourceMgr.h b/contrib/llvm/include/llvm/Support/SourceMgr.h index 58b8fab..76967db 100644 --- a/contrib/llvm/include/llvm/Support/SourceMgr.h +++ b/contrib/llvm/include/llvm/Support/SourceMgr.h @@ -128,8 +128,11 @@ public: /// PrintMessage - Emit a message about the specified location with the /// specified string. /// + /// @param ShowColors - Display colored messages if output is a terminal and + /// the default error handler is used. void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, - ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const; + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(), + bool ShowColors = true) const; /// GetMessage - Return an SMDiagnostic at the specified location with the @@ -188,7 +191,7 @@ public: const std::vector<std::pair<unsigned, unsigned> > &getRanges() const { return Ranges; } - void print(const char *ProgName, raw_ostream &S) const; + void print(const char *ProgName, raw_ostream &S, bool ShowColors = true) const; }; } // end llvm namespace diff --git a/contrib/llvm/include/llvm/Support/YAMLParser.h b/contrib/llvm/include/llvm/Support/YAMLParser.h index b24cacd..47206b3 100644 --- a/contrib/llvm/include/llvm/Support/YAMLParser.h +++ b/contrib/llvm/include/llvm/Support/YAMLParser.h @@ -516,8 +516,11 @@ public: document_iterator() : Doc(NullDoc) {} document_iterator(OwningPtr<Document> &D) : Doc(D) {} + bool operator ==(const document_iterator &Other) { + return Doc == Other.Doc; + } bool operator !=(const document_iterator &Other) { - return Doc != Other.Doc; + return !(*this == Other); } document_iterator operator ++() { diff --git a/contrib/llvm/include/llvm/Support/raw_ostream.h b/contrib/llvm/include/llvm/Support/raw_ostream.h index 6bfae5e..6c5d478 100644 --- a/contrib/llvm/include/llvm/Support/raw_ostream.h +++ b/contrib/llvm/include/llvm/Support/raw_ostream.h @@ -222,6 +222,9 @@ public: /// outputting colored text, or before program exit. virtual raw_ostream &resetColor() { return *this; } + /// Reverses the forground and background colors. + virtual raw_ostream &reverseColor() { return *this; } + /// This function determines if this stream is connected to a "tty" or /// "console" window. That is, the output would be displayed to the user /// rather than being put on a pipe or stored in a file. @@ -379,6 +382,8 @@ public: bool bg=false); virtual raw_ostream &resetColor(); + virtual raw_ostream &reverseColor(); + virtual bool is_displayed() const; /// has_error - Return the value of the flag in this raw_fd_ostream indicating diff --git a/contrib/llvm/include/llvm/TableGen/Error.h b/contrib/llvm/include/llvm/TableGen/Error.h index c01b32b..fd5f805 100644 --- a/contrib/llvm/include/llvm/TableGen/Error.h +++ b/contrib/llvm/include/llvm/TableGen/Error.h @@ -29,6 +29,11 @@ public: const std::string &getMessage() const { return Message; } }; +void PrintWarning(SMLoc WarningLoc, const Twine &Msg); +void PrintWarning(const char *Loc, const Twine &Msg); +void PrintWarning(const Twine &Msg); +void PrintWarning(const TGError &Warning); + void PrintError(SMLoc ErrorLoc, const Twine &Msg); void PrintError(const char *Loc, const Twine &Msg); void PrintError(const Twine &Msg); diff --git a/contrib/llvm/include/llvm/TableGen/Record.h b/contrib/llvm/include/llvm/TableGen/Record.h index 5e68c10..3aea1ae 100644 --- a/contrib/llvm/include/llvm/TableGen/Record.h +++ b/contrib/llvm/include/llvm/TableGen/Record.h @@ -454,7 +454,7 @@ public: /// without adding quote markers. This primaruly affects /// StringInits where we will not surround the string value with /// quotes. - virtual std::string getAsUnquotedString() const { return getAsString(); } + virtual std::string getAsUnquotedString() const { return getAsString(); } /// dump - Debugging method that may be called through a debugger, just /// invokes print on stderr. @@ -1529,7 +1529,7 @@ struct MultiClass { void dump() const; - MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) : + MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) : Rec(Name, Loc, Records) {} }; diff --git a/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h b/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h index 70e26bf..c8cacf2 100644 --- a/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h +++ b/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h @@ -83,7 +83,7 @@ namespace llvm { /// long double expm1l(long double x); expm1l, /// float expm1f(float x); - expl1f, + expm1f, /// double fabs(double x); fabs, /// long double fabsl(long double x); @@ -159,8 +159,14 @@ namespace llvm { rint, /// float rintf(float x); rintf, - /// long dobule rintl(long double x); + /// long double rintl(long double x); rintl, + /// double round(double x); + round, + /// float roundf(float x); + roundf, + /// long double roundl(long double x); + roundl, /// double sin(double x); sin, /// long double sinl(long double x); diff --git a/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h b/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h index 7d8a46b..6ddd364 100644 --- a/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h +++ b/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h @@ -205,7 +205,7 @@ struct TargetRegisterInfoDesc { /// Each TargetRegisterClass has a per register weight, and weight /// limit which must be less than the limits of its pressure sets. struct RegClassWeight { - unsigned RegWeigt; + unsigned RegWeight; unsigned WeightLimit; }; diff --git a/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h index 867b9e4..2f9dc54 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -110,7 +110,8 @@ bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum, /// BasicBlock *SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P = 0, bool MergeIdenticalEdges = false, - bool DontDeleteUselessPHIs = false); + bool DontDeleteUselessPHIs = false, + bool SplitLandingPads = false); inline BasicBlock *SplitCriticalEdge(BasicBlock *BB, succ_iterator SI, Pass *P = 0) { diff --git a/contrib/llvm/include/llvm/Transforms/Vectorize.h b/contrib/llvm/include/llvm/Transforms/Vectorize.h index 7701ceb..652916c 100644 --- a/contrib/llvm/include/llvm/Transforms/Vectorize.h +++ b/contrib/llvm/include/llvm/Transforms/Vectorize.h @@ -34,6 +34,9 @@ struct VectorizeConfig { /// @brief Vectorize floating-point values. bool VectorizeFloats; + /// @brief Vectorize pointer values. + bool VectorizePointers; + /// @brief Vectorize casting (conversion) operations. bool VectorizeCasts; @@ -43,6 +46,12 @@ struct VectorizeConfig { /// @brief Vectorize the fused-multiply-add intrinsic. bool VectorizeFMA; + /// @brief Vectorize select instructions. + bool VectorizeSelect; + + /// @brief Vectorize getelementptr instructions. + bool VectorizeGEP; + /// @brief Vectorize loads and stores. bool VectorizeMemOps; diff --git a/contrib/llvm/lib/Analysis/ConstantFolding.cpp b/contrib/llvm/lib/Analysis/ConstantFolding.cpp index 7a0a4e1e..783c32e 100644 --- a/contrib/llvm/lib/Analysis/ConstantFolding.cpp +++ b/contrib/llvm/lib/Analysis/ConstantFolding.cpp @@ -681,6 +681,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops, // This makes it easy to determine if the getelementptr is "inbounds". // Also, this helps GlobalOpt do SROA on GlobalVariables. Type *Ty = Ptr->getType(); + assert(Ty->isPointerTy() && "Forming regular GEP of non-pointer type"); SmallVector<Constant*, 32> NewIdxs; do { if (SequentialType *ATy = dyn_cast<SequentialType>(Ty)) { @@ -711,10 +712,17 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops, } Ty = ATy->getElementType(); } else if (StructType *STy = dyn_cast<StructType>(Ty)) { - // Determine which field of the struct the offset points into. The - // getZExtValue is at least as safe as the StructLayout API because we - // know the offset is within the struct at this point. + // If we end up with an offset that isn't valid for this struct type, we + // can't re-form this GEP in a regular form, so bail out. The pointer + // operand likely went through casts that are necessary to make the GEP + // sensible. const StructLayout &SL = *TD->getStructLayout(STy); + if (Offset.uge(SL.getSizeInBytes())) + break; + + // Determine which field of the struct the offset points into. The + // getZExtValue is fine as we've already ensured that the offset is + // within the range representable by the StructLayout API. unsigned ElIdx = SL.getElementContainingOffset(Offset.getZExtValue()); NewIdxs.push_back(ConstantInt::get(Type::getInt32Ty(Ty->getContext()), ElIdx)); diff --git a/contrib/llvm/lib/Analysis/ScalarEvolution.cpp b/contrib/llvm/lib/Analysis/ScalarEvolution.cpp index 1d55642..205227c 100644 --- a/contrib/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/contrib/llvm/lib/Analysis/ScalarEvolution.cpp @@ -3187,7 +3187,7 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) { // Add the total offset from all the GEP indices to the base. return getAddExpr(BaseS, TotalOffset, - isInBounds ? SCEV::FlagNUW : SCEV::FlagAnyWrap); + isInBounds ? SCEV::FlagNSW : SCEV::FlagAnyWrap); } /// GetMinTrailingZeros - Determine the minimum number of zero bits that S is diff --git a/contrib/llvm/lib/Analysis/ValueTracking.cpp b/contrib/llvm/lib/Analysis/ValueTracking.cpp index a430f62..1418e01 100644 --- a/contrib/llvm/lib/Analysis/ValueTracking.cpp +++ b/contrib/llvm/lib/Analysis/ValueTracking.cpp @@ -564,7 +564,7 @@ void llvm::ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne, Depth+1); // If it's known zero, our sign bit is also zero. if (LHSKnownZero.isNegative()) - KnownZero |= LHSKnownZero; + KnownZero.setBit(BitWidth - 1); } break; diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp index 660684d..454a923 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp @@ -36,35 +36,20 @@ const char *DwarfAccelTable::Atom::AtomTypeString(enum AtomType AT) { llvm_unreachable("invalid AtomType!"); } -// The general case would need to have a less hard coded size for the -// length of the HeaderData, however, if we're constructing based on a -// single Atom then we know it will always be: 4 + 4 + 2 + 2. -DwarfAccelTable::DwarfAccelTable(DwarfAccelTable::Atom atom) : - Header(12), - HeaderData(atom) { -} - // The length of the header data is always going to be 4 + 4 + 4*NumAtoms. -DwarfAccelTable::DwarfAccelTable(std::vector<DwarfAccelTable::Atom> &atomList) : +DwarfAccelTable::DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom> atomList) : Header(8 + (atomList.size() * 4)), - HeaderData(atomList) { -} + HeaderData(atomList), + Entries(Allocator) { } -DwarfAccelTable::~DwarfAccelTable() { - for (size_t i = 0, e = Data.size(); i < e; ++i) - delete Data[i]; - for (StringMap<DataArray>::iterator - EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) - for (DataArray::iterator DI = EI->second.begin(), - DE = EI->second.end(); DI != DE; ++DI) - delete (*DI); -} +DwarfAccelTable::~DwarfAccelTable() { } void DwarfAccelTable::AddName(StringRef Name, DIE* die, char Flags) { + assert(Data.empty() && "Already finalized!"); // If the string is in the list already then add this die to the list // otherwise add a new one. DataArray &DIEs = Entries[Name]; - DIEs.push_back(new HashDataContents(die, Flags)); + DIEs.push_back(new (Allocator) HashDataContents(die, Flags)); } void DwarfAccelTable::ComputeBucketCount(void) { @@ -85,31 +70,23 @@ void DwarfAccelTable::ComputeBucketCount(void) { Header.hashes_count = num; } -namespace { - // DIESorter - comparison predicate that sorts DIEs by their offset. - struct DIESorter { - bool operator()(const struct DwarfAccelTable::HashDataContents *A, - const struct DwarfAccelTable::HashDataContents *B) const { - return A->Die->getOffset() < B->Die->getOffset(); - } - }; +// compareDIEs - comparison predicate that sorts DIEs by their offset. +static bool compareDIEs(const DwarfAccelTable::HashDataContents *A, + const DwarfAccelTable::HashDataContents *B) { + return A->Die->getOffset() < B->Die->getOffset(); } void DwarfAccelTable::FinalizeTable(AsmPrinter *Asm, const char *Prefix) { // Create the individual hash data outputs. for (StringMap<DataArray>::iterator EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { - struct HashData *Entry = new HashData((*EI).getKeyData()); // Unique the entries. - std::stable_sort(EI->second.begin(), EI->second.end(), DIESorter()); + std::stable_sort(EI->second.begin(), EI->second.end(), compareDIEs); EI->second.erase(std::unique(EI->second.begin(), EI->second.end()), EI->second.end()); - for (DataArray::const_iterator DI = EI->second.begin(), - DE = EI->second.end(); - DI != DE; ++DI) - Entry->addData((*DI)); + HashData *Entry = new (Allocator) HashData(EI->getKey(), EI->second); Data.push_back(Entry); } @@ -216,7 +193,7 @@ void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D) { D->getStringPool()); Asm->OutStreamer.AddComment("Num DIEs"); Asm->EmitInt32((*HI)->Data.size()); - for (std::vector<struct HashDataContents*>::const_iterator + for (ArrayRef<HashDataContents*>::const_iterator DI = (*HI)->Data.begin(), DE = (*HI)->Data.end(); DI != DE; ++DI) { // Emit the DIE offset diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h index 2278d4c..963b8cd 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h @@ -15,6 +15,7 @@ #define CODEGEN_ASMPRINTER_DWARFACCELTABLE_H__ #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/DataTypes.h" @@ -164,22 +165,12 @@ public: private: struct TableHeaderData { - uint32_t die_offset_base; - std::vector<Atom> Atoms; + SmallVector<Atom, 1> Atoms; + + TableHeaderData(ArrayRef<Atom> AtomList, uint32_t offset = 0) + : die_offset_base(offset), Atoms(AtomList.begin(), AtomList.end()) { } - TableHeaderData(std::vector<DwarfAccelTable::Atom> &AtomList, - uint32_t offset = 0) : - die_offset_base(offset) { - for (size_t i = 0, e = AtomList.size(); i != e; ++i) - Atoms.push_back(AtomList[i]); - } - - TableHeaderData(DwarfAccelTable::Atom Atom, uint32_t offset = 0) - : die_offset_base(offset) { - Atoms.push_back(Atom); - } - #ifndef NDEBUG void print (raw_ostream &O) { O << "die_offset_base: " << die_offset_base << "\n"; @@ -221,11 +212,11 @@ private: StringRef Str; uint32_t HashValue; MCSymbol *Sym; - std::vector<struct HashDataContents*> Data; // offsets - HashData(StringRef S) : Str(S) { + ArrayRef<HashDataContents*> Data; // offsets + HashData(StringRef S, ArrayRef<HashDataContents*> Data) + : Str(S), Data(Data) { HashValue = DwarfAccelTable::HashDJB(S); } - void addData(struct HashDataContents *Datum) { Data.push_back(Datum); } #ifndef NDEBUG void print(raw_ostream &O) { O << "Name: " << Str << "\n"; @@ -255,15 +246,18 @@ private: void EmitHashes(AsmPrinter *); void EmitOffsets(AsmPrinter *, MCSymbol *); void EmitData(AsmPrinter *, DwarfDebug *D); - + + // Allocator for HashData and HashDataContents. + BumpPtrAllocator Allocator; + // Output Variables TableHeader Header; TableHeaderData HeaderData; std::vector<HashData*> Data; // String Data - typedef std::vector<struct HashDataContents*> DataArray; - typedef StringMap<DataArray> StringEntries; + typedef std::vector<HashDataContents*> DataArray; + typedef StringMap<DataArray, BumpPtrAllocator&> StringEntries; StringEntries Entries; // Buckets/Hashes/Offsets @@ -274,8 +268,7 @@ private: // Public Implementation public: - DwarfAccelTable(DwarfAccelTable::Atom); - DwarfAccelTable(std::vector<DwarfAccelTable::Atom> &); + DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom>); ~DwarfAccelTable(); void AddName(StringRef, DIE*, char = 0); void FinalizeTable(AsmPrinter *, const char *); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 69dc454..cc5b642 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1032,9 +1032,10 @@ DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) { // Add function template parameters. addTemplateParams(*SPDie, SP.getTemplateParams()); - // Unfortunately this code needs to stay here to work around - // a bug in older gdbs that requires the linkage name to resolve - // multiple template functions. + // Unfortunately this code needs to stay here instead of below the + // AT_specification code in order to work around a bug in older + // gdbs that requires the linkage name to resolve multiple template + // functions. StringRef LinkageName = SP.getLinkageName(); if (!LinkageName.empty()) addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, diff --git a/contrib/llvm/lib/CodeGen/DFAPacketizer.cpp b/contrib/llvm/lib/CodeGen/DFAPacketizer.cpp index bfbe779..5ff641c 100644 --- a/contrib/llvm/lib/CodeGen/DFAPacketizer.cpp +++ b/contrib/llvm/lib/CodeGen/DFAPacketizer.cpp @@ -23,10 +23,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/ScheduleDAGInstrs.h" #include "llvm/CodeGen/DFAPacketizer.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBundle.h" +#include "llvm/CodeGen/ScheduleDAGInstrs.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/MC/MCInstrItineraries.h" using namespace llvm; @@ -100,17 +100,17 @@ void DFAPacketizer::reserveResources(llvm::MachineInstr *MI) { reserveResources(&MID); } -namespace llvm { +namespace { // DefaultVLIWScheduler - This class extends ScheduleDAGInstrs and overrides // Schedule method to build the dependence graph. class DefaultVLIWScheduler : public ScheduleDAGInstrs { public: DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI, - MachineDominatorTree &MDT, bool IsPostRA); + MachineDominatorTree &MDT, bool IsPostRA); // Schedule - Actual scheduling work. void schedule(); }; -} +} // end anonymous namespace DefaultVLIWScheduler::DefaultVLIWScheduler( MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, @@ -129,25 +129,49 @@ VLIWPacketizerList::VLIWPacketizerList( bool IsPostRA) : TM(MF.getTarget()), MF(MF) { TII = TM.getInstrInfo(); ResourceTracker = TII->CreateTargetScheduleState(&TM, 0); - VLIWScheduler = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA); + SchedulerImpl = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA); } // VLIWPacketizerList Dtor VLIWPacketizerList::~VLIWPacketizerList() { - if (VLIWScheduler) - delete VLIWScheduler; + delete SchedulerImpl; + delete ResourceTracker; +} + +// ignorePseudoInstruction - ignore pseudo instructions. +bool VLIWPacketizerList::ignorePseudoInstruction(MachineInstr *MI, + MachineBasicBlock *MBB) { + if (MI->isDebugValue()) + return true; + + if (TII->isSchedulingBoundary(MI, MBB, MF)) + return true; + + return false; +} + +// isSoloInstruction - return true if instruction I must end previous +// packet. +bool VLIWPacketizerList::isSoloInstruction(MachineInstr *I) { + if (I->isInlineAsm()) + return true; + + return false; +} - if (ResourceTracker) - delete ResourceTracker; +// addToPacket - Add I to the current packet and reserve resource. +void VLIWPacketizerList::addToPacket(MachineInstr *MI) { + CurrentPacketMIs.push_back(MI); + ResourceTracker->reserveResources(MI); } // endPacket - End the current packet, bundle packet instructions and reset // DFA state. void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB, - MachineInstr *MI) { + MachineInstr *I) { if (CurrentPacketMIs.size() > 1) { MachineInstr *MIFirst = CurrentPacketMIs.front(); - finalizeBundle(*MBB, MIFirst, MI); + finalizeBundle(*MBB, MIFirst, I); } CurrentPacketMIs.clear(); ResourceTracker->clearResources(); @@ -157,36 +181,31 @@ void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB, void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB, MachineBasicBlock::iterator BeginItr, MachineBasicBlock::iterator EndItr) { - assert(VLIWScheduler && "VLIW Scheduler is not initialized!"); - VLIWScheduler->enterRegion(MBB, BeginItr, EndItr, MBB->size()); - VLIWScheduler->schedule(); - VLIWScheduler->exitRegion(); - - // Generate MI -> SU map. - //std::map <MachineInstr*, SUnit*> MIToSUnit; - MIToSUnit.clear(); - for (unsigned i = 0, e = VLIWScheduler->SUnits.size(); i != e; ++i) { - SUnit *SU = &VLIWScheduler->SUnits[i]; - MIToSUnit[SU->getInstr()] = SU; - } + assert(MBB->end() == EndItr && "Bad EndIndex"); + + SchedulerImpl->enterRegion(MBB, BeginItr, EndItr, MBB->size()); + + // Build the DAG without reordering instructions. + SchedulerImpl->schedule(); + + // Remember scheduling units. + SUnits = SchedulerImpl->SUnits; // The main packetizer loop. for (; BeginItr != EndItr; ++BeginItr) { MachineInstr *MI = BeginItr; - this->initPacketizerState(); + // Ignore pseudo instructions. + if (ignorePseudoInstruction(MI, MBB)) + continue; // End the current packet if needed. - if (this->isSoloInstruction(MI)) { + if (isSoloInstruction(MI)) { endPacket(MBB, MI); continue; } - // Ignore pseudo instructions. - if (this->ignorePseudoInstruction(MI, MBB)) - continue; - - SUnit *SUI = MIToSUnit[MI]; + SUnit *SUI = SchedulerImpl->getSUnit(MI); assert(SUI && "Missing SUnit Info!"); // Ask DFA if machine resource is available for MI. @@ -196,13 +215,13 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB, for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(), VE = CurrentPacketMIs.end(); VI != VE; ++VI) { MachineInstr *MJ = *VI; - SUnit *SUJ = MIToSUnit[MJ]; + SUnit *SUJ = SchedulerImpl->getSUnit(MJ); assert(SUJ && "Missing SUnit Info!"); // Is it legal to packetize SUI and SUJ together. - if (!this->isLegalToPacketizeTogether(SUI, SUJ)) { + if (!isLegalToPacketizeTogether(SUI, SUJ)) { // Allow packetization if dependency can be pruned. - if (!this->isLegalToPruneDependencies(SUI, SUJ)) { + if (!isLegalToPruneDependencies(SUI, SUJ)) { // End the packet if dependency cannot be pruned. endPacket(MBB, MI); break; @@ -215,9 +234,11 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB, } // Add MI to the current packet. - BeginItr = this->addToPacket(MI); + addToPacket(MI); } // For all instructions in BB. // End any packet left behind. endPacket(MBB, EndItr); + + SchedulerImpl->exitRegion(); } diff --git a/contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index 3ade660..934cc12 100644 --- a/contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1068,9 +1068,9 @@ public: #ifndef NDEBUG LIValidator validator; - std::for_each(Entering.begin(), Entering.end(), validator); - std::for_each(Internal.begin(), Internal.end(), validator); - std::for_each(Exiting.begin(), Exiting.end(), validator); + validator = std::for_each(Entering.begin(), Entering.end(), validator); + validator = std::for_each(Internal.begin(), Internal.end(), validator); + validator = std::for_each(Exiting.begin(), Exiting.end(), validator); assert(validator.rangesOk() && "moveAllOperandsFrom broke liveness."); #endif @@ -1115,9 +1115,9 @@ public: #ifndef NDEBUG LIValidator validator; - std::for_each(Entering.begin(), Entering.end(), validator); - std::for_each(Internal.begin(), Internal.end(), validator); - std::for_each(Exiting.begin(), Exiting.end(), validator); + validator = std::for_each(Entering.begin(), Entering.end(), validator); + validator = std::for_each(Internal.begin(), Internal.end(), validator); + validator = std::for_each(Exiting.begin(), Exiting.end(), validator); assert(validator.rangesOk() && "moveAllOperandsInto broke liveness."); #endif } diff --git a/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp b/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp index 6c8a107..1abb8f2 100644 --- a/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -392,22 +392,44 @@ void MachineBasicBlock::updateTerminator() { TII->InsertBranch(*this, TBB, 0, Cond, dl); } } else { + // Walk through the successors and find the successor which is not + // a landing pad and is not the conditional branch destination (in TBB) + // as the fallthrough successor. + MachineBasicBlock *FallthroughBB = 0; + for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) { + if ((*SI)->isLandingPad() || *SI == TBB) + continue; + assert(!FallthroughBB && "Found more than one fallthrough successor."); + FallthroughBB = *SI; + } + if (!FallthroughBB && canFallThrough()) { + // We fallthrough to the same basic block as the conditional jump + // targets. Remove the conditional jump, leaving unconditional + // fallthrough. + // FIXME: This does not seem like a reasonable pattern to support, but it + // has been seen in the wild coming out of degenerate ARM test cases. + TII->RemoveBranch(*this); + + // Finally update the unconditional successor to be reached via a branch + // if it would not be reached by fallthrough. + if (!isLayoutSuccessor(TBB)) + TII->InsertBranch(*this, TBB, 0, Cond, dl); + return; + } + // The block has a fallthrough conditional branch. - MachineBasicBlock *MBBA = *succ_begin(); - MachineBasicBlock *MBBB = *llvm::next(succ_begin()); - if (MBBA == TBB) std::swap(MBBB, MBBA); if (isLayoutSuccessor(TBB)) { if (TII->ReverseBranchCondition(Cond)) { // We can't reverse the condition, add an unconditional branch. Cond.clear(); - TII->InsertBranch(*this, MBBA, 0, Cond, dl); + TII->InsertBranch(*this, FallthroughBB, 0, Cond, dl); return; } TII->RemoveBranch(*this); - TII->InsertBranch(*this, MBBA, 0, Cond, dl); - } else if (!isLayoutSuccessor(MBBA)) { + TII->InsertBranch(*this, FallthroughBB, 0, Cond, dl); + } else if (!isLayoutSuccessor(FallthroughBB)) { TII->RemoveBranch(*this); - TII->InsertBranch(*this, TBB, MBBA, Cond, dl); + TII->InsertBranch(*this, TBB, FallthroughBB, Cond, dl); } } } diff --git a/contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp index 22d7212..5ba6851 100644 --- a/contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp +++ b/contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp @@ -102,13 +102,13 @@ public: } /// \brief Iterator over blocks within the chain. - typedef SmallVectorImpl<MachineBasicBlock *>::const_iterator iterator; + typedef SmallVectorImpl<MachineBasicBlock *>::iterator iterator; /// \brief Beginning of blocks within the chain. - iterator begin() const { return Blocks.begin(); } + iterator begin() { return Blocks.begin(); } /// \brief End of blocks within the chain. - iterator end() const { return Blocks.end(); } + iterator end() { return Blocks.end(); } /// \brief Merge a block chain into this one. /// @@ -211,12 +211,15 @@ class MachineBlockPlacement : public MachineFunctionPass { void buildChain(MachineBasicBlock *BB, BlockChain &Chain, SmallVectorImpl<MachineBasicBlock *> &BlockWorkList, const BlockFilterSet *BlockFilter = 0); - MachineBasicBlock *findBestLoopTop(MachineFunction &F, - MachineLoop &L, + MachineBasicBlock *findBestLoopTop(MachineLoop &L, const BlockFilterSet &LoopBlockSet); + MachineBasicBlock *findBestLoopExit(MachineFunction &F, + MachineLoop &L, + const BlockFilterSet &LoopBlockSet); void buildLoopChains(MachineFunction &F, MachineLoop &L); + void rotateLoop(BlockChain &LoopChain, MachineBasicBlock *ExitingBB, + const BlockFilterSet &LoopBlockSet); void buildCFGChains(MachineFunction &F); - void AlignLoops(MachineFunction &F); public: static char ID; // Pass identification, replacement for typeid @@ -540,13 +543,74 @@ void MachineBlockPlacement::buildChain( /// \brief Find the best loop top block for layout. /// +/// Look for a block which is strictly better than the loop header for laying +/// out at the top of the loop. This looks for one and only one pattern: +/// a latch block with no conditional exit. This block will cause a conditional +/// jump around it or will be the bottom of the loop if we lay it out in place, +/// but if it it doesn't end up at the bottom of the loop for any reason, +/// rotation alone won't fix it. Because such a block will always result in an +/// unconditional jump (for the backedge) rotating it in front of the loop +/// header is always profitable. +MachineBasicBlock * +MachineBlockPlacement::findBestLoopTop(MachineLoop &L, + const BlockFilterSet &LoopBlockSet) { + // Check that the header hasn't been fused with a preheader block due to + // crazy branches. If it has, we need to start with the header at the top to + // prevent pulling the preheader into the loop body. + BlockChain &HeaderChain = *BlockToChain[L.getHeader()]; + if (!LoopBlockSet.count(*HeaderChain.begin())) + return L.getHeader(); + + DEBUG(dbgs() << "Finding best loop top for: " + << getBlockName(L.getHeader()) << "\n"); + + BlockFrequency BestPredFreq; + MachineBasicBlock *BestPred = 0; + for (MachineBasicBlock::pred_iterator PI = L.getHeader()->pred_begin(), + PE = L.getHeader()->pred_end(); + PI != PE; ++PI) { + MachineBasicBlock *Pred = *PI; + if (!LoopBlockSet.count(Pred)) + continue; + DEBUG(dbgs() << " header pred: " << getBlockName(Pred) << ", " + << Pred->succ_size() << " successors, " + << MBFI->getBlockFreq(Pred) << " freq\n"); + if (Pred->succ_size() > 1) + continue; + + BlockFrequency PredFreq = MBFI->getBlockFreq(Pred); + if (!BestPred || PredFreq > BestPredFreq || + (!(PredFreq < BestPredFreq) && + Pred->isLayoutSuccessor(L.getHeader()))) { + BestPred = Pred; + BestPredFreq = PredFreq; + } + } + + // If no direct predecessor is fine, just use the loop header. + if (!BestPred) + return L.getHeader(); + + // Walk backwards through any straight line of predecessors. + while (BestPred->pred_size() == 1 && + (*BestPred->pred_begin())->succ_size() == 1 && + *BestPred->pred_begin() != L.getHeader()) + BestPred = *BestPred->pred_begin(); + + DEBUG(dbgs() << " final top: " << getBlockName(BestPred) << "\n"); + return BestPred; +} + + +/// \brief Find the best loop exiting block for layout. +/// /// This routine implements the logic to analyze the loop looking for the best /// block to layout at the top of the loop. Typically this is done to maximize /// fallthrough opportunities. MachineBasicBlock * -MachineBlockPlacement::findBestLoopTop(MachineFunction &F, - MachineLoop &L, - const BlockFilterSet &LoopBlockSet) { +MachineBlockPlacement::findBestLoopExit(MachineFunction &F, + MachineLoop &L, + const BlockFilterSet &LoopBlockSet) { // We don't want to layout the loop linearly in all cases. If the loop header // is just a normal basic block in the loop, we want to look for what block // within the loop is the best one to layout at the top. However, if the loop @@ -557,11 +621,11 @@ MachineBlockPlacement::findBestLoopTop(MachineFunction &F, // header and only rotate if safe. BlockChain &HeaderChain = *BlockToChain[L.getHeader()]; if (!LoopBlockSet.count(*HeaderChain.begin())) - return L.getHeader(); + return 0; BlockFrequency BestExitEdgeFreq; + unsigned BestExitLoopDepth = 0; MachineBasicBlock *ExitingBB = 0; - MachineBasicBlock *LoopingBB = 0; // If there are exits to outer loops, loop rotation can severely limit // fallthrough opportunites unless it selects such an exit. Keep a set of // blocks where rotating to exit with that block will reach an outer loop. @@ -584,15 +648,10 @@ MachineBlockPlacement::findBestLoopTop(MachineFunction &F, // successor isn't found. MachineBasicBlock *OldExitingBB = ExitingBB; BlockFrequency OldBestExitEdgeFreq = BestExitEdgeFreq; - // We also compute and store the best looping successor for use in layout. - MachineBasicBlock *BestLoopSucc = 0; + bool HasLoopingSucc = false; // FIXME: Due to the performance of the probability and weight routines in - // the MBPI analysis, we use the internal weights. This is only valid - // because it is purely a ranking function, we don't care about anything - // but the relative values. - uint32_t BestLoopSuccWeight = 0; - // FIXME: We also manually compute the probabilities to avoid quadratic - // behavior. + // the MBPI analysis, we use the internal weights and manually compute the + // probabilities to avoid quadratic behavior. uint32_t WeightScale = 0; uint32_t SumWeight = MBPI->getSumForBlock(*I, WeightScale); for (MachineBasicBlock::succ_iterator SI = (*I)->succ_begin(), @@ -604,10 +663,8 @@ MachineBlockPlacement::findBestLoopTop(MachineFunction &F, continue; BlockChain &SuccChain = *BlockToChain[*SI]; // Don't split chains, either this chain or the successor's chain. - if (&Chain == &SuccChain || *SI != *SuccChain.begin()) { - DEBUG(dbgs() << " " << (LoopBlockSet.count(*SI) ? "looping: " - : "exiting: ") - << getBlockName(*I) << " -> " + if (&Chain == &SuccChain) { + DEBUG(dbgs() << " exiting: " << getBlockName(*I) << " -> " << getBlockName(*SI) << " (chain conflict)\n"); continue; } @@ -616,60 +673,103 @@ MachineBlockPlacement::findBestLoopTop(MachineFunction &F, if (LoopBlockSet.count(*SI)) { DEBUG(dbgs() << " looping: " << getBlockName(*I) << " -> " << getBlockName(*SI) << " (" << SuccWeight << ")\n"); - if (BestLoopSucc && BestLoopSuccWeight >= SuccWeight) - continue; - - BestLoopSucc = *SI; - BestLoopSuccWeight = SuccWeight; + HasLoopingSucc = true; continue; } + unsigned SuccLoopDepth = 0; + if (MachineLoop *ExitLoop = MLI->getLoopFor(*SI)) { + SuccLoopDepth = ExitLoop->getLoopDepth(); + if (ExitLoop->contains(&L)) + BlocksExitingToOuterLoop.insert(*I); + } + BranchProbability SuccProb(SuccWeight / WeightScale, SumWeight); BlockFrequency ExitEdgeFreq = MBFI->getBlockFreq(*I) * SuccProb; DEBUG(dbgs() << " exiting: " << getBlockName(*I) << " -> " - << getBlockName(*SI) << " (" << ExitEdgeFreq << ")\n"); + << getBlockName(*SI) << " [L:" << SuccLoopDepth + << "] (" << ExitEdgeFreq << ")\n"); // Note that we slightly bias this toward an existing layout successor to // retain incoming order in the absence of better information. // FIXME: Should we bias this more strongly? It's pretty weak. - if (!ExitingBB || ExitEdgeFreq > BestExitEdgeFreq || + if (!ExitingBB || BestExitLoopDepth < SuccLoopDepth || + ExitEdgeFreq > BestExitEdgeFreq || ((*I)->isLayoutSuccessor(*SI) && !(ExitEdgeFreq < BestExitEdgeFreq))) { BestExitEdgeFreq = ExitEdgeFreq; ExitingBB = *I; } - - if (MachineLoop *ExitLoop = MLI->getLoopFor(*SI)) - if (ExitLoop->contains(&L)) - BlocksExitingToOuterLoop.insert(*I); } // Restore the old exiting state, no viable looping successor was found. - if (!BestLoopSucc) { + if (!HasLoopingSucc) { ExitingBB = OldExitingBB; BestExitEdgeFreq = OldBestExitEdgeFreq; continue; } - - // If this was best exiting block thus far, also record the looping block. - if (ExitingBB == *I) - LoopingBB = BestLoopSucc; } - // Without a candidate exitting block or with only a single block in the + // Without a candidate exiting block or with only a single block in the // loop, just use the loop header to layout the loop. if (!ExitingBB || L.getNumBlocks() == 1) - return L.getHeader(); + return 0; // Also, if we have exit blocks which lead to outer loops but didn't select // one of them as the exiting block we are rotating toward, disable loop // rotation altogether. if (!BlocksExitingToOuterLoop.empty() && !BlocksExitingToOuterLoop.count(ExitingBB)) - return L.getHeader(); + return 0; - assert(LoopingBB && "All successors of a loop block are exit blocks!"); DEBUG(dbgs() << " Best exiting block: " << getBlockName(ExitingBB) << "\n"); - DEBUG(dbgs() << " Best top block: " << getBlockName(LoopingBB) << "\n"); - return LoopingBB; + return ExitingBB; +} + +/// \brief Attempt to rotate an exiting block to the bottom of the loop. +/// +/// Once we have built a chain, try to rotate it to line up the hot exit block +/// with fallthrough out of the loop if doing so doesn't introduce unnecessary +/// branches. For example, if the loop has fallthrough into its header and out +/// of its bottom already, don't rotate it. +void MachineBlockPlacement::rotateLoop(BlockChain &LoopChain, + MachineBasicBlock *ExitingBB, + const BlockFilterSet &LoopBlockSet) { + if (!ExitingBB) + return; + + MachineBasicBlock *Top = *LoopChain.begin(); + bool ViableTopFallthrough = false; + for (MachineBasicBlock::pred_iterator PI = Top->pred_begin(), + PE = Top->pred_end(); + PI != PE; ++PI) { + BlockChain *PredChain = BlockToChain[*PI]; + if (!LoopBlockSet.count(*PI) && + (!PredChain || *PI == *llvm::prior(PredChain->end()))) { + ViableTopFallthrough = true; + break; + } + } + + // If the header has viable fallthrough, check whether the current loop + // bottom is a viable exiting block. If so, bail out as rotating will + // introduce an unnecessary branch. + if (ViableTopFallthrough) { + MachineBasicBlock *Bottom = *llvm::prior(LoopChain.end()); + for (MachineBasicBlock::succ_iterator SI = Bottom->succ_begin(), + SE = Bottom->succ_end(); + SI != SE; ++SI) { + BlockChain *SuccChain = BlockToChain[*SI]; + if (!LoopBlockSet.count(*SI) && + (!SuccChain || *SI == *SuccChain->begin())) + return; + } + } + + BlockChain::iterator ExitIt = std::find(LoopChain.begin(), LoopChain.end(), + ExitingBB); + if (ExitIt == LoopChain.end()) + return; + + std::rotate(LoopChain.begin(), llvm::next(ExitIt), LoopChain.end()); } /// \brief Forms basic block chains from the natural loop structures. @@ -688,8 +788,20 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F, SmallVector<MachineBasicBlock *, 16> BlockWorkList; BlockFilterSet LoopBlockSet(L.block_begin(), L.block_end()); - MachineBasicBlock *LayoutTop = findBestLoopTop(F, L, LoopBlockSet); - BlockChain &LoopChain = *BlockToChain[LayoutTop]; + // First check to see if there is an obviously preferable top block for the + // loop. This will default to the header, but may end up as one of the + // predecessors to the header if there is one which will result in strictly + // fewer branches in the loop body. + MachineBasicBlock *LoopTop = findBestLoopTop(L, LoopBlockSet); + + // If we selected just the header for the loop top, look for a potentially + // profitable exit block in the event that rotating the loop can eliminate + // branches by placing an exit edge at the bottom. + MachineBasicBlock *ExitingBB = 0; + if (LoopTop == L.getHeader()) + ExitingBB = findBestLoopExit(F, L, LoopBlockSet); + + BlockChain &LoopChain = *BlockToChain[LoopTop]; // FIXME: This is a really lame way of walking the chains in the loop: we // walk the blocks, and use a set to prevent visiting a particular chain @@ -721,7 +833,8 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F, BlockWorkList.push_back(*Chain.begin()); } - buildChain(LayoutTop, LoopChain, BlockWorkList, &LoopBlockSet); + buildChain(LoopTop, LoopChain, BlockWorkList, &LoopBlockSet); + rotateLoop(LoopChain, ExitingBB, LoopBlockSet); DEBUG({ // Crash at the end so we get all of the debugging output first. @@ -733,7 +846,8 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F, << " Chain header: " << getBlockName(*LoopChain.begin()) << "\n"; } for (BlockChain::iterator BCI = LoopChain.begin(), BCE = LoopChain.end(); - BCI != BCE; ++BCI) + BCI != BCE; ++BCI) { + dbgs() << " ... " << getBlockName(*BCI) << "\n"; if (!LoopBlockSet.erase(*BCI)) { // We don't mark the loop as bad here because there are real situations // where this can occur. For example, with an unanalyzable fallthrough @@ -743,6 +857,7 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F, << " Chain header: " << getBlockName(*LoopChain.begin()) << "\n" << " Bad block: " << getBlockName(*BCI) << "\n"; } + } if (!LoopBlockSet.empty()) { BadLoop = true; @@ -882,28 +997,33 @@ void MachineBlockPlacement::buildCFGChains(MachineFunction &F) { MachineBasicBlock *TBB = 0, *FBB = 0; // For AnalyzeBranch. if (!TII->AnalyzeBranch(F.back(), TBB, FBB, Cond)) F.back().updateTerminator(); -} -/// \brief Recursive helper to align a loop and any nested loops. -static void AlignLoop(MachineFunction &F, MachineLoop *L, unsigned Align) { - // Recurse through nested loops. - for (MachineLoop::iterator I = L->begin(), E = L->end(); I != E; ++I) - AlignLoop(F, *I, Align); - - L->getTopBlock()->setAlignment(Align); -} - -/// \brief Align loop headers to target preferred alignments. -void MachineBlockPlacement::AlignLoops(MachineFunction &F) { + // Walk through the backedges of the function now that we have fully laid out + // the basic blocks and align the destination of each backedge. We don't rely + // on the loop info here so that we can align backedges in unnatural CFGs and + // backedges that were introduced purely because of the loop rotations done + // during this layout pass. + // FIXME: This isn't quite right, we shouldn't align backedges that result + // from blocks being sunken below the exit block for the function. if (F.getFunction()->hasFnAttr(Attribute::OptimizeForSize)) return; - unsigned Align = TLI->getPrefLoopAlignment(); if (!Align) return; // Don't care about loop alignment. - for (MachineLoopInfo::iterator I = MLI->begin(), E = MLI->end(); I != E; ++I) - AlignLoop(F, *I, Align); + SmallPtrSet<MachineBasicBlock *, 16> PreviousBlocks; + for (BlockChain::iterator BI = FunctionChain.begin(), + BE = FunctionChain.end(); + BI != BE; ++BI) { + PreviousBlocks.insert(*BI); + // Set alignment on the destination of all the back edges in the new + // ordering. + for (MachineBasicBlock::succ_iterator SI = (*BI)->succ_begin(), + SE = (*BI)->succ_end(); + SI != SE; ++SI) + if (PreviousBlocks.count(*SI)) + (*SI)->setAlignment(Align); + } } bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &F) { @@ -919,7 +1039,6 @@ bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &F) { assert(BlockToChain.empty()); buildCFGChains(F); - AlignLoops(F); BlockToChain.clear(); ChainAllocator.DestroyAll(); diff --git a/contrib/llvm/lib/CodeGen/Passes.cpp b/contrib/llvm/lib/CodeGen/Passes.cpp index 53d1fcf..490547b 100644 --- a/contrib/llvm/lib/CodeGen/Passes.cpp +++ b/contrib/llvm/lib/CodeGen/Passes.cpp @@ -37,8 +37,9 @@ static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden, cl::desc("Disable tail duplication")); static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden, cl::desc("Disable pre-register allocation tail duplication")); -static cl::opt<bool> EnableBlockPlacement("enable-block-placement", - cl::Hidden, cl::desc("Enable probability-driven block placement")); +static cl::opt<bool> DisableBlockPlacement("disable-block-placement", + cl::Hidden, cl::desc("Disable the probability-driven block placement, and " + "re-enable the old code placement pass")); static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats", cl::Hidden, cl::desc("Collect probability-driven block placement stats")); static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden, @@ -206,7 +207,7 @@ TargetPassConfig::~TargetPassConfig() { // Out of line constructor provides default values for pass options and // registers all common codegen passes. TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm) - : ImmutablePass(ID), TM(tm), PM(pm), Impl(0), Initialized(false), + : ImmutablePass(ID), TM(tm), PM(&pm), Impl(0), Initialized(false), DisableVerify(false), EnableTailMerge(true) { @@ -233,7 +234,7 @@ TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) { } TargetPassConfig::TargetPassConfig() - : ImmutablePass(ID), PM(*(PassManagerBase*)0) { + : ImmutablePass(ID), PM(0) { llvm_unreachable("TargetPassConfig should not be constructed on-the-fly"); } @@ -268,16 +269,16 @@ AnalysisID TargetPassConfig::addPass(char &ID) { Pass *P = Pass::createPass(FinalID); if (!P) llvm_unreachable("Pass ID not registered"); - PM.add(P); + PM->add(P); return FinalID; } void TargetPassConfig::printAndVerify(const char *Banner) const { if (TM->shouldPrintMachineCode()) - PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); + PM->add(createMachineFunctionPrinterPass(dbgs(), Banner)); if (VerifyMachineCode) - PM.add(createMachineVerifierPass(Banner)); + PM->add(createMachineVerifierPass(Banner)); } /// Add common target configurable passes that perform LLVM IR to IR transforms @@ -287,46 +288,46 @@ void TargetPassConfig::addIRPasses() { // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that // BasicAliasAnalysis wins if they disagree. This is intended to help // support "obvious" type-punning idioms. - PM.add(createTypeBasedAliasAnalysisPass()); - PM.add(createBasicAliasAnalysisPass()); + PM->add(createTypeBasedAliasAnalysisPass()); + PM->add(createBasicAliasAnalysisPass()); // Before running any passes, run the verifier to determine if the input // coming from the front-end and/or optimizer is valid. if (!DisableVerify) - PM.add(createVerifierPass()); + PM->add(createVerifierPass()); // Run loop strength reduction before anything else. if (getOptLevel() != CodeGenOpt::None && !DisableLSR) { - PM.add(createLoopStrengthReducePass(getTargetLowering())); + PM->add(createLoopStrengthReducePass(getTargetLowering())); if (PrintLSR) - PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs())); + PM->add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs())); } - PM.add(createGCLoweringPass()); + PM->add(createGCLoweringPass()); // Make sure that no unreachable blocks are instruction selected. - PM.add(createUnreachableBlockEliminationPass()); + PM->add(createUnreachableBlockEliminationPass()); } /// Add common passes that perform LLVM IR to IR transforms in preparation for /// instruction selection. void TargetPassConfig::addISelPrepare() { if (getOptLevel() != CodeGenOpt::None && !DisableCGP) - PM.add(createCodeGenPreparePass(getTargetLowering())); + PM->add(createCodeGenPreparePass(getTargetLowering())); - PM.add(createStackProtectorPass(getTargetLowering())); + PM->add(createStackProtectorPass(getTargetLowering())); addPreISel(); if (PrintISelInput) - PM.add(createPrintFunctionPass("\n\n" - "*** Final LLVM Code input to ISel ***\n", - &dbgs())); + PM->add(createPrintFunctionPass("\n\n" + "*** Final LLVM Code input to ISel ***\n", + &dbgs())); // All passes which modify the LLVM IR are now complete; run the verifier // to ensure that the IR is valid. if (!DisableVerify) - PM.add(createVerifierPass()); + PM->add(createVerifierPass()); } /// Add the complete set of target-independent postISel code generator passes. @@ -404,7 +405,7 @@ void TargetPassConfig::addMachinePasses() { // GC addPass(GCMachineCodeAnalysisID); if (PrintGCInfo) - PM.add(createGCInfoPrinter(dbgs())); + PM->add(createGCInfoPrinter(dbgs())); // Basic block placement. if (getOptLevel() != CodeGenOpt::None) @@ -521,7 +522,7 @@ void TargetPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) { addPass(PHIEliminationID); addPass(TwoAddressInstructionPassID); - PM.add(RegAllocPass); + PM->add(RegAllocPass); printAndVerify("After Register Allocation"); } @@ -563,7 +564,7 @@ void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) { printAndVerify("After Machine Scheduling"); // Add the selected register allocation pass. - PM.add(RegAllocPass); + PM->add(RegAllocPass); printAndVerify("After Register Allocation"); // FinalizeRegAlloc is convenient until MachineInstrBundles is more mature, @@ -610,10 +611,10 @@ void TargetPassConfig::addMachineLateOptimization() { /// Add standard basic block placement passes. void TargetPassConfig::addBlockPlacement() { AnalysisID ID = &NoPassID; - if (EnableBlockPlacement) { - // MachineBlockPlacement is an experimental pass which is disabled by - // default currently. Eventually it should subsume CodePlacementOpt, so - // when enabled, the other is disabled. + if (!DisableBlockPlacement) { + // MachineBlockPlacement is a new pass which subsumes the functionality of + // CodPlacementOpt. The old code placement pass can be restored by + // disabling block placement, but eventually it will be removed. ID = addPass(MachineBlockPlacementID); } else { ID = addPass(CodePlacementOptID); diff --git a/contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp index 6be1ab7..d46eb89 100644 --- a/contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -39,8 +39,8 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf, LiveIntervals *lis) : ScheduleDAG(mf), MLI(mli), MDT(mdt), MFI(mf.getFrameInfo()), InstrItins(mf.getTarget().getInstrItineraryData()), LIS(lis), - IsPostRA(IsPostRAFlag), UnitLatencies(false), LoopRegs(MLI, MDT), - FirstDbgValue(0) { + IsPostRA(IsPostRAFlag), UnitLatencies(false), CanHandleTerminators(false), + LoopRegs(MLI, MDT), FirstDbgValue(0) { assert((IsPostRA || LIS) && "PreRA scheduling requires LiveIntervals"); DbgValues.clear(); assert(!(IsPostRA && MRI.getNumVirtRegs()) && @@ -554,7 +554,7 @@ void ScheduleDAGInstrs::buildSchedGraph(AliasAnalysis *AA) { continue; } - assert(!MI->isTerminator() && !MI->isLabel() && + assert((!MI->isTerminator() || CanHandleTerminators) && !MI->isLabel() && "Cannot schedule terminators or labels!"); SUnit *SU = MISUnitMap[MI]; diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d1b998f..0914c66 100644 --- a/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1080,6 +1080,7 @@ void DAGCombiner::Run(CombineLevel AtLevel) { // If the root changed (e.g. it was a dead load, update the root). DAG.setRoot(Dummy.getValue()); + DAG.RemoveDeadNodes(); } SDValue DAGCombiner::visit(SDNode *N) { diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index 3ae8345..9fe4480 100644 --- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -417,7 +417,8 @@ SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) { Op1 = DAG.getNode(ISD::AND, DL, VT, Op1, Mask); Op2 = DAG.getNode(ISD::AND, DL, VT, Op2, NotMask); - return DAG.getNode(ISD::OR, DL, VT, Op1, Op2); + SDValue Val = DAG.getNode(ISD::OR, DL, VT, Op1, Op2); + return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Val); } SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) { diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp index 69dd813..8ec1ae8 100644 --- a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -138,9 +138,11 @@ static void AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) { // Don't add glue from a node to itself. if (GlueDestNode == N) return; - // Don't add glue to something which already has glue. - if (N->getValueType(N->getNumValues() - 1) == MVT::Glue) return; - + // Don't add glue to something that already has it, either as a use or value. + if (N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue || + N->getValueType(N->getNumValues() - 1) == MVT::Glue) { + return; + } for (unsigned I = 0, E = N->getNumValues(); I != E; ++I) VTs.push_back(N->getValueType(I)); diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 94cb958..f1e879b 100644 --- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5050,7 +5050,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { } case Intrinsic::gcroot: if (GFI) { - const Value *Alloca = I.getArgOperand(0); + const Value *Alloca = I.getArgOperand(0)->stripPointerCasts(); const Constant *TypeMap = cast<Constant>(I.getArgOperand(1)); FrameIndexSDNode *FI = cast<FrameIndexSDNode>(getValue(Alloca).getNode()); diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 09a2b1f..e341e15 100644 --- a/contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1367,8 +1367,9 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, // bits on that side are also known to be set on the other side, turn this // into an AND, as we know the bits will be cleared. // e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2 - if ((NewMask & (KnownZero|KnownOne)) == NewMask) { // all known - if ((KnownOne & KnownOne2) == KnownOne) { + // NB: it is okay if more bits are known than are requested + if ((NewMask & (KnownZero|KnownOne)) == NewMask) { // all known on one side + if (KnownOne == KnownOne2) { // set bits are the same on both sides EVT VT = Op.getValueType(); SDValue ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, VT); return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, dl, VT, diff --git a/contrib/llvm/lib/CodeGen/SlotIndexes.cpp b/contrib/llvm/lib/CodeGen/SlotIndexes.cpp index c5bd3a3..26cf259 100644 --- a/contrib/llvm/lib/CodeGen/SlotIndexes.cpp +++ b/contrib/llvm/lib/CodeGen/SlotIndexes.cpp @@ -34,7 +34,8 @@ void SlotIndexes::releaseMemory() { mi2iMap.clear(); MBBRanges.clear(); idx2MBBMap.clear(); - clearList(); + indexList.clear(); + ileAllocator.Reset(); } bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { @@ -45,17 +46,15 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { // 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 + // 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(); // Check that the list contains only the sentinal. - assert(indexListHead->getNext() == 0 && - "Index list non-empty at initial numbering?"); + assert(indexList.empty() && "Index list non-empty at initial numbering?"); assert(idx2MBBMap.empty() && "Index -> MBB mapping non-empty at initial numbering?"); assert(MBBRanges.empty() && @@ -68,7 +67,7 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { MBBRanges.resize(mf->getNumBlockIDs()); idx2MBBMap.reserve(mf->size()); - push_back(createEntry(0, index)); + indexList.push_back(createEntry(0, index)); // Iterate over the function. for (MachineFunction::iterator mbbItr = mf->begin(), mbbEnd = mf->end(); @@ -76,7 +75,7 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { MachineBasicBlock *mbb = &*mbbItr; // Insert an index for the MBB start. - SlotIndex blockStartIndex(back(), SlotIndex::Slot_Block); + SlotIndex blockStartIndex(&indexList.back(), SlotIndex::Slot_Block); for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end(); miItr != miEnd; ++miItr) { @@ -85,20 +84,20 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { continue; // Insert a store index for the instr. - push_back(createEntry(mi, index += SlotIndex::InstrDist)); + indexList.push_back(createEntry(mi, index += SlotIndex::InstrDist)); // Save this base index in the maps. - mi2iMap.insert(std::make_pair(mi, SlotIndex(back(), + mi2iMap.insert(std::make_pair(mi, SlotIndex(&indexList.back(), SlotIndex::Slot_Block))); - + ++functionSize; } // We insert one blank instructions between basic blocks. - push_back(createEntry(0, index += SlotIndex::InstrDist)); + indexList.push_back(createEntry(0, index += SlotIndex::InstrDist)); MBBRanges[mbb->getNumber()].first = blockStartIndex; - MBBRanges[mbb->getNumber()].second = SlotIndex(back(), + MBBRanges[mbb->getNumber()].second = SlotIndex(&indexList.back(), SlotIndex::Slot_Block); idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, mbb)); } @@ -119,38 +118,37 @@ void SlotIndexes::renumberIndexes() { unsigned index = 0; - for (IndexListEntry *curEntry = front(); curEntry != getTail(); - curEntry = curEntry->getNext()) { - curEntry->setIndex(index); + for (IndexList::iterator I = indexList.begin(), E = indexList.end(); + I != E; ++I) { + I->setIndex(index); index += SlotIndex::InstrDist; } } -// Renumber indexes locally after curEntry was inserted, but failed to get a new +// Renumber indexes locally after curItr was inserted, but failed to get a new // index. -void SlotIndexes::renumberIndexes(IndexListEntry *curEntry) { +void SlotIndexes::renumberIndexes(IndexList::iterator curItr) { // Number indexes with half the default spacing so we can catch up quickly. const unsigned Space = SlotIndex::InstrDist/2; assert((Space & 3) == 0 && "InstrDist must be a multiple of 2*NUM"); - IndexListEntry *start = curEntry->getPrev(); - unsigned index = start->getIndex(); - IndexListEntry *tail = getTail(); + IndexList::iterator startItr = prior(curItr); + unsigned index = startItr->getIndex(); do { - curEntry->setIndex(index += Space); - curEntry = curEntry->getNext(); + curItr->setIndex(index += Space); + ++curItr; // If the next index is bigger, we have caught up. - } while (curEntry != tail && curEntry->getIndex() <= index); + } while (curItr != indexList.end() && curItr->getIndex() <= index); - DEBUG(dbgs() << "\n*** Renumbered SlotIndexes " << start->getIndex() << '-' + DEBUG(dbgs() << "\n*** Renumbered SlotIndexes " << startItr->getIndex() << '-' << index << " ***\n"); ++NumLocalRenum; } void SlotIndexes::dump() const { - for (const IndexListEntry *itr = front(); itr != getTail(); - itr = itr->getNext()) { + for (IndexList::const_iterator itr = indexList.begin(); + itr != indexList.end(); ++itr) { dbgs() << itr->getIndex() << " "; if (itr->getInstr() != 0) { @@ -168,7 +166,7 @@ void SlotIndexes::dump() const { // Print a SlotIndex to a raw_ostream. void SlotIndex::print(raw_ostream &os) const { if (isValid()) - os << entry().getIndex() << "Berd"[getSlot()]; + os << listEntry()->getIndex() << "Berd"[getSlot()]; else os << "invalid"; } diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp new file mode 100644 index 0000000..8b50101 --- /dev/null +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp @@ -0,0 +1,214 @@ +//===-- GDBRegistrar.cpp - Registers objects with GDB ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "JITRegistrar.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/MutexGuard.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Compiler.h" + +using namespace llvm; + +// This must be kept in sync with gdb/gdb/jit.h . +extern "C" { + + typedef enum { + JIT_NOACTION = 0, + JIT_REGISTER_FN, + JIT_UNREGISTER_FN + } jit_actions_t; + + struct jit_code_entry { + struct jit_code_entry *next_entry; + struct jit_code_entry *prev_entry; + const char *symfile_addr; + uint64_t symfile_size; + }; + + struct jit_descriptor { + uint32_t version; + // This should be jit_actions_t, but we want to be specific about the + // bit-width. + uint32_t action_flag; + struct jit_code_entry *relevant_entry; + struct jit_code_entry *first_entry; + }; + + // We put information about the JITed function in this global, which the + // debugger reads. Make sure to specify the version statically, because the + // debugger checks the version before we can set it during runtime. + static struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; + + // Debuggers puts a breakpoint in this function. + LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() { } + +} + +namespace { + +// Buffer for an in-memory object file in executable memory +typedef llvm::DenseMap< const char*, + std::pair<std::size_t, jit_code_entry*> > + RegisteredObjectBufferMap; + +/// Global access point for the JIT debugging interface designed for use with a +/// singleton toolbox. Handles thread-safe registration and deregistration of +/// object files that are in executable memory managed by the client of this +/// class. +class GDBJITRegistrar : public JITRegistrar { + /// A map of in-memory object files that have been registered with the + /// JIT interface. + RegisteredObjectBufferMap ObjectBufferMap; + +public: + /// Instantiates the JIT service. + GDBJITRegistrar() : ObjectBufferMap() {} + + /// Unregisters each object that was previously registered and releases all + /// internal resources. + virtual ~GDBJITRegistrar(); + + /// Creates an entry in the JIT registry for the buffer @p Object, + /// which must contain an object file in executable memory with any + /// debug information for the debugger. + void registerObject(const MemoryBuffer &Object); + + /// Removes the internal registration of @p Object, and + /// frees associated resources. + /// Returns true if @p Object was found in ObjectBufferMap. + bool deregisterObject(const MemoryBuffer &Object); + +private: + /// Deregister the debug info for the given object file from the debugger + /// and delete any temporary copies. This private method does not remove + /// the function from Map so that it can be called while iterating over Map. + void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I); +}; + +/// Lock used to serialize all jit registration events, since they +/// modify global variables. +llvm::sys::Mutex JITDebugLock; + +/// Acquire the lock and do the registration. +void NotifyDebugger(jit_code_entry* JITCodeEntry) { + llvm::MutexGuard locked(JITDebugLock); + __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; + + // Insert this entry at the head of the list. + JITCodeEntry->prev_entry = NULL; + jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry; + JITCodeEntry->next_entry = NextEntry; + if (NextEntry != NULL) { + NextEntry->prev_entry = JITCodeEntry; + } + __jit_debug_descriptor.first_entry = JITCodeEntry; + __jit_debug_descriptor.relevant_entry = JITCodeEntry; + __jit_debug_register_code(); +} + +GDBJITRegistrar::~GDBJITRegistrar() { + // Free all registered object files. + for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end(); + I != E; ++I) { + // Call the private method that doesn't update the map so our iterator + // doesn't break. + deregisterObjectInternal(I); + } + ObjectBufferMap.clear(); +} + +void GDBJITRegistrar::registerObject(const MemoryBuffer &Object) { + + const char *Buffer = Object.getBufferStart(); + size_t Size = Object.getBufferSize(); + + assert(Buffer && "Attempt to register a null object with a debugger."); + assert(ObjectBufferMap.find(Buffer) == ObjectBufferMap.end() && + "Second attempt to perform debug registration."); + jit_code_entry* JITCodeEntry = new jit_code_entry(); + + if (JITCodeEntry == 0) { + llvm::report_fatal_error( + "Allocation failed when registering a JIT entry!\n"); + } + else { + JITCodeEntry->symfile_addr = Buffer; + JITCodeEntry->symfile_size = Size; + + ObjectBufferMap[Buffer] = std::make_pair(Size, JITCodeEntry); + NotifyDebugger(JITCodeEntry); + } +} + +bool GDBJITRegistrar::deregisterObject(const MemoryBuffer& Object) { + const char *Buffer = Object.getBufferStart(); + RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer); + + if (I != ObjectBufferMap.end()) { + deregisterObjectInternal(I); + ObjectBufferMap.erase(I); + return true; + } + return false; +} + +void GDBJITRegistrar::deregisterObjectInternal( + RegisteredObjectBufferMap::iterator I) { + + jit_code_entry*& JITCodeEntry = I->second.second; + + // Acquire the lock and do the unregistration. + { + llvm::MutexGuard locked(JITDebugLock); + __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN; + + // Remove the jit_code_entry from the linked list. + jit_code_entry* PrevEntry = JITCodeEntry->prev_entry; + jit_code_entry* NextEntry = JITCodeEntry->next_entry; + + if (NextEntry) { + NextEntry->prev_entry = PrevEntry; + } + if (PrevEntry) { + PrevEntry->next_entry = NextEntry; + } + else { + assert(__jit_debug_descriptor.first_entry == JITCodeEntry); + __jit_debug_descriptor.first_entry = NextEntry; + } + + // Tell the debugger which entry we removed, and unregister the code. + __jit_debug_descriptor.relevant_entry = JITCodeEntry; + __jit_debug_register_code(); + } + + delete JITCodeEntry; + JITCodeEntry = NULL; +} + +} // end namespace + +namespace llvm { + +JITRegistrar& JITRegistrar::getGDBRegistrar() { + static GDBJITRegistrar* sRegistrar = NULL; + if (sRegistrar == NULL) { + // The mutex is here so that it won't slow down access once the registrar + // is instantiated + llvm::MutexGuard locked(JITDebugLock); + // Check again to be sure another thread didn't create this while we waited + if (sRegistrar == NULL) { + sRegistrar = new GDBJITRegistrar; + } + } + return *sRegistrar; +} + +} // namespace llvm diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h new file mode 100644 index 0000000..f964bc6 --- /dev/null +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h @@ -0,0 +1,43 @@ +//===-- JITRegistrar.h - Registers objects with a debugger ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H +#define LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H + +#include "llvm/Support/MemoryBuffer.h" + +namespace llvm { + +/// Global access point for the JIT debugging interface. +class JITRegistrar { +public: + /// Instantiates the JIT service. + JITRegistrar() {} + + /// Unregisters each object that was previously registered and releases all + /// internal resources. + virtual ~JITRegistrar() {} + + /// Creates an entry in the JIT registry for the buffer @p Object, + /// which must contain an object file in executable memory with any + /// debug information for the debugger. + virtual void registerObject(const MemoryBuffer &Object) = 0; + + /// Removes the internal registration of @p Object, and + /// frees associated resources. + /// Returns true if @p Object was previously registered. + virtual bool deregisterObject(const MemoryBuffer &Object) = 0; + + /// Returns a reference to a GDB JIT registrar singleton + static JITRegistrar& getGDBRegistrar(); +}; + +} // end namespace llvm + +#endif // LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h new file mode 100644 index 0000000..8206ead --- /dev/null +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h @@ -0,0 +1,59 @@ +//===---- ObjectImage.h - Format independent executuable object image -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares a file format independent ObjectImage class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H +#define LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H + +#include "llvm/Object/ObjectFile.h" + +namespace llvm { + +class ObjectImage { + ObjectImage(); // = delete + ObjectImage(const ObjectImage &other); // = delete +protected: + object::ObjectFile *ObjFile; + +public: + ObjectImage(object::ObjectFile *Obj) { ObjFile = Obj; } + virtual ~ObjectImage() {} + + virtual object::symbol_iterator begin_symbols() const + { return ObjFile->begin_symbols(); } + virtual object::symbol_iterator end_symbols() const + { return ObjFile->end_symbols(); } + + virtual object::section_iterator begin_sections() const + { return ObjFile->begin_sections(); } + virtual object::section_iterator end_sections() const + { return ObjFile->end_sections(); } + + virtual /* Triple::ArchType */ unsigned getArch() const + { return ObjFile->getArch(); } + + // Subclasses can override these methods to update the image with loaded + // addresses for sections and common symbols + virtual void updateSectionAddress(const object::SectionRef &Sec, + uint64_t Addr) {} + virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr) + {} + + // Subclasses can override this method to provide JIT debugging support + virtual void registerWithDebugger() {} + virtual void deregisterWithDebugger() {} +}; + +} // end namespace llvm + +#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H + diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 63cec1a..1b1840a 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -59,11 +59,17 @@ void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress, llvm_unreachable("Attempting to remap address of unknown section!"); } +// Subclasses can implement this method to create specialized image instances +// The caller owns the the pointer that is returned. +ObjectImage *RuntimeDyldImpl::createObjectImage(const MemoryBuffer *InputBuffer) { + ObjectFile *ObjFile = ObjectFile::createObjectFile(const_cast<MemoryBuffer*> + (InputBuffer)); + ObjectImage *Obj = new ObjectImage(ObjFile); + return Obj; +} + bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { - // FIXME: ObjectFile don't modify MemoryBuffer. - // It should use const MemoryBuffer as parameter. - OwningPtr<ObjectFile> obj(ObjectFile::createObjectFile( - const_cast<MemoryBuffer*>(InputBuffer))); + OwningPtr<ObjectImage> obj(createObjectImage(InputBuffer)); if (!obj) report_fatal_error("Unable to create object image from memory buffer!"); @@ -110,7 +116,8 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { (uintptr_t)FileOffset; uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)sData.begin()); unsigned SectionID = - findOrEmitSection(*si, + findOrEmitSection(*obj, + *si, SymType == object::SymbolRef::ST_Function, LocalSections); bool isGlobal = flags & SymbolRef::SF_Global; @@ -128,7 +135,7 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { // Allocate common symbols if (CommonSize != 0) - emitCommonSymbols(CommonSymbols, CommonSize, LocalSymbols); + emitCommonSymbols(*obj, CommonSymbols, CommonSize, LocalSymbols); // Parse and proccess relocations DEBUG(dbgs() << "Parse relocations:\n"); @@ -145,7 +152,7 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { // If it's first relocation in this section, find its SectionID if (isFirstRelocation) { - SectionID = findOrEmitSection(*si, true, LocalSections); + SectionID = findOrEmitSection(*obj, *si, true, LocalSections); DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n"); isFirstRelocation = false; } @@ -164,10 +171,14 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { processRelocationRef(RI, *obj, LocalSections, LocalSymbols, Stubs); } } + + handleObjectLoaded(obj.take()); + return false; } -unsigned RuntimeDyldImpl::emitCommonSymbols(const CommonSymbolMap &Map, +unsigned RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, + const CommonSymbolMap &Map, uint64_t TotalSize, LocalSymbolMap &LocalSymbols) { // Allocate memory for the section @@ -191,6 +202,7 @@ unsigned RuntimeDyldImpl::emitCommonSymbols(const CommonSymbolMap &Map, uint64_t Size = it->second; StringRef Name; it->first.getName(Name); + Obj.updateSymbolAddress(it->first, (uint64_t)Addr); LocalSymbols[Name.data()] = SymbolLoc(SectionID, Offset); Offset += Size; Addr += Size; @@ -199,7 +211,8 @@ unsigned RuntimeDyldImpl::emitCommonSymbols(const CommonSymbolMap &Map, return SectionID; } -unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section, +unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, + const SectionRef &Section, bool IsCode) { unsigned StubBufSize = 0, @@ -257,6 +270,7 @@ unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section, << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); + Obj.updateSectionAddress(Section, (uint64_t)Addr); } else { // Even if we didn't load the section, we need to record an entry for it @@ -277,7 +291,8 @@ unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section, return SectionID; } -unsigned RuntimeDyldImpl::findOrEmitSection(const SectionRef &Section, +unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj, + const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections) { @@ -286,7 +301,7 @@ unsigned RuntimeDyldImpl::findOrEmitSection(const SectionRef &Section, if (i != LocalSections.end()) SectionID = i->second; else { - SectionID = emitSection(Section, IsCode); + SectionID = emitSection(Obj, Section, IsCode); LocalSections[Section] = SectionID; } return SectionID; diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 57fefee..db6da8c 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -20,11 +20,176 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Support/ELF.h" #include "llvm/ADT/Triple.h" +#include "llvm/Object/ELF.h" +#include "JITRegistrar.h" using namespace llvm; using namespace llvm::object; +namespace { + +template<support::endianness target_endianness, bool is64Bits> +class DyldELFObject : public ELFObjectFile<target_endianness, is64Bits> { + LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + + typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; + typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; + typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel; + typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela; + + typedef typename ELFObjectFile<target_endianness, is64Bits>:: + Elf_Ehdr Elf_Ehdr; + + typedef typename ELFDataTypeTypedefHelper< + target_endianness, is64Bits>::value_type addr_type; + +protected: + // This duplicates the 'Data' member in the 'Binary' base class + // but it is necessary to workaround a bug in gcc 4.2 + MemoryBuffer *InputData; + +public: + DyldELFObject(MemoryBuffer *Object, error_code &ec); + + void updateSectionAddress(const SectionRef &Sec, uint64_t Addr); + void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr); + + const MemoryBuffer& getBuffer() const { return *InputData; } + + // Methods for type inquiry through isa, cast, and dyn_cast + static inline bool classof(const Binary *v) { + return (isa<ELFObjectFile<target_endianness, is64Bits> >(v) + && classof(cast<ELFObjectFile<target_endianness, is64Bits> >(v))); + } + static inline bool classof( + const ELFObjectFile<target_endianness, is64Bits> *v) { + return v->isDyldType(); + } + static inline bool classof(const DyldELFObject *v) { + return true; + } +}; + +template<support::endianness target_endianness, bool is64Bits> +class ELFObjectImage : public ObjectImage { + protected: + DyldELFObject<target_endianness, is64Bits> *DyldObj; + bool Registered; + + public: + ELFObjectImage(DyldELFObject<target_endianness, is64Bits> *Obj) + : ObjectImage(Obj), + DyldObj(Obj), + Registered(false) {} + + virtual ~ELFObjectImage() { + if (Registered) + deregisterWithDebugger(); + } + + // Subclasses can override these methods to update the image with loaded + // addresses for sections and common symbols + virtual void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) + { + DyldObj->updateSectionAddress(Sec, Addr); + } + + virtual void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) + { + DyldObj->updateSymbolAddress(Sym, Addr); + } + + virtual void registerWithDebugger() + { + JITRegistrar::getGDBRegistrar().registerObject(DyldObj->getBuffer()); + Registered = true; + } + virtual void deregisterWithDebugger() + { + JITRegistrar::getGDBRegistrar().deregisterObject(DyldObj->getBuffer()); + } +}; + +template<support::endianness target_endianness, bool is64Bits> +DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Object, + error_code &ec) + : ELFObjectFile<target_endianness, is64Bits>(Object, ec), + InputData(Object) { + this->isDyldELFObject = true; +} + +template<support::endianness target_endianness, bool is64Bits> +void DyldELFObject<target_endianness, is64Bits>::updateSectionAddress( + const SectionRef &Sec, + uint64_t Addr) { + DataRefImpl ShdrRef = Sec.getRawDataRefImpl(); + Elf_Shdr *shdr = const_cast<Elf_Shdr*>( + reinterpret_cast<const Elf_Shdr *>(ShdrRef.p)); + + // This assumes the address passed in matches the target address bitness + // The template-based type cast handles everything else. + shdr->sh_addr = static_cast<addr_type>(Addr); +} + +template<support::endianness target_endianness, bool is64Bits> +void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress( + const SymbolRef &SymRef, + uint64_t Addr) { + + Elf_Sym *sym = const_cast<Elf_Sym*>( + ELFObjectFile<target_endianness, is64Bits>:: + getSymbol(SymRef.getRawDataRefImpl())); + + // This assumes the address passed in matches the target address bitness + // The template-based type cast handles everything else. + sym->st_value = static_cast<addr_type>(Addr); +} + +} // namespace + + namespace llvm { +ObjectImage *RuntimeDyldELF::createObjectImage( + const MemoryBuffer *ConstInputBuffer) { + MemoryBuffer *InputBuffer = const_cast<MemoryBuffer*>(ConstInputBuffer); + std::pair<unsigned char, unsigned char> Ident = getElfArchType(InputBuffer); + error_code ec; + + if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { + DyldELFObject<support::little, false> *Obj = + new DyldELFObject<support::little, false>(InputBuffer, ec); + return new ELFObjectImage<support::little, false>(Obj); + } + else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) { + DyldELFObject<support::big, false> *Obj = + new DyldELFObject<support::big, false>(InputBuffer, ec); + return new ELFObjectImage<support::big, false>(Obj); + } + else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) { + DyldELFObject<support::big, true> *Obj = + new DyldELFObject<support::big, true>(InputBuffer, ec); + return new ELFObjectImage<support::big, true>(Obj); + } + else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) { + DyldELFObject<support::little, true> *Obj = + new DyldELFObject<support::little, true>(InputBuffer, ec); + return new ELFObjectImage<support::little, true>(Obj); + } + else + llvm_unreachable("Unexpected ELF format"); +} + +void RuntimeDyldELF::handleObjectLoaded(ObjectImage *Obj) +{ + Obj->registerWithDebugger(); + // Save the loaded object. It will deregister itself when deleted + LoadedObject = Obj; +} + +RuntimeDyldELF::~RuntimeDyldELF() { + if (LoadedObject) + delete LoadedObject; +} void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress, uint64_t FinalAddress, @@ -167,7 +332,7 @@ void RuntimeDyldELF::resolveRelocation(uint8_t *LocalAddress, } void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, - const ObjectFile &Obj, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, LocalSymbolMap &Symbols, StubMap &Stubs) { @@ -206,7 +371,7 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, if (si == Obj.end_sections()) llvm_unreachable("Symbol section not found, bad object file format!"); DEBUG(dbgs() << "\t\tThis is section symbol\n"); - Value.SectionID = findOrEmitSection((*si), true, ObjSectionToID); + Value.SectionID = findOrEmitSection(Obj, (*si), true, ObjSectionToID); Value.Addend = Addend; break; } @@ -236,7 +401,7 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, // Look up for existing stub. StubMap::const_iterator i = Stubs.find(Value); if (i != Stubs.end()) { - resolveRelocation(Target, Section.LoadAddress, (uint64_t)Section.Address + + resolveRelocation(Target, (uint64_t)Target, (uint64_t)Section.Address + i->second, RelType, 0); DEBUG(dbgs() << " Stub function found\n"); } else { @@ -247,7 +412,7 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, Section.StubOffset); AddRelocation(Value, Rel.SectionID, StubTargetAddr - Section.Address, ELF::R_ARM_ABS32); - resolveRelocation(Target, Section.LoadAddress, (uint64_t)Section.Address + + resolveRelocation(Target, (uint64_t)Target, (uint64_t)Section.Address + Section.StubOffset, RelType, 0); Section.StubOffset += getMaxStubSize(); } diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index 36566da..e7f6fab 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -22,6 +22,8 @@ using namespace llvm; namespace llvm { class RuntimeDyldELF : public RuntimeDyldImpl { protected: + ObjectImage *LoadedObject; + void resolveX86_64Relocation(uint8_t *LocalAddress, uint64_t FinalAddress, uint64_t Value, @@ -47,12 +49,18 @@ protected: int64_t Addend); virtual void processRelocationRef(const ObjRelocationInfo &Rel, - const ObjectFile &Obj, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, LocalSymbolMap &Symbols, StubMap &Stubs); + virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer); + virtual void handleObjectLoaded(ObjectImage *Obj); + public: - RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} + RuntimeDyldELF(RTDyldMemoryManager *mm) + : RuntimeDyldImpl(mm), LoadedObject(0) {} + + virtual ~RuntimeDyldELF(); bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const; }; diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index bf678af..2dea13f 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -29,6 +29,7 @@ #include "llvm/ADT/Triple.h" #include <map> #include "llvm/Support/Format.h" +#include "ObjectImage.h" using namespace llvm; using namespace llvm::object; @@ -154,7 +155,8 @@ protected: /// \brief Emits a section containing common symbols. /// \return SectionID. - unsigned emitCommonSymbols(const CommonSymbolMap &Map, + unsigned emitCommonSymbols(ObjectImage &Obj, + const CommonSymbolMap &Map, uint64_t TotalSize, LocalSymbolMap &Symbols); @@ -162,14 +164,18 @@ protected: /// \param IsCode if it's true then allocateCodeSection() will be /// used for emmits, else allocateDataSection() will be used. /// \return SectionID. - unsigned emitSection(const SectionRef &Section, bool IsCode); + unsigned emitSection(ObjectImage &Obj, + const SectionRef &Section, + bool IsCode); /// \brief Find Section in LocalSections. If the secton is not found - emit /// it and store in LocalSections. /// \param IsCode if it's true then allocateCodeSection() will be /// used for emmits, else allocateDataSection() will be used. /// \return SectionID. - unsigned findOrEmitSection(const SectionRef &Section, bool IsCode, + unsigned findOrEmitSection(ObjectImage &Obj, + const SectionRef &Section, + bool IsCode, ObjSectionToIDMap &LocalSections); /// \brief If Value.SymbolName is NULL then store relocation to the @@ -200,11 +206,18 @@ protected: /// \brief Parses the object file relocation and store it to Relocations /// or SymbolRelocations. Its depend from object file type. virtual void processRelocationRef(const ObjRelocationInfo &Rel, - const ObjectFile &Obj, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, LocalSymbolMap &Symbols, StubMap &Stubs) = 0; void resolveSymbols(); + virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer); + virtual void handleObjectLoaded(ObjectImage *Obj) + { + // Subclasses may choose to retain this image if they have a use for it + delete Obj; + } + public: RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {} diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 1318b44..b7f515d 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -205,7 +205,7 @@ resolveARMRelocation(uint8_t *LocalAddress, } void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, - const ObjectFile &Obj, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, LocalSymbolMap &Symbols, StubMap &Stubs) { @@ -246,7 +246,7 @@ void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, break; } assert(si != se && "No section containing relocation!"); - Value.SectionID = findOrEmitSection(*si, true, ObjSectionToID); + Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID); Value.Addend = *(const intptr_t *)Target; if (Value.Addend) { // The MachO addend is offset from the current section, we need set it diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 898b851..418d130 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -49,7 +49,7 @@ protected: int64_t Addend); virtual void processRelocationRef(const ObjRelocationInfo &Rel, - const ObjectFile &Obj, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, LocalSymbolMap &Symbols, StubMap &Stubs); @@ -59,7 +59,7 @@ public: uint64_t Value, uint32_t Type, int64_t Addend); - + RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const; diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp index 2d61cac..8aef43c 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp @@ -1527,11 +1527,11 @@ bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc, } Lex(); } - // If there weren't any arguments, erase the token vector so everything - // else knows that. Leaving around the vestigal empty token list confuses - // things. - if (MacroArguments.size() == 1 && MacroArguments.back().empty()) - MacroArguments.clear(); + // If the last argument didn't end up with any tokens, it's not a real + // argument and we should remove it from the list. This happens with either + // a tailing comma or an empty argument list. + if (MacroArguments.back().empty()) + MacroArguments.pop_back(); // Macro instantiation is lexical, unfortunately. We construct a new buffer // to hold the macro body with substitutions. diff --git a/contrib/llvm/lib/Object/ELFObjectFile.cpp b/contrib/llvm/lib/Object/ELFObjectFile.cpp index ab5f810..663b84e 100644 --- a/contrib/llvm/lib/Object/ELFObjectFile.cpp +++ b/contrib/llvm/lib/Object/ELFObjectFile.cpp @@ -17,16 +17,6 @@ namespace llvm { using namespace object; -namespace { - std::pair<unsigned char, unsigned char> - getElfArchType(MemoryBuffer *Object) { - if (Object->getBufferSize() < ELF::EI_NIDENT) - return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE); - return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS] - , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]); - } -} - // Creates an in-memory object-file by default: createELFObjectFile(Buffer) ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) { std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object); diff --git a/contrib/llvm/lib/Support/JSONParser.cpp b/contrib/llvm/lib/Support/JSONParser.cpp deleted file mode 100644 index 5dfcf29..0000000 --- a/contrib/llvm/lib/Support/JSONParser.cpp +++ /dev/null @@ -1,302 +0,0 @@ -//===--- JSONParser.cpp - Simple JSON parser ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements a JSON parser. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/JSONParser.h" - -#include "llvm/ADT/Twine.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/MemoryBuffer.h" - -using namespace llvm; - -JSONParser::JSONParser(StringRef Input, SourceMgr *SM) - : SM(SM), Failed(false) { - InputBuffer = MemoryBuffer::getMemBuffer(Input, "JSON"); - SM->AddNewSourceBuffer(InputBuffer, SMLoc()); - End = InputBuffer->getBuffer().end(); - Position = InputBuffer->getBuffer().begin(); -} - -JSONValue *JSONParser::parseRoot() { - if (Position != InputBuffer->getBuffer().begin()) - report_fatal_error("Cannot reuse JSONParser."); - if (isWhitespace()) - nextNonWhitespace(); - if (errorIfAtEndOfFile("'[' or '{' at start of JSON text")) - return 0; - switch (*Position) { - case '[': - return new (ValueAllocator.Allocate<JSONArray>(1)) JSONArray(this); - case '{': - return new (ValueAllocator.Allocate<JSONObject>(1)) JSONObject(this); - default: - setExpectedError("'[' or '{' at start of JSON text", *Position); - return 0; - } -} - -bool JSONParser::validate() { - JSONValue *Root = parseRoot(); - if (Root == NULL) { - return false; - } - return skip(*Root); -} - -bool JSONParser::skip(const JSONAtom &Atom) { - switch(Atom.getKind()) { - case JSONAtom::JK_Array: - case JSONAtom::JK_Object: - return skipContainer(*cast<JSONContainer>(&Atom)); - case JSONAtom::JK_String: - return true; - case JSONAtom::JK_KeyValuePair: - return skip(*cast<JSONKeyValuePair>(&Atom)->Value); - } - llvm_unreachable("Impossible enum value."); -} - -// Sets the current error to: -// "expected <Expected>, but found <Found>". -void JSONParser::setExpectedError(StringRef Expected, StringRef Found) { - SM->PrintMessage(SMLoc::getFromPointer(Position), SourceMgr::DK_Error, - "expected " + Expected + ", but found " + Found + ".", ArrayRef<SMRange>()); - Failed = true; -} - -// Sets the current error to: -// "expected <Expected>, but found <Found>". -void JSONParser::setExpectedError(StringRef Expected, char Found) { - setExpectedError(Expected, ("'" + StringRef(&Found, 1) + "'").str()); -} - -// If there is no character available, returns true and sets the current error -// to: "expected <Expected>, but found EOF.". -bool JSONParser::errorIfAtEndOfFile(StringRef Expected) { - if (Position == End) { - setExpectedError(Expected, "EOF"); - return true; - } - return false; -} - -// Sets the current error if the current character is not C to: -// "expected 'C', but got <current character>". -bool JSONParser::errorIfNotAt(char C, StringRef Message) { - if (*Position != C) { - std::string Expected = - ("'" + StringRef(&C, 1) + "' " + Message).str(); - if (Position == End) - setExpectedError(Expected, "EOF"); - else - setExpectedError(Expected, *Position); - return true; - } - return false; -} - -// Forbidding inlining improves performance by roughly 20%. -// FIXME: Remove once llvm optimizes this to the faster version without hints. -LLVM_ATTRIBUTE_NOINLINE static bool -wasEscaped(StringRef::iterator First, StringRef::iterator Position); - -// Returns whether a character at 'Position' was escaped with a leading '\'. -// 'First' specifies the position of the first character in the string. -static bool wasEscaped(StringRef::iterator First, - StringRef::iterator Position) { - assert(Position - 1 >= First); - StringRef::iterator I = Position - 1; - // We calulate the number of consecutive '\'s before the current position - // by iterating backwards through our string. - while (I >= First && *I == '\\') --I; - // (Position - 1 - I) now contains the number of '\'s before the current - // position. If it is odd, the character at 'Positon' was escaped. - return (Position - 1 - I) % 2 == 1; -} - -// Parses a JSONString, assuming that the current position is on a quote. -JSONString *JSONParser::parseString() { - assert(Position != End); - assert(!isWhitespace()); - if (errorIfNotAt('"', "at start of string")) - return 0; - StringRef::iterator First = Position + 1; - - // Benchmarking shows that this loop is the hot path of the application with - // about 2/3rd of the runtime cycles. Since escaped quotes are not the common - // case, and multiple escaped backslashes before escaped quotes are very rare, - // we pessimize this case to achieve a smaller inner loop in the common case. - // We're doing that by having a quick inner loop that just scans for the next - // quote. Once we find the quote we check the last character to see whether - // the quote might have been escaped. If the last character is not a '\', we - // know the quote was not escaped and have thus found the end of the string. - // If the immediately preceding character was a '\', we have to scan backwards - // to see whether the previous character was actually an escaped backslash, or - // an escape character for the quote. If we find that the current quote was - // escaped, we continue parsing for the next quote and repeat. - // This optimization brings around 30% performance improvements. - do { - // Step over the current quote. - ++Position; - // Find the next quote. - while (Position != End && *Position != '"') - ++Position; - if (errorIfAtEndOfFile("'\"' at end of string")) - return 0; - // Repeat until the previous character was not a '\' or was an escaped - // backslash. - } while (*(Position - 1) == '\\' && wasEscaped(First, Position)); - - return new (ValueAllocator.Allocate<JSONString>()) - JSONString(StringRef(First, Position - First)); -} - - -// Advances the position to the next non-whitespace position. -void JSONParser::nextNonWhitespace() { - do { - ++Position; - } while (isWhitespace()); -} - -// Checks if there is a whitespace character at the current position. -bool JSONParser::isWhitespace() { - return *Position == ' ' || *Position == '\t' || - *Position == '\n' || *Position == '\r'; -} - -bool JSONParser::failed() const { - return Failed; -} - -// Parses a JSONValue, assuming that the current position is at the first -// character of the value. -JSONValue *JSONParser::parseValue() { - assert(Position != End); - assert(!isWhitespace()); - switch (*Position) { - case '[': - return new (ValueAllocator.Allocate<JSONArray>(1)) JSONArray(this); - case '{': - return new (ValueAllocator.Allocate<JSONObject>(1)) JSONObject(this); - case '"': - return parseString(); - default: - setExpectedError("'[', '{' or '\"' at start of value", *Position); - return 0; - } -} - -// Parses a JSONKeyValuePair, assuming that the current position is at the first -// character of the key, value pair. -JSONKeyValuePair *JSONParser::parseKeyValuePair() { - assert(Position != End); - assert(!isWhitespace()); - - JSONString *Key = parseString(); - if (Key == 0) - return 0; - - nextNonWhitespace(); - if (errorIfNotAt(':', "between key and value")) - return 0; - - nextNonWhitespace(); - const JSONValue *Value = parseValue(); - if (Value == 0) - return 0; - - return new (ValueAllocator.Allocate<JSONKeyValuePair>(1)) - JSONKeyValuePair(Key, Value); -} - -/// \brief Parses the first element of a JSON array or object, or closes the -/// array. -/// -/// The method assumes that the current position is before the first character -/// of the element, with possible white space in between. When successful, it -/// returns the new position after parsing the element. Otherwise, if there is -/// no next value, it returns a default constructed StringRef::iterator. -StringRef::iterator JSONParser::parseFirstElement(JSONAtom::Kind ContainerKind, - char StartChar, char EndChar, - const JSONAtom *&Element) { - assert(*Position == StartChar); - Element = 0; - nextNonWhitespace(); - if (errorIfAtEndOfFile("value or end of container at start of container")) - return StringRef::iterator(); - - if (*Position == EndChar) - return StringRef::iterator(); - - Element = parseElement(ContainerKind); - if (Element == 0) - return StringRef::iterator(); - - return Position; -} - -/// \brief Parses the next element of a JSON array or object, or closes the -/// array. -/// -/// The method assumes that the current position is before the ',' which -/// separates the next element from the current element. When successful, it -/// returns the new position after parsing the element. Otherwise, if there is -/// no next value, it returns a default constructed StringRef::iterator. -StringRef::iterator JSONParser::parseNextElement(JSONAtom::Kind ContainerKind, - char EndChar, - const JSONAtom *&Element) { - Element = 0; - nextNonWhitespace(); - if (errorIfAtEndOfFile("',' or end of container for next element")) - return 0; - - if (*Position == ',') { - nextNonWhitespace(); - if (errorIfAtEndOfFile("element in container")) - return StringRef::iterator(); - - Element = parseElement(ContainerKind); - if (Element == 0) - return StringRef::iterator(); - - return Position; - } else if (*Position == EndChar) { - return StringRef::iterator(); - } else { - setExpectedError("',' or end of container for next element", *Position); - return StringRef::iterator(); - } -} - -const JSONAtom *JSONParser::parseElement(JSONAtom::Kind ContainerKind) { - switch (ContainerKind) { - case JSONAtom::JK_Array: - return parseValue(); - case JSONAtom::JK_Object: - return parseKeyValuePair(); - default: - llvm_unreachable("Impossible code path"); - } -} - -bool JSONParser::skipContainer(const JSONContainer &Container) { - for (JSONContainer::AtomIterator I = Container.atom_current(), - E = Container.atom_end(); - I != E; ++I) { - assert(*I != 0); - if (!skip(**I)) - return false; - } - return !failed(); -} diff --git a/contrib/llvm/lib/Support/Locale.cpp b/contrib/llvm/lib/Support/Locale.cpp new file mode 100644 index 0000000..17b9b6c --- /dev/null +++ b/contrib/llvm/lib/Support/Locale.cpp @@ -0,0 +1,10 @@ +#include "llvm/Support/Locale.h" +#include "llvm/Config/config.h" + +#ifdef __APPLE__ +#include "LocaleXlocale.inc" +#elif LLVM_ON_WIN32 +#include "LocaleWindows.inc" +#else +#include "LocaleGeneric.inc" +#endif diff --git a/contrib/llvm/lib/Support/LocaleGeneric.inc b/contrib/llvm/lib/Support/LocaleGeneric.inc new file mode 100644 index 0000000..278deee --- /dev/null +++ b/contrib/llvm/lib/Support/LocaleGeneric.inc @@ -0,0 +1,17 @@ +#include <cwctype> + +namespace llvm { +namespace sys { +namespace locale { + +int columnWidth(StringRef s) { + return s.size(); +} + +bool isPrint(int c) { + return iswprint(c); +} + +} +} +} diff --git a/contrib/llvm/lib/Support/LocaleWindows.inc b/contrib/llvm/lib/Support/LocaleWindows.inc new file mode 100644 index 0000000..6827ac1 --- /dev/null +++ b/contrib/llvm/lib/Support/LocaleWindows.inc @@ -0,0 +1,15 @@ +namespace llvm { +namespace sys { +namespace locale { + +int columnWidth(StringRef s) { + return s.size(); +} + +bool isPrint(int c) { + return ' ' <= c && c <= '~'; +} + +} +} +}
\ No newline at end of file diff --git a/contrib/llvm/lib/Support/LocaleXlocale.inc b/contrib/llvm/lib/Support/LocaleXlocale.inc new file mode 100644 index 0000000..f595e7c --- /dev/null +++ b/contrib/llvm/lib/Support/LocaleXlocale.inc @@ -0,0 +1,61 @@ +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/ManagedStatic.h" +#include <cassert> +#include <xlocale.h> + + +namespace { + struct locale_holder { + locale_holder() + : l(newlocale(LC_CTYPE_MASK,"en_US.UTF-8",LC_GLOBAL_LOCALE)) + { + assert(NULL!=l); + } + ~locale_holder() { + freelocale(l); + } + + int mbswidth(llvm::SmallString<16> s) const { + // this implementation assumes no '\0' in s + assert(s.size()==strlen(s.c_str())); + + size_t size = mbstowcs_l(NULL,s.c_str(),0,l); + assert(size!=(size_t)-1); + if (size==0) + return 0; + llvm::SmallVector<wchar_t,200> ws(size); + size = mbstowcs_l(&ws[0],s.c_str(),ws.size(),l); + assert(ws.size()==size); + return wcswidth_l(&ws[0],ws.size(),l); + } + + int isprint(int c) const { + return iswprint_l(c,l); + } + + private: + + locale_t l; + }; + + llvm::ManagedStatic<locale_holder> l; +} + +namespace llvm { +namespace sys { +namespace locale { + +int columnWidth(StringRef s) { + int width = l->mbswidth(s); + assert(width>=0); + return width; +} + +bool isPrint(int c) { + return l->isprint(c); +} + +} +} +} diff --git a/contrib/llvm/lib/Support/SmallPtrSet.cpp b/contrib/llvm/lib/Support/SmallPtrSet.cpp index 68d9c29..3b53e9f 100644 --- a/contrib/llvm/lib/Support/SmallPtrSet.cpp +++ b/contrib/llvm/lib/Support/SmallPtrSet.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/MathExtras.h" #include <algorithm> #include <cstdlib> @@ -102,7 +103,7 @@ bool SmallPtrSetImpl::erase_imp(const void * Ptr) { } const void * const *SmallPtrSetImpl::FindBucketFor(const void *Ptr) const { - unsigned Bucket = Hash(Ptr); + unsigned Bucket = DenseMapInfo<void *>::getHashValue(Ptr) & (CurArraySize-1); unsigned ArraySize = CurArraySize; unsigned ProbeAmt = 1; const void *const *Array = CurArray; diff --git a/contrib/llvm/lib/Support/SourceMgr.cpp b/contrib/llvm/lib/Support/SourceMgr.cpp index bbe36b2..15278c5 100644 --- a/contrib/llvm/lib/Support/SourceMgr.cpp +++ b/contrib/llvm/lib/Support/SourceMgr.cpp @@ -193,7 +193,8 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind, } void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, - const Twine &Msg, ArrayRef<SMRange> Ranges) const { + const Twine &Msg, ArrayRef<SMRange> Ranges, + bool ShowColors) const { SMDiagnostic Diagnostic = GetMessage(Loc, Kind, Msg, Ranges); // Report the message with the diagnostic handler if present. @@ -208,7 +209,7 @@ void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, assert(CurBuf != -1 && "Invalid or unspecified location!"); PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS); - Diagnostic.print(0, OS); + Diagnostic.print(0, OS, ShowColors); } //===----------------------------------------------------------------------===// @@ -225,7 +226,14 @@ SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN, } -void SMDiagnostic::print(const char *ProgName, raw_ostream &S) const { +void SMDiagnostic::print(const char *ProgName, raw_ostream &S, + bool ShowColors) const { + // Display colors only if OS goes to a tty. + ShowColors &= S.is_displayed(); + + if (ShowColors) + S.changeColor(raw_ostream::SAVEDCOLOR, true); + if (ProgName && ProgName[0]) S << ProgName << ": "; @@ -244,13 +252,33 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &S) const { } switch (Kind) { - case SourceMgr::DK_Error: S << "error: "; break; - case SourceMgr::DK_Warning: S << "warning: "; break; - case SourceMgr::DK_Note: S << "note: "; break; + case SourceMgr::DK_Error: + if (ShowColors) + S.changeColor(raw_ostream::RED, true); + S << "error: "; + break; + case SourceMgr::DK_Warning: + if (ShowColors) + S.changeColor(raw_ostream::MAGENTA, true); + S << "warning: "; + break; + case SourceMgr::DK_Note: + if (ShowColors) + S.changeColor(raw_ostream::BLACK, true); + S << "note: "; + break; } - + + if (ShowColors) { + S.resetColor(); + S.changeColor(raw_ostream::SAVEDCOLOR, true); + } + S << Message << '\n'; + if (ShowColors) + S.resetColor(); + if (LineNo == -1 || ColumnNo == -1) return; @@ -292,6 +320,9 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &S) const { } S << '\n'; + if (ShowColors) + S.changeColor(raw_ostream::GREEN, true); + // Print out the caret line, matching tabs in the source line. for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) { if (i >= LineContents.size() || LineContents[i] != '\t') { @@ -306,6 +337,9 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &S) const { ++OutCol; } while (OutCol & 7); } + + if (ShowColors) + S.resetColor(); S << '\n'; } diff --git a/contrib/llvm/lib/Support/Unix/Process.inc b/contrib/llvm/lib/Support/Unix/Process.inc index 2d7fd38..f640462 100644 --- a/contrib/llvm/lib/Support/Unix/Process.inc +++ b/contrib/llvm/lib/Support/Unix/Process.inc @@ -290,6 +290,10 @@ const char *Process::OutputBold(bool bg) { return "\033[1m"; } +const char *Process::OutputReverse() { + return "\033[7m"; +} + const char *Process::ResetColor() { return "\033[0m"; } diff --git a/contrib/llvm/lib/Support/Windows/Process.inc b/contrib/llvm/lib/Support/Windows/Process.inc index 913b073..9a388b4 100644 --- a/contrib/llvm/lib/Support/Windows/Process.inc +++ b/contrib/llvm/lib/Support/Windows/Process.inc @@ -215,6 +215,38 @@ const char *Process::OutputColor(char code, bool bold, bool bg) { return 0; } +static WORD GetConsoleTextAttribute(HANDLE hConsoleOutput) { + CONSOLE_SCREEN_BUFFER_INFO info; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); + return info.wAttributes; +} + +const char *Process::OutputReverse() { + const WORD attributes + = GetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE)); + + const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | + FOREGROUND_RED | FOREGROUND_INTENSITY; + const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | + BACKGROUND_RED | BACKGROUND_INTENSITY; + const WORD color_mask = foreground_mask | background_mask; + + WORD new_attributes = + ((attributes & FOREGROUND_BLUE )?BACKGROUND_BLUE :0) | + ((attributes & FOREGROUND_GREEN )?BACKGROUND_GREEN :0) | + ((attributes & FOREGROUND_RED )?BACKGROUND_RED :0) | + ((attributes & FOREGROUND_INTENSITY)?BACKGROUND_INTENSITY:0) | + ((attributes & BACKGROUND_BLUE )?FOREGROUND_BLUE :0) | + ((attributes & BACKGROUND_GREEN )?FOREGROUND_GREEN :0) | + ((attributes & BACKGROUND_RED )?FOREGROUND_RED :0) | + ((attributes & BACKGROUND_INTENSITY)?FOREGROUND_INTENSITY:0) | + 0; + new_attributes = (attributes & ~color_mask) | (new_attributes & color_mask); + + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), new_attributes); + return 0; +} + const char *Process::ResetColor() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors()); return 0; diff --git a/contrib/llvm/lib/Support/YAMLParser.cpp b/contrib/llvm/lib/Support/YAMLParser.cpp index 330519f..d38b51b 100644 --- a/contrib/llvm/lib/Support/YAMLParser.cpp +++ b/contrib/llvm/lib/Support/YAMLParser.cpp @@ -1732,7 +1732,7 @@ StringRef ScalarNode::unescapeDoubleQuoted( StringRef UnquotedValue if (UnquotedValue.size() < 3) // TODO: Report error. break; - unsigned int UnicodeScalarValue; + unsigned int UnicodeScalarValue = 0; UnquotedValue.substr(1, 2).getAsInteger(16, UnicodeScalarValue); encodeUTF8(UnicodeScalarValue, Storage); UnquotedValue = UnquotedValue.substr(2); @@ -1742,7 +1742,7 @@ StringRef ScalarNode::unescapeDoubleQuoted( StringRef UnquotedValue if (UnquotedValue.size() < 5) // TODO: Report error. break; - unsigned int UnicodeScalarValue; + unsigned int UnicodeScalarValue = 0; UnquotedValue.substr(1, 4).getAsInteger(16, UnicodeScalarValue); encodeUTF8(UnicodeScalarValue, Storage); UnquotedValue = UnquotedValue.substr(4); @@ -1752,7 +1752,7 @@ StringRef ScalarNode::unescapeDoubleQuoted( StringRef UnquotedValue if (UnquotedValue.size() < 9) // TODO: Report error. break; - unsigned int UnicodeScalarValue; + unsigned int UnicodeScalarValue = 0; UnquotedValue.substr(1, 8).getAsInteger(16, UnicodeScalarValue); encodeUTF8(UnicodeScalarValue, Storage); UnquotedValue = UnquotedValue.substr(8); diff --git a/contrib/llvm/lib/Support/raw_ostream.cpp b/contrib/llvm/lib/Support/raw_ostream.cpp index 72d3986..86cdca1 100644 --- a/contrib/llvm/lib/Support/raw_ostream.cpp +++ b/contrib/llvm/lib/Support/raw_ostream.cpp @@ -633,6 +633,19 @@ raw_ostream &raw_fd_ostream::resetColor() { return *this; } +raw_ostream &raw_fd_ostream::reverseColor() { + if (sys::Process::ColorNeedsFlush()) + flush(); + const char *colorcode = sys::Process::OutputReverse(); + if (colorcode) { + size_t len = strlen(colorcode); + write(colorcode, len); + // don't account colors towards output characters + pos -= len; + } + return *this; +} + bool raw_fd_ostream::is_displayed() const { return sys::Process::FileDescriptorIsDisplayed(FD); } diff --git a/contrib/llvm/lib/TableGen/Error.cpp b/contrib/llvm/lib/TableGen/Error.cpp index 5071ee7..1463b68 100644 --- a/contrib/llvm/lib/TableGen/Error.cpp +++ b/contrib/llvm/lib/TableGen/Error.cpp @@ -20,6 +20,22 @@ namespace llvm { SourceMgr SrcMgr; +void PrintWarning(SMLoc WarningLoc, const Twine &Msg) { + SrcMgr.PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg); +} + +void PrintWarning(const char *Loc, const Twine &Msg) { + SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg); +} + +void PrintWarning(const Twine &Msg) { + errs() << "warning:" << Msg << "\n"; +} + +void PrintWarning(const TGError &Warning) { + PrintWarning(Warning.getLoc(), Warning.getMessage()); +} + void PrintError(SMLoc ErrorLoc, const Twine &Msg) { SrcMgr.PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg); } diff --git a/contrib/llvm/lib/Target/ARM/ARMCallingConv.td b/contrib/llvm/lib/Target/ARM/ARMCallingConv.td index d33364b..b9a2512 100644 --- a/contrib/llvm/lib/Target/ARM/ARMCallingConv.td +++ b/contrib/llvm/lib/Target/ARM/ARMCallingConv.td @@ -9,10 +9,6 @@ // This describes the calling conventions for ARM architecture. //===----------------------------------------------------------------------===// -/// CCIfSubtarget - Match if the current subtarget has a feature F. -class CCIfSubtarget<string F, CCAction A>: - CCIf<!strconcat("State.getTarget().getSubtarget<ARMSubtarget>().", F), A>; - /// CCIfAlign - Match of the original alignment of the arg class CCIfAlign<string Align, CCAction A>: CCIf<!strconcat("ArgFlags.getOrigAlign() == ", Align), A>; diff --git a/contrib/llvm/lib/Target/ARM/ARMInstrFormats.td b/contrib/llvm/lib/Target/ARM/ARMInstrFormats.td index 1d38bcf..f04926a 100644 --- a/contrib/llvm/lib/Target/ARM/ARMInstrFormats.td +++ b/contrib/llvm/lib/Target/ARM/ARMInstrFormats.td @@ -532,6 +532,7 @@ class AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern> let Inst{11-4} = 0b00001001; let Inst{3-0} = Rt2; + let Unpredictable{11-8} = 0b1111; let DecoderMethod = "DecodeSwap"; } diff --git a/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td b/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td index 3caaa23..1eb561d 100644 --- a/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -219,8 +219,11 @@ def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">; // Prefer fused MAC for fp mul + add over fp VMLA / VMLS if they are available. // But only select them if more precision in FP computation is allowed. -def UseFusedMAC : Predicate<"!TM.Options.NoExcessFPPrecision">; -def DontUseFusedMAC : Predicate<"!Subtarget->hasVFP4()">; +// Do not use them for Darwin platforms. +def UseFusedMAC : Predicate<"!TM.Options.NoExcessFPPrecision && " + "!Subtarget->isTargetDarwin()">; +def DontUseFusedMAC : Predicate<"!Subtarget->hasVFP4() || " + "Subtarget->isTargetDarwin()">; //===----------------------------------------------------------------------===// // ARM Flag Definitions. @@ -905,6 +908,11 @@ def p_imm : Operand<i32> { let DecoderMethod = "DecodeCoprocessor"; } +def pf_imm : Operand<i32> { + let PrintMethod = "printPImmediate"; + let ParserMatchClass = CoprocNumAsmOperand; +} + def CoprocRegAsmOperand : AsmOperandClass { let Name = "CoprocReg"; let ParserMethod = "parseCoprocRegOperand"; @@ -1184,6 +1192,8 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc, let Inst{19-16} = Rn; let Inst{15-12} = 0b0000; let Inst{11-0} = imm; + + let Unpredictable{15-12} = 0b1111; } def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir, opc, "\t$Rn, $Rm", @@ -1197,6 +1207,8 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc, let Inst{15-12} = 0b0000; let Inst{11-4} = 0b00000000; let Inst{3-0} = Rm; + + let Unpredictable{15-12} = 0b1111; } def rsi : AI1<opcod, (outs), (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, iis, @@ -1211,11 +1223,13 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc, let Inst{11-5} = shift{11-5}; let Inst{4} = 0; let Inst{3-0} = shift{3-0}; + + let Unpredictable{15-12} = 0b1111; } def rsr : AI1<opcod, (outs), - (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis, + (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis, opc, "\t$Rn, $shift", - [(opnode GPR:$Rn, so_reg_reg:$shift)]> { + [(opnode GPRnopc:$Rn, so_reg_reg:$shift)]> { bits<4> Rn; bits<12> shift; let Inst{25} = 0; @@ -1227,6 +1241,8 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc, let Inst{6-5} = shift{6-5}; let Inst{4} = 1; let Inst{3-0} = shift{3-0}; + + let Unpredictable{15-12} = 0b1111; } } @@ -4103,7 +4119,7 @@ def ISB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, let Inst{3-0} = opt; } -// Pseudo isntruction that combines movs + predicated rsbmi +// Pseudo instruction that combines movs + predicated rsbmi // to implement integer ABS let usesCustomInserter = 1, Defs = [CPSR] in { def ABS : ARMPseudoInst< @@ -4264,9 +4280,9 @@ def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", []>, // SWP/SWPB are deprecated in V6/V7. let mayLoad = 1, mayStore = 1 in { -def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, addr_offset_none:$addr), +def SWP : AIswp<0, (outs GPRnopc:$Rt), (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swp", []>; -def SWPB: AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, addr_offset_none:$addr), +def SWPB: AIswp<1, (outs GPRnopc:$Rt), (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swpb", []>; } @@ -4295,7 +4311,7 @@ def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, let Inst{23-20} = opc1; } -def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, +def CDP2 : ABXI<0b1110, (outs), (ins pf_imm:$cop, imm0_15:$opc1, c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, @@ -4574,7 +4590,7 @@ def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, class MovRRCopro<string opc, bit direction, list<dag> pattern = []> : ABI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, - GPR:$Rt, GPR:$Rt2, c_imm:$CRm), + GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { let Inst{23-21} = 0b010; let Inst{20} = direction; @@ -4593,13 +4609,13 @@ class MovRRCopro<string opc, bit direction, list<dag> pattern = []> } def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, - [(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, + [(int_arm_mcrr imm:$cop, imm:$opc1, GPRnopc:$Rt, GPRnopc:$Rt2, imm:$CRm)]>; def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>; class MovRRCopro2<string opc, bit direction, list<dag> pattern = []> : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, - GPR:$Rt, GPR:$Rt2, c_imm:$CRm), NoItinerary, + GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> { let Inst{31-28} = 0b1111; let Inst{23-21} = 0b010; @@ -4616,10 +4632,12 @@ class MovRRCopro2<string opc, bit direction, list<dag> pattern = []> let Inst{11-8} = cop; let Inst{7-4} = opc1; let Inst{3-0} = CRm; + + let DecoderMethod = "DecodeMRRC2"; } def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */, - [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, + [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPRnopc:$Rt, GPRnopc:$Rt2, imm:$CRm)]>; def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>; @@ -4628,22 +4646,32 @@ def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>; // // Move to ARM core register from Special Register -def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, +def MRS : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, apsr", []> { bits<4> Rd; let Inst{23-16} = 0b00001111; + let Unpredictable{19-17} = 0b111; + let Inst{15-12} = Rd; - let Inst{7-4} = 0b0000; + + let Inst{11-0} = 0b000000000000; + let Unpredictable{11-0} = 0b110100001111; } -def : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPR:$Rd, pred:$p)>, Requires<[IsARM]>; +def : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPRnopc:$Rd, pred:$p)>, Requires<[IsARM]>; -def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, +// The MRSsys instruction is the MRS instruction from the ARM ARM, +// section B9.3.9, with the R bit set to 1. +def MRSsys : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr", []> { bits<4> Rd; let Inst{23-16} = 0b01001111; + let Unpredictable{19-16} = 0b1111; + let Inst{15-12} = Rd; - let Inst{7-4} = 0b0000; + + let Inst{11-0} = 0b000000000000; + let Unpredictable{11-0} = 0b110100001111; } // Move from ARM core register to Special Register diff --git a/contrib/llvm/lib/Target/ARM/ARMInstrNEON.td b/contrib/llvm/lib/Target/ARM/ARMInstrNEON.td index c7219a6..fd8ac0b 100644 --- a/contrib/llvm/lib/Target/ARM/ARMInstrNEON.td +++ b/contrib/llvm/lib/Target/ARM/ARMInstrNEON.td @@ -5634,6 +5634,7 @@ multiclass Lengthen_HalfSingle<string DestLanes, string DestTy, string SrcTy, // extload, zextload and sextload for a lengthening load followed by another // lengthening load, to quadruple the initial length. +// // Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32", qsub_0> = // Pat<(v4i32 (extloadvi8 addrmode5:$addr)) // (EXTRACT_SUBREG (VMOVLuv4i32 @@ -5644,28 +5645,63 @@ multiclass Lengthen_HalfSingle<string DestLanes, string DestTy, string SrcTy, // qsub_0)>; multiclass Lengthen_Double<string DestLanes, string DestTy, string SrcTy, string Insn1Lanes, string Insn1Ty, string Insn2Lanes, - string Insn2Ty, SubRegIndex RegType> { + string Insn2Ty> { + def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) + (!cast<PatFrag>("extloadv" # SrcTy) addrmode5:$addr)), + (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) + (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) + (INSERT_SUBREG (f64 (IMPLICIT_DEF)), (VLDRS addrmode5:$addr), + ssub_0)), dsub_0))>; + def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) + (!cast<PatFrag>("zextloadv" # SrcTy) addrmode5:$addr)), + (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) + (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) + (INSERT_SUBREG (f64 (IMPLICIT_DEF)), (VLDRS addrmode5:$addr), + ssub_0)), dsub_0))>; + def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) + (!cast<PatFrag>("sextloadv" # SrcTy) addrmode5:$addr)), + (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty) + (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty) + (INSERT_SUBREG (f64 (IMPLICIT_DEF)), (VLDRS addrmode5:$addr), + ssub_0)), dsub_0))>; +} + +// extload, zextload and sextload for a lengthening load followed by another +// lengthening load, to quadruple the initial length, but which ends up only +// requiring half the available lanes (a 64-bit outcome instead of a 128-bit). +// +// Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32"> = +// Pat<(v4i32 (extloadvi8 addrmode5:$addr)) +// (EXTRACT_SUBREG (VMOVLuv4i32 +// (EXTRACT_SUBREG (VMOVLuv8i16 (INSERT_SUBREG (f64 (IMPLICIT_DEF)), +// (VLDRS addrmode5:$addr), +// ssub_0)), +// dsub_0)), +// dsub_0)>; +multiclass Lengthen_HalfDouble<string DestLanes, string DestTy, string SrcTy, + string Insn1Lanes, string Insn1Ty, string Insn2Lanes, + string Insn2Ty> { def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) (!cast<PatFrag>("extloadv" # SrcTy) addrmode5:$addr)), (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) (INSERT_SUBREG (f64 (IMPLICIT_DEF)), (VLDRS addrmode5:$addr), ssub_0)), dsub_0)), - RegType)>; + dsub_0)>; def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) (!cast<PatFrag>("zextloadv" # SrcTy) addrmode5:$addr)), (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) (INSERT_SUBREG (f64 (IMPLICIT_DEF)), (VLDRS addrmode5:$addr), ssub_0)), dsub_0)), - RegType)>; + dsub_0)>; def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) (!cast<PatFrag>("sextloadv" # SrcTy) addrmode5:$addr)), (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty) (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty) (INSERT_SUBREG (f64 (IMPLICIT_DEF)), (VLDRS addrmode5:$addr), ssub_0)), dsub_0)), - RegType)>; + dsub_0)>; } defm : Lengthen_Single<"8", "i16", "i8">; // v8i8 -> v8i16 @@ -5676,12 +5712,12 @@ defm : Lengthen_HalfSingle<"4", "i16", "i8", "8", "i16">; // v4i8 -> v4i16 defm : Lengthen_HalfSingle<"2", "i16", "i8", "8", "i16">; // v2i8 -> v2i16 defm : Lengthen_HalfSingle<"2", "i32", "i16", "4", "i32">; // v2i16 -> v2i32 -// Double lengthening - v4i8 -> v4i16 -> v4i32 -defm : Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32", qsub_0>; +// Double lengthening - v4i8 -> v4i16 -> v4i32 +defm : Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32">; // v2i8 -> v2i16 -> v2i32 -defm : Lengthen_Double<"2", "i32", "i8", "8", "i16", "4", "i32", dsub_0>; +defm : Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32">; // v2i16 -> v2i32 -> v2i64 -defm : Lengthen_Double<"2", "i64", "i16", "4", "i32", "2", "i64", qsub_0>; +defm : Lengthen_Double<"2", "i64", "i16", "4", "i32", "2", "i64">; // Triple lengthening - v2i8 -> v2i16 -> v2i32 -> v2i64 def : Pat<(v2i64 (extloadvi8 addrmode5:$addr)), @@ -5951,7 +5987,7 @@ def : NEONInstAlias<"vshl${p}.u32 $Vdn, $Vm", def : NEONInstAlias<"vshl${p}.u64 $Vdn, $Vm", (VSHLuv2i64 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; -// VSHL (immediate) two-operand aliases. +// VSHR (immediate) two-operand aliases. def : NEONInstAlias<"vshr${p}.s8 $Vdn, $imm", (VSHRsv8i8 DPR:$Vdn, DPR:$Vdn, shr_imm8:$imm, pred:$p)>; def : NEONInstAlias<"vshr${p}.s16 $Vdn, $imm", @@ -5988,6 +6024,41 @@ def : NEONInstAlias<"vshr${p}.u32 $Vdn, $imm", def : NEONInstAlias<"vshr${p}.u64 $Vdn, $imm", (VSHRuv2i64 QPR:$Vdn, QPR:$Vdn, shr_imm64:$imm, pred:$p)>; +// VRSHL two-operand aliases. +def : NEONInstAlias<"vrshl${p}.s8 $Vdn, $Vm", + (VRSHLsv8i8 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.s16 $Vdn, $Vm", + (VRSHLsv4i16 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.s32 $Vdn, $Vm", + (VRSHLsv2i32 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.s64 $Vdn, $Vm", + (VRSHLsv1i64 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.u8 $Vdn, $Vm", + (VRSHLuv8i8 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.u16 $Vdn, $Vm", + (VRSHLuv4i16 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.u32 $Vdn, $Vm", + (VRSHLuv2i32 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.u64 $Vdn, $Vm", + (VRSHLuv1i64 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; + +def : NEONInstAlias<"vrshl${p}.s8 $Vdn, $Vm", + (VRSHLsv16i8 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.s16 $Vdn, $Vm", + (VRSHLsv8i16 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.s32 $Vdn, $Vm", + (VRSHLsv4i32 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.s64 $Vdn, $Vm", + (VRSHLsv2i64 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.u8 $Vdn, $Vm", + (VRSHLuv16i8 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.u16 $Vdn, $Vm", + (VRSHLuv8i16 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.u32 $Vdn, $Vm", + (VRSHLuv4i32 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vrshl${p}.u64 $Vdn, $Vm", + (VRSHLuv2i64 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; + // VLD1 single-lane pseudo-instructions. These need special handling for // the lane index that an InstAlias can't handle, so we use these instead. def VLD1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr", @@ -6951,6 +7022,100 @@ def : NEONInstAlias<"vsli${p}.32 $Vdm, $imm", def : NEONInstAlias<"vsli${p}.64 $Vdm, $imm", (VSLIv2i64 QPR:$Vdm, QPR:$Vdm, shr_imm64:$imm, pred:$p)>; +// Two-operand variants for VHSUB. + // Signed. +def : NEONInstAlias<"vhsub${p}.s8 $Vdn, $Vm", + (VHSUBsv8i8 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhsub${p}.s16 $Vdn, $Vm", + (VHSUBsv4i16 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhsub${p}.s32 $Vdn, $Vm", + (VHSUBsv2i32 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; + +def : NEONInstAlias<"vhsub${p}.s8 $Vdn, $Vm", + (VHSUBsv16i8 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhsub${p}.s16 $Vdn, $Vm", + (VHSUBsv8i16 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhsub${p}.s32 $Vdn, $Vm", + (VHSUBsv4i32 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; + + // Unsigned. +def : NEONInstAlias<"vhsub${p}.u8 $Vdn, $Vm", + (VHSUBuv8i8 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhsub${p}.u16 $Vdn, $Vm", + (VHSUBuv4i16 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhsub${p}.u32 $Vdn, $Vm", + (VHSUBuv2i32 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; + +def : NEONInstAlias<"vhsub${p}.u8 $Vdn, $Vm", + (VHSUBuv16i8 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhsub${p}.u16 $Vdn, $Vm", + (VHSUBuv8i16 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhsub${p}.u32 $Vdn, $Vm", + (VHSUBuv4i32 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; + + +// Two-operand variants for VHADD. + // Signed. +def : NEONInstAlias<"vhadd${p}.s8 $Vdn, $Vm", + (VHADDsv8i8 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhadd${p}.s16 $Vdn, $Vm", + (VHADDsv4i16 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhadd${p}.s32 $Vdn, $Vm", + (VHADDsv2i32 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; + +def : NEONInstAlias<"vhadd${p}.s8 $Vdn, $Vm", + (VHADDsv16i8 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhadd${p}.s16 $Vdn, $Vm", + (VHADDsv8i16 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhadd${p}.s32 $Vdn, $Vm", + (VHADDsv4i32 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; + + // Unsigned. +def : NEONInstAlias<"vhadd${p}.u8 $Vdn, $Vm", + (VHADDuv8i8 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhadd${p}.u16 $Vdn, $Vm", + (VHADDuv4i16 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhadd${p}.u32 $Vdn, $Vm", + (VHADDuv2i32 DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; + +def : NEONInstAlias<"vhadd${p}.u8 $Vdn, $Vm", + (VHADDuv16i8 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhadd${p}.u16 $Vdn, $Vm", + (VHADDuv8i16 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; +def : NEONInstAlias<"vhadd${p}.u32 $Vdn, $Vm", + (VHADDuv4i32 QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; + +// Two-operand variants for VRHADD. + // Signed. +def : NEONInstAlias<"vrhadd${p}.s8 $Vdn, $Rm", + (VRHADDsv8i8 DPR:$Vdn, DPR:$Vdn, DPR:$Rm, pred:$p)>; +def : NEONInstAlias<"vrhadd${p}.s16 $Vdn, $Rm", + (VRHADDsv4i16 DPR:$Vdn, DPR:$Vdn, DPR:$Rm, pred:$p)>; +def : NEONInstAlias<"vrhadd${p}.s32 $Vdn, $Rm", + (VRHADDsv2i32 DPR:$Vdn, DPR:$Vdn, DPR:$Rm, pred:$p)>; + +def : NEONInstAlias<"vrhadd${p}.s8 $Vdn, $Rm", + (VRHADDsv16i8 QPR:$Vdn, QPR:$Vdn, QPR:$Rm, pred:$p)>; +def : NEONInstAlias<"vrhadd${p}.s16 $Vdn, $Rm", + (VRHADDsv8i16 QPR:$Vdn, QPR:$Vdn, QPR:$Rm, pred:$p)>; +def : NEONInstAlias<"vrhadd${p}.s32 $Vdn, $Rm", + (VRHADDsv4i32 QPR:$Vdn, QPR:$Vdn, QPR:$Rm, pred:$p)>; + + // Unsigned. +def : NEONInstAlias<"vrhadd${p}.u8 $Vdn, $Rm", + (VRHADDuv8i8 DPR:$Vdn, DPR:$Vdn, DPR:$Rm, pred:$p)>; +def : NEONInstAlias<"vrhadd${p}.u16 $Vdn, $Rm", + (VRHADDuv4i16 DPR:$Vdn, DPR:$Vdn, DPR:$Rm, pred:$p)>; +def : NEONInstAlias<"vrhadd${p}.u32 $Vdn, $Rm", + (VRHADDuv2i32 DPR:$Vdn, DPR:$Vdn, DPR:$Rm, pred:$p)>; + +def : NEONInstAlias<"vrhadd${p}.u8 $Vdn, $Rm", + (VRHADDuv16i8 QPR:$Vdn, QPR:$Vdn, QPR:$Rm, pred:$p)>; +def : NEONInstAlias<"vrhadd${p}.u16 $Vdn, $Rm", + (VRHADDuv8i16 QPR:$Vdn, QPR:$Vdn, QPR:$Rm, pred:$p)>; +def : NEONInstAlias<"vrhadd${p}.u32 $Vdn, $Rm", + (VRHADDuv4i32 QPR:$Vdn, QPR:$Vdn, QPR:$Rm, pred:$p)>; + // VSWP allows, but does not require, a type suffix. defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm", (VSWPd DPR:$Vd, DPR:$Vm, pred:$p)>; diff --git a/contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp index 047efc2..9aa8308 100644 --- a/contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -136,22 +136,22 @@ TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) { bool ARMPassConfig::addPreISel() { if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge) - PM.add(createGlobalMergePass(TM->getTargetLowering())); + PM->add(createGlobalMergePass(TM->getTargetLowering())); return false; } bool ARMPassConfig::addInstSelector() { - PM.add(createARMISelDag(getARMTargetMachine(), getOptLevel())); + PM->add(createARMISelDag(getARMTargetMachine(), getOptLevel())); return false; } bool ARMPassConfig::addPreRegAlloc() { // FIXME: temporarily disabling load / store optimization pass for Thumb1. if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only()) - PM.add(createARMLoadStoreOptimizationPass(true)); + PM->add(createARMLoadStoreOptimizationPass(true)); if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9()) - PM.add(createMLxExpansionPass()); + PM->add(createMLxExpansionPass()); return true; } @@ -159,23 +159,23 @@ bool ARMPassConfig::addPreSched2() { // FIXME: temporarily disabling load / store optimization pass for Thumb1. if (getOptLevel() != CodeGenOpt::None) { if (!getARMSubtarget().isThumb1Only()) { - PM.add(createARMLoadStoreOptimizationPass()); + PM->add(createARMLoadStoreOptimizationPass()); printAndVerify("After ARM load / store optimizer"); } if (getARMSubtarget().hasNEON()) - PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass)); + PM->add(createExecutionDependencyFixPass(&ARM::DPRRegClass)); } // Expand some pseudo instructions into multiple instructions to allow // proper scheduling. - PM.add(createARMExpandPseudoPass()); + PM->add(createARMExpandPseudoPass()); if (getOptLevel() != CodeGenOpt::None) { if (!getARMSubtarget().isThumb1Only()) addPass(IfConverterID); } if (getARMSubtarget().isThumb2()) - PM.add(createThumb2ITBlockPass()); + PM->add(createThumb2ITBlockPass()); return true; } @@ -183,13 +183,13 @@ bool ARMPassConfig::addPreSched2() { bool ARMPassConfig::addPreEmitPass() { if (getARMSubtarget().isThumb2()) { if (!getARMSubtarget().prefers32BitThumb()) - PM.add(createThumb2SizeReductionPass()); + PM->add(createThumb2SizeReductionPass()); // Constant island pass work on unbundled instructions. addPass(UnpackMachineBundlesID); } - PM.add(createARMConstantIslandPass()); + PM->add(createARMConstantIslandPass()); return true; } diff --git a/contrib/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/contrib/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index e55a7da..2c53e3f 100644 --- a/contrib/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/contrib/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -82,8 +82,14 @@ class ARMAsmParser : public MCTargetAsmParser { MCAsmParser &getParser() const { return Parser; } MCAsmLexer &getLexer() const { return Parser.getLexer(); } - void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } - bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } + bool Warning(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) { + return Parser.Warning(L, Msg, Ranges); + } + bool Error(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) { + return Parser.Error(L, Msg, Ranges); + } int tryParseRegister(); bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); @@ -478,6 +484,8 @@ public: /// getEndLoc - Get the location of the last token of this operand. SMLoc getEndLoc() const { return EndLoc; } + SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } + ARMCC::CondCodes getCondCode() const { assert(Kind == k_CondCode && "Invalid access!"); return CC.Val; @@ -4518,22 +4526,26 @@ bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, case AsmToken::Dollar: case AsmToken::Hash: { // #42 -> immediate. - // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate S = Parser.getTok().getLoc(); Parser.Lex(); - bool isNegative = Parser.getTok().is(AsmToken::Minus); - const MCExpr *ImmVal; - if (getParser().ParseExpression(ImmVal)) - return true; - const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); - if (CE) { - int32_t Val = CE->getValue(); - if (isNegative && Val == 0) - ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); + + if (Parser.getTok().isNot(AsmToken::Colon)) { + bool isNegative = Parser.getTok().is(AsmToken::Minus); + const MCExpr *ImmVal; + if (getParser().ParseExpression(ImmVal)) + return true; + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); + if (CE) { + int32_t Val = CE->getValue(); + if (isNegative && Val == 0) + ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); + } + E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); + return false; } - E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); - return false; + // w/ a ':' after the '#', it's just like a plain ':'. + // FALLTHROUGH } case AsmToken::Colon: { // ":lower16:" and ":upper16:" expression prefixes @@ -7321,7 +7333,8 @@ MatchAndEmitInstruction(SMLoc IDLoc, return Error(ErrorLoc, "invalid operand for instruction"); } case Match_MnemonicFail: - return Error(IDLoc, "invalid instruction"); + return Error(IDLoc, "invalid instruction", + ((ARMOperand*)Operands[0])->getLocRange()); case Match_ConversionFail: // The converter function will have already emited a diagnostic. return true; diff --git a/contrib/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/contrib/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 2f504b7..912935d 100644 --- a/contrib/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/contrib/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -326,6 +326,8 @@ static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val, static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); #include "ARMGenDisassemblerTables.inc" #include "ARMGenInstrInfo.inc" #include "ARMGenEDInfo.inc" @@ -2690,7 +2692,6 @@ static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn, unsigned Rm = fieldFromInstruction32(Insn, 0, 4); unsigned align = fieldFromInstruction32(Insn, 4, 1); unsigned size = 1 << fieldFromInstruction32(Insn, 6, 2); - unsigned pred = fieldFromInstruction32(Insn, 22, 4); align *= 2*size; switch (Inst.getOpcode()) { @@ -2721,16 +2722,11 @@ static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn, return MCDisassembler::Fail; Inst.addOperand(MCOperand::CreateImm(align)); - if (Rm == 0xD) - Inst.addOperand(MCOperand::CreateReg(0)); - else if (Rm != 0xF) { + if (Rm != 0xD && Rm != 0xF) { if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) return MCDisassembler::Fail; } - if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) - return MCDisassembler::Fail; - return S; } @@ -4314,6 +4310,10 @@ static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, return DecodeCPSInstruction(Inst, Insn, Address, Decoder); DecodeStatus S = MCDisassembler::Success; + + if (Rt == Rn || Rn == Rt2) + S = MCDisassembler::SoftFail; + if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) return MCDisassembler::Fail; if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) @@ -4409,3 +4409,31 @@ static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, return S; } +static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder) { + + DecodeStatus S = MCDisassembler::Success; + + unsigned CRm = fieldFromInstruction32(Val, 0, 4); + unsigned opc1 = fieldFromInstruction32(Val, 4, 4); + unsigned cop = fieldFromInstruction32(Val, 8, 4); + unsigned Rt = fieldFromInstruction32(Val, 12, 4); + unsigned Rt2 = fieldFromInstruction32(Val, 16, 4); + + if ((cop & ~0x1) == 0xa) + return MCDisassembler::Fail; + + if (Rt == Rt2) + S = MCDisassembler::SoftFail; + + Inst.addOperand(MCOperand::CreateImm(cop)); + Inst.addOperand(MCOperand::CreateImm(opc1)); + if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::CreateImm(CRm)); + + return S; +} + diff --git a/contrib/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/contrib/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index b3eeafe..cbd81c1 100644 --- a/contrib/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/contrib/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -209,12 +209,12 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, } else { assert(Op.isExpr() && "unknown operand kind in printOperand"); // If a symbolic branch target was added as a constant expression then print - // that address in hex. + // that address in hex. And only print 32 unsigned bits for the address. const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr()); int64_t Address; if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) { O << "0x"; - O.write_hex(Address); + O.write_hex((uint32_t)Address); } else { // Otherwise, just print the expression. diff --git a/contrib/llvm/lib/Target/CellSPU/SPUCallingConv.td b/contrib/llvm/lib/Target/CellSPU/SPUCallingConv.td index 9f9692b..9bc6be7 100644 --- a/contrib/llvm/lib/Target/CellSPU/SPUCallingConv.td +++ b/contrib/llvm/lib/Target/CellSPU/SPUCallingConv.td @@ -11,10 +11,6 @@ // //===----------------------------------------------------------------------===// -/// CCIfSubtarget - Match if the current subtarget has a feature F. -class CCIfSubtarget<string F, CCAction A> - : CCIf<!strconcat("State.getTarget().getSubtarget<PPCSubtarget>().", F), A>; - //===----------------------------------------------------------------------===// // Return Value Calling Convention //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/Target/CellSPU/SPUTargetMachine.cpp b/contrib/llvm/lib/Target/CellSPU/SPUTargetMachine.cpp index 21f6b25..3b90261 100644 --- a/contrib/llvm/lib/Target/CellSPU/SPUTargetMachine.cpp +++ b/contrib/llvm/lib/Target/CellSPU/SPUTargetMachine.cpp @@ -72,7 +72,7 @@ TargetPassConfig *SPUTargetMachine::createPassConfig(PassManagerBase &PM) { bool SPUPassConfig::addInstSelector() { // Install an instruction selector. - PM.add(createSPUISelDag(getSPUTargetMachine())); + PM->add(createSPUISelDag(getSPUTargetMachine())); return false; } @@ -85,9 +85,9 @@ bool SPUPassConfig::addPreEmitPass() { (BuilderFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol( "createTCESchedulerPass"); if (schedulerCreator != NULL) - PM.add(schedulerCreator("cellspu")); + PM->add(schedulerCreator("cellspu")); //align instructions with nops/lnops for dual issue - PM.add(createSPUNopFillerPass(getSPUTargetMachine())); + PM->add(createSPUNopFillerPass(getSPUTargetMachine())); return true; } diff --git a/contrib/llvm/lib/Target/Hexagon/Hexagon.h b/contrib/llvm/lib/Target/Hexagon/Hexagon.h index 43858b9..0808323 100644 --- a/contrib/llvm/lib/Target/Hexagon/Hexagon.h +++ b/contrib/llvm/lib/Target/Hexagon/Hexagon.h @@ -40,7 +40,6 @@ namespace llvm { FunctionPass *createHexagonHardwareLoops(); FunctionPass *createHexagonPeephole(); FunctionPass *createHexagonFixupHwLoops(); - FunctionPass *createHexagonPacketizer(); /* TODO: object output. MCCodeEmitter *createHexagonMCCodeEmitter(const Target &, diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 2cc8b81..39bf45d 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -13,11 +13,11 @@ // //===----------------------------------------------------------------------===// + #define DEBUG_TYPE "asm-printer" #include "Hexagon.h" #include "HexagonAsmPrinter.h" #include "HexagonMachineFunctionInfo.h" -#include "HexagonMCInst.h" #include "HexagonTargetMachine.h" #include "HexagonSubtarget.h" #include "InstPrinter/HexagonInstPrinter.h" @@ -54,7 +54,6 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" -#include <map> using namespace llvm; @@ -78,7 +77,8 @@ void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, const MachineOperand &MO = MI->getOperand(OpNo); switch (MO.getType()) { - default: llvm_unreachable("<unknown operand type>"); + default: + assert(0 && "<unknown operand type>"); case MachineOperand::MO_Register: O << HexagonInstPrinter::getRegisterName(MO.getReg()); return; @@ -196,45 +196,10 @@ void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI, /// the current output stream. /// void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { - if (MI->isBundle()) { - std::vector<const MachineInstr*> BundleMIs; - - const MachineBasicBlock *MBB = MI->getParent(); - MachineBasicBlock::const_instr_iterator MII = MI; - ++MII; - unsigned int IgnoreCount = 0; - while (MII != MBB->end() && MII->isInsideBundle()) { - const MachineInstr *MInst = MII; - if (MInst->getOpcode() == TargetOpcode::DBG_VALUE || - MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) { - IgnoreCount++; - ++MII; - continue; - } - //BundleMIs.push_back(&*MII); - BundleMIs.push_back(MInst); - ++MII; - } - unsigned Size = BundleMIs.size(); - assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!"); - for (unsigned Index = 0; Index < Size; Index++) { - HexagonMCInst MCI; - MCI.setStartPacket(Index == 0); - MCI.setEndPacket(Index == (Size-1)); - - HexagonLowerToMC(BundleMIs[Index], MCI, *this); - OutStreamer.EmitInstruction(MCI); - } - } - else { - HexagonMCInst MCI; - if (MI->getOpcode() == Hexagon::ENDLOOP0) { - MCI.setStartPacket(true); - MCI.setEndPacket(true); - } - HexagonLowerToMC(MI, MCI, *this); - OutStreamer.EmitInstruction(MCI); - } + MCInst MCI; + + HexagonLowerToMC(MI, MCI, *this); + OutStreamer.EmitInstruction(MCI); return; } @@ -277,17 +242,17 @@ void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo, raw_ostream &O) { const MachineOperand &MO = MI->getOperand(OpNo); assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) && - "Expecting jump table index"); + "Expecting jump table index"); // Hexagon_TODO: Do we need name mangling? O << *GetJTISymbol(MO.getIndex()); } void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo, - raw_ostream &O) { + raw_ostream &O) { const MachineOperand &MO = MI->getOperand(OpNo); assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) && - "Expecting constant pool index"); + "Expecting constant pool index"); // Hexagon_TODO: Do we need name mangling? O << *GetCPISymbol(MO.getIndex()); diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index d6da0d0..8c4350d 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -32,9 +32,11 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/CommandLine.h" +#include "llvm/Support/raw_ostream.h" + using namespace llvm; const unsigned Hexagon_MAX_RET_SIZE = 64; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormats.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormats.td index 48f0f01..c9f16fb 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormats.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormats.td @@ -13,26 +13,13 @@ // *** Must match HexagonBaseInfo.h *** //===----------------------------------------------------------------------===// -class Type<bits<5> t> { - bits<5> Value = t; -} -def TypePSEUDO : Type<0>; -def TypeALU32 : Type<1>; -def TypeCR : Type<2>; -def TypeJR : Type<3>; -def TypeJ : Type<4>; -def TypeLD : Type<5>; -def TypeST : Type<6>; -def TypeSYSTEM : Type<7>; -def TypeXTYPE : Type<8>; -def TypeMARKER : Type<31>; //===----------------------------------------------------------------------===// // Intruction Class Declaration + //===----------------------------------------------------------------------===// class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, - string cstr, InstrItinClass itin, Type type> : Instruction { + string cstr, InstrItinClass itin> : Instruction { field bits<32> Inst; let Namespace = "Hexagon"; @@ -44,15 +31,11 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, let Constraints = cstr; let Itinerary = itin; - // *** Must match HexagonBaseInfo.h *** - Type HexagonType = type; - let TSFlags{4-0} = HexagonType.Value; - bits<1> isHexagonSolo = 0; - let TSFlags{5} = isHexagonSolo; + // *** The code below must match HexagonBaseInfo.h *** // Predicated instructions. bits<1> isPredicated = 0; - let TSFlags{6} = isPredicated; + let TSFlags{1} = isPredicated; // *** The code above must match HexagonBaseInfo.h *** } @@ -64,40 +47,28 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, // LD Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class LDInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", LD, TypeLD> { + : InstHexagon<outs, ins, asmstr, pattern, "", LD> { bits<5> rd; bits<5> rs; bits<13> imm13; - let mayLoad = 1; } // LD Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class LDInstPost<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, LD, TypeLD> { + : InstHexagon<outs, ins, asmstr, pattern, cstr, LD> { bits<5> rd; bits<5> rs; bits<5> rt; bits<13> imm13; - let mayLoad = 1; } // ST Instruction Class in V2/V3 can take SLOT0 only. // ST Instruction Class in V4 can take SLOT0 & SLOT1. // Definition of the instruction class CHANGED from V2/V3 to V4. class STInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", ST, TypeST> { - bits<5> rd; - bits<5> rs; - bits<13> imm13; - let mayStore = 1; -} - -// SYSTEM Instruction Class in V4 can take SLOT0 only -// In V2/V3 we used ST for this but in v4 ST can take SLOT0 or SLOT1. -class SYSInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", SYS, TypeSYSTEM> { + : InstHexagon<outs, ins, asmstr, pattern, "", ST> { bits<5> rd; bits<5> rs; bits<13> imm13; @@ -108,18 +79,17 @@ class SYSInst<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class CHANGED from V2/V3 to V4. class STInstPost<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, ST, TypeST> { + : InstHexagon<outs, ins, asmstr, pattern, cstr, ST> { bits<5> rd; bits<5> rs; bits<5> rt; bits<13> imm13; - let mayStore = 1; } // ALU32 Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class ALU32Type<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", ALU32, TypeALU32> { + : InstHexagon<outs, ins, asmstr, pattern, "", ALU32> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -132,17 +102,7 @@ class ALU32Type<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from ALU64 to XTYPE from V2/V3 to V4. class ALU64Type<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", ALU64, TypeXTYPE> { - bits<5> rd; - bits<5> rs; - bits<5> rt; - bits<16> imm16; - bits<16> imm16_2; -} - -class ALU64_acc<dag outs, dag ins, string asmstr, list<dag> pattern, - string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, ALU64, TypeXTYPE> { + : InstHexagon<outs, ins, asmstr, pattern, "", ALU64> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -155,7 +115,7 @@ class ALU64_acc<dag outs, dag ins, string asmstr, list<dag> pattern, // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from M to XTYPE from V2/V3 to V4. class MInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", M, TypeXTYPE> { + : InstHexagon<outs, ins, asmstr, pattern, "", M> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -166,8 +126,8 @@ class MInst<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from M to XTYPE from V2/V3 to V4. class MInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern, - string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, M, TypeXTYPE> { + string cstr> + : InstHexagon<outs, ins, asmstr, pattern, cstr, M> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -178,7 +138,9 @@ class MInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern, // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from S to XTYPE from V2/V3 to V4. class SInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", S, TypeXTYPE> { +//: InstHexagon<outs, ins, asmstr, pattern, cstr, !if(V4T, XTYPE_V4, M)> { + : InstHexagon<outs, ins, asmstr, pattern, "", S> { +// : InstHexagon<outs, ins, asmstr, pattern, "", S> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -189,8 +151,8 @@ class SInst<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from S to XTYPE from V2/V3 to V4. class SInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern, - string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, S, TypeXTYPE> { + string cstr> + : InstHexagon<outs, ins, asmstr, pattern, cstr, S> { // : InstHexagon<outs, ins, asmstr, pattern, cstr, S> { // : InstHexagon<outs, ins, asmstr, pattern, cstr, !if(V4T, XTYPE_V4, S)> { bits<5> rd; @@ -201,14 +163,14 @@ class SInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern, // J Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class JType<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", J, TypeJ> { + : InstHexagon<outs, ins, asmstr, pattern, "", J> { bits<16> imm16; } // JR Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class JRType<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", JR, TypeJR> { + : InstHexagon<outs, ins, asmstr, pattern, "", JR> { bits<5> rs; bits<5> pu; // Predicate register } @@ -216,22 +178,15 @@ class JRType<dag outs, dag ins, string asmstr, list<dag> pattern> // CR Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class CRInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", CR, TypeCR> { + : InstHexagon<outs, ins, asmstr, pattern, "", CR> { bits<5> rs; bits<10> imm10; } -class Marker<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", MARKER, TypeMARKER> { - let isCodeGenOnly = 1; - let isPseudo = 1; -} class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", PSEUDO, TypePSEUDO> { - let isCodeGenOnly = 1; - let isPseudo = 1; -} + : InstHexagon<outs, ins, asmstr, pattern, "", PSEUDO>; + //===----------------------------------------------------------------------===// // Intruction Classes Definitions - @@ -267,11 +222,6 @@ class ALU64_rr<dag outs, dag ins, string asmstr, list<dag> pattern> : ALU64Type<outs, ins, asmstr, pattern> { } -class ALU64_ri<dag outs, dag ins, string asmstr, list<dag> pattern> - : ALU64Type<outs, ins, asmstr, pattern> { - let rt{0-4} = 0; -} - // J Type Instructions. class JInst<dag outs, dag ins, string asmstr, list<dag> pattern> : JType<outs, ins, asmstr, pattern> { @@ -287,14 +237,12 @@ class JRInst<dag outs, dag ins, string asmstr, list<dag> pattern> class STInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> : STInstPost<outs, ins, asmstr, pattern, cstr> { let rt{0-4} = 0; - let mayStore = 1; } // Post increment LD Instruction. class LDInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> : LDInstPost<outs, ins, asmstr, pattern, cstr> { let rt{0-4} = 0; - let mayLoad = 1; } //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td index 49741a3..bd5e449 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td @@ -11,25 +11,11 @@ // //===----------------------------------------------------------------------===// -//----------------------------------------------------------------------------// -// Hexagon Intruction Flags + -// -// *** Must match BaseInfo.h *** -//----------------------------------------------------------------------------// - -def TypeMEMOP : Type<9>; -def TypeNV : Type<10>; -def TypePREFIX : Type<30>; - -//----------------------------------------------------------------------------// -// Intruction Classes Definitions + -//----------------------------------------------------------------------------// - // // NV type instructions. // class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", NV_V4, TypeNV> { + : InstHexagon<outs, ins, asmstr, pattern, "", NV_V4> { bits<5> rd; bits<5> rs; bits<13> imm13; @@ -38,7 +24,7 @@ class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of Post increment new value store. class NVInstPost_V4<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, NV_V4, TypeNV> { + : InstHexagon<outs, ins, asmstr, pattern, cstr, NV_V4> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -53,15 +39,8 @@ class NVInstPI_V4<dag outs, dag ins, string asmstr, list<dag> pattern, } class MEMInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", MEM_V4, TypeMEMOP> { + : InstHexagon<outs, ins, asmstr, pattern, "", MEM_V4> { bits<5> rd; bits<5> rs; bits<6> imm6; } - -class Immext<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", PREFIX, TypePREFIX> { - let isCodeGenOnly = 1; - - bits<26> imm26; -} diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 8685ec1..77b3663 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// +#include "Hexagon.h" #include "HexagonInstrInfo.h" #include "HexagonRegisterInfo.h" #include "HexagonSubtarget.h" -#include "Hexagon.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/DFAPacketizer.h" @@ -466,865 +466,7 @@ unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const { return NewReg; } -bool HexagonInstrInfo::isExtendable(const MachineInstr *MI) const { - switch(MI->getOpcode()) { - // JMP_EQri - case Hexagon::JMP_EQriPt_nv_V4: - case Hexagon::JMP_EQriPnt_nv_V4: - case Hexagon::JMP_EQriNotPt_nv_V4: - case Hexagon::JMP_EQriNotPnt_nv_V4: - - // JMP_EQri - with -1 - case Hexagon::JMP_EQriPtneg_nv_V4: - case Hexagon::JMP_EQriPntneg_nv_V4: - case Hexagon::JMP_EQriNotPtneg_nv_V4: - case Hexagon::JMP_EQriNotPntneg_nv_V4: - - // JMP_EQrr - case Hexagon::JMP_EQrrPt_nv_V4: - case Hexagon::JMP_EQrrPnt_nv_V4: - case Hexagon::JMP_EQrrNotPt_nv_V4: - case Hexagon::JMP_EQrrNotPnt_nv_V4: - - // JMP_GTri - case Hexagon::JMP_GTriPt_nv_V4: - case Hexagon::JMP_GTriPnt_nv_V4: - case Hexagon::JMP_GTriNotPt_nv_V4: - case Hexagon::JMP_GTriNotPnt_nv_V4: - - // JMP_GTri - with -1 - case Hexagon::JMP_GTriPtneg_nv_V4: - case Hexagon::JMP_GTriPntneg_nv_V4: - case Hexagon::JMP_GTriNotPtneg_nv_V4: - case Hexagon::JMP_GTriNotPntneg_nv_V4: - - // JMP_GTrr - case Hexagon::JMP_GTrrPt_nv_V4: - case Hexagon::JMP_GTrrPnt_nv_V4: - case Hexagon::JMP_GTrrNotPt_nv_V4: - case Hexagon::JMP_GTrrNotPnt_nv_V4: - - // JMP_GTrrdn - case Hexagon::JMP_GTrrdnPt_nv_V4: - case Hexagon::JMP_GTrrdnPnt_nv_V4: - case Hexagon::JMP_GTrrdnNotPt_nv_V4: - case Hexagon::JMP_GTrrdnNotPnt_nv_V4: - - // JMP_GTUri - case Hexagon::JMP_GTUriPt_nv_V4: - case Hexagon::JMP_GTUriPnt_nv_V4: - case Hexagon::JMP_GTUriNotPt_nv_V4: - case Hexagon::JMP_GTUriNotPnt_nv_V4: - - // JMP_GTUrr - case Hexagon::JMP_GTUrrPt_nv_V4: - case Hexagon::JMP_GTUrrPnt_nv_V4: - case Hexagon::JMP_GTUrrNotPt_nv_V4: - case Hexagon::JMP_GTUrrNotPnt_nv_V4: - - // JMP_GTUrrdn - case Hexagon::JMP_GTUrrdnPt_nv_V4: - case Hexagon::JMP_GTUrrdnPnt_nv_V4: - case Hexagon::JMP_GTUrrdnNotPt_nv_V4: - case Hexagon::JMP_GTUrrdnNotPnt_nv_V4: - return true; - - // TFR_FI - case Hexagon::TFR_FI: - return true; - - - default: - return false; - } - return false; -} - -bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const { - switch(MI->getOpcode()) { - // JMP_EQri - case Hexagon::JMP_EQriPt_ie_nv_V4: - case Hexagon::JMP_EQriPnt_ie_nv_V4: - case Hexagon::JMP_EQriNotPt_ie_nv_V4: - case Hexagon::JMP_EQriNotPnt_ie_nv_V4: - - // JMP_EQri - with -1 - case Hexagon::JMP_EQriPtneg_ie_nv_V4: - case Hexagon::JMP_EQriPntneg_ie_nv_V4: - case Hexagon::JMP_EQriNotPtneg_ie_nv_V4: - case Hexagon::JMP_EQriNotPntneg_ie_nv_V4: - - // JMP_EQrr - case Hexagon::JMP_EQrrPt_ie_nv_V4: - case Hexagon::JMP_EQrrPnt_ie_nv_V4: - case Hexagon::JMP_EQrrNotPt_ie_nv_V4: - case Hexagon::JMP_EQrrNotPnt_ie_nv_V4: - - // JMP_GTri - case Hexagon::JMP_GTriPt_ie_nv_V4: - case Hexagon::JMP_GTriPnt_ie_nv_V4: - case Hexagon::JMP_GTriNotPt_ie_nv_V4: - case Hexagon::JMP_GTriNotPnt_ie_nv_V4: - - // JMP_GTri - with -1 - case Hexagon::JMP_GTriPtneg_ie_nv_V4: - case Hexagon::JMP_GTriPntneg_ie_nv_V4: - case Hexagon::JMP_GTriNotPtneg_ie_nv_V4: - case Hexagon::JMP_GTriNotPntneg_ie_nv_V4: - - // JMP_GTrr - case Hexagon::JMP_GTrrPt_ie_nv_V4: - case Hexagon::JMP_GTrrPnt_ie_nv_V4: - case Hexagon::JMP_GTrrNotPt_ie_nv_V4: - case Hexagon::JMP_GTrrNotPnt_ie_nv_V4: - - // JMP_GTrrdn - case Hexagon::JMP_GTrrdnPt_ie_nv_V4: - case Hexagon::JMP_GTrrdnPnt_ie_nv_V4: - case Hexagon::JMP_GTrrdnNotPt_ie_nv_V4: - case Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4: - - // JMP_GTUri - case Hexagon::JMP_GTUriPt_ie_nv_V4: - case Hexagon::JMP_GTUriPnt_ie_nv_V4: - case Hexagon::JMP_GTUriNotPt_ie_nv_V4: - case Hexagon::JMP_GTUriNotPnt_ie_nv_V4: - - // JMP_GTUrr - case Hexagon::JMP_GTUrrPt_ie_nv_V4: - case Hexagon::JMP_GTUrrPnt_ie_nv_V4: - case Hexagon::JMP_GTUrrNotPt_ie_nv_V4: - case Hexagon::JMP_GTUrrNotPnt_ie_nv_V4: - - // JMP_GTUrrdn - case Hexagon::JMP_GTUrrdnPt_ie_nv_V4: - case Hexagon::JMP_GTUrrdnPnt_ie_nv_V4: - case Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4: - case Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4: - - // V4 absolute set addressing. - case Hexagon::LDrid_abs_setimm_V4: - case Hexagon::LDriw_abs_setimm_V4: - case Hexagon::LDrih_abs_setimm_V4: - case Hexagon::LDrib_abs_setimm_V4: - case Hexagon::LDriuh_abs_setimm_V4: - case Hexagon::LDriub_abs_setimm_V4: - - case Hexagon::STrid_abs_setimm_V4: - case Hexagon::STrib_abs_setimm_V4: - case Hexagon::STrih_abs_setimm_V4: - case Hexagon::STriw_abs_setimm_V4: - - // V4 global address load. - case Hexagon::LDrid_GP_cPt_V4 : - case Hexagon::LDrid_GP_cNotPt_V4 : - case Hexagon::LDrid_GP_cdnPt_V4 : - case Hexagon::LDrid_GP_cdnNotPt_V4 : - case Hexagon::LDrib_GP_cPt_V4 : - case Hexagon::LDrib_GP_cNotPt_V4 : - case Hexagon::LDrib_GP_cdnPt_V4 : - case Hexagon::LDrib_GP_cdnNotPt_V4 : - case Hexagon::LDriub_GP_cPt_V4 : - case Hexagon::LDriub_GP_cNotPt_V4 : - case Hexagon::LDriub_GP_cdnPt_V4 : - case Hexagon::LDriub_GP_cdnNotPt_V4 : - case Hexagon::LDrih_GP_cPt_V4 : - case Hexagon::LDrih_GP_cNotPt_V4 : - case Hexagon::LDrih_GP_cdnPt_V4 : - case Hexagon::LDrih_GP_cdnNotPt_V4 : - case Hexagon::LDriuh_GP_cPt_V4 : - case Hexagon::LDriuh_GP_cNotPt_V4 : - case Hexagon::LDriuh_GP_cdnPt_V4 : - case Hexagon::LDriuh_GP_cdnNotPt_V4 : - case Hexagon::LDriw_GP_cPt_V4 : - case Hexagon::LDriw_GP_cNotPt_V4 : - case Hexagon::LDriw_GP_cdnPt_V4 : - case Hexagon::LDriw_GP_cdnNotPt_V4 : - case Hexagon::LDd_GP_cPt_V4 : - case Hexagon::LDd_GP_cNotPt_V4 : - case Hexagon::LDd_GP_cdnPt_V4 : - case Hexagon::LDd_GP_cdnNotPt_V4 : - case Hexagon::LDb_GP_cPt_V4 : - case Hexagon::LDb_GP_cNotPt_V4 : - case Hexagon::LDb_GP_cdnPt_V4 : - case Hexagon::LDb_GP_cdnNotPt_V4 : - case Hexagon::LDub_GP_cPt_V4 : - case Hexagon::LDub_GP_cNotPt_V4 : - case Hexagon::LDub_GP_cdnPt_V4 : - case Hexagon::LDub_GP_cdnNotPt_V4 : - case Hexagon::LDh_GP_cPt_V4 : - case Hexagon::LDh_GP_cNotPt_V4 : - case Hexagon::LDh_GP_cdnPt_V4 : - case Hexagon::LDh_GP_cdnNotPt_V4 : - case Hexagon::LDuh_GP_cPt_V4 : - case Hexagon::LDuh_GP_cNotPt_V4 : - case Hexagon::LDuh_GP_cdnPt_V4 : - case Hexagon::LDuh_GP_cdnNotPt_V4 : - case Hexagon::LDw_GP_cPt_V4 : - case Hexagon::LDw_GP_cNotPt_V4 : - case Hexagon::LDw_GP_cdnPt_V4 : - case Hexagon::LDw_GP_cdnNotPt_V4 : - - // V4 global address store. - case Hexagon::STrid_GP_cPt_V4 : - case Hexagon::STrid_GP_cNotPt_V4 : - case Hexagon::STrid_GP_cdnPt_V4 : - case Hexagon::STrid_GP_cdnNotPt_V4 : - case Hexagon::STrib_GP_cPt_V4 : - case Hexagon::STrib_GP_cNotPt_V4 : - case Hexagon::STrib_GP_cdnPt_V4 : - case Hexagon::STrib_GP_cdnNotPt_V4 : - case Hexagon::STrih_GP_cPt_V4 : - case Hexagon::STrih_GP_cNotPt_V4 : - case Hexagon::STrih_GP_cdnPt_V4 : - case Hexagon::STrih_GP_cdnNotPt_V4 : - case Hexagon::STriw_GP_cPt_V4 : - case Hexagon::STriw_GP_cNotPt_V4 : - case Hexagon::STriw_GP_cdnPt_V4 : - case Hexagon::STriw_GP_cdnNotPt_V4 : - case Hexagon::STd_GP_cPt_V4 : - case Hexagon::STd_GP_cNotPt_V4 : - case Hexagon::STd_GP_cdnPt_V4 : - case Hexagon::STd_GP_cdnNotPt_V4 : - case Hexagon::STb_GP_cPt_V4 : - case Hexagon::STb_GP_cNotPt_V4 : - case Hexagon::STb_GP_cdnPt_V4 : - case Hexagon::STb_GP_cdnNotPt_V4 : - case Hexagon::STh_GP_cPt_V4 : - case Hexagon::STh_GP_cNotPt_V4 : - case Hexagon::STh_GP_cdnPt_V4 : - case Hexagon::STh_GP_cdnNotPt_V4 : - case Hexagon::STw_GP_cPt_V4 : - case Hexagon::STw_GP_cNotPt_V4 : - case Hexagon::STw_GP_cdnPt_V4 : - case Hexagon::STw_GP_cdnNotPt_V4 : - - // V4 predicated global address new value store. - case Hexagon::STrib_GP_cPt_nv_V4 : - case Hexagon::STrib_GP_cNotPt_nv_V4 : - case Hexagon::STrib_GP_cdnPt_nv_V4 : - case Hexagon::STrib_GP_cdnNotPt_nv_V4 : - case Hexagon::STrih_GP_cPt_nv_V4 : - case Hexagon::STrih_GP_cNotPt_nv_V4 : - case Hexagon::STrih_GP_cdnPt_nv_V4 : - case Hexagon::STrih_GP_cdnNotPt_nv_V4 : - case Hexagon::STriw_GP_cPt_nv_V4 : - case Hexagon::STriw_GP_cNotPt_nv_V4 : - case Hexagon::STriw_GP_cdnPt_nv_V4 : - case Hexagon::STriw_GP_cdnNotPt_nv_V4 : - case Hexagon::STb_GP_cPt_nv_V4 : - case Hexagon::STb_GP_cNotPt_nv_V4 : - case Hexagon::STb_GP_cdnPt_nv_V4 : - case Hexagon::STb_GP_cdnNotPt_nv_V4 : - case Hexagon::STh_GP_cPt_nv_V4 : - case Hexagon::STh_GP_cNotPt_nv_V4 : - case Hexagon::STh_GP_cdnPt_nv_V4 : - case Hexagon::STh_GP_cdnNotPt_nv_V4 : - case Hexagon::STw_GP_cPt_nv_V4 : - case Hexagon::STw_GP_cNotPt_nv_V4 : - case Hexagon::STw_GP_cdnPt_nv_V4 : - case Hexagon::STw_GP_cdnNotPt_nv_V4 : - - // TFR_FI - case Hexagon::TFR_FI_immext_V4: - return true; - - default: - return false; - } - return false; -} - -bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const { - switch (MI->getOpcode()) { - // JMP_EQri - case Hexagon::JMP_EQriPt_nv_V4: - case Hexagon::JMP_EQriPnt_nv_V4: - case Hexagon::JMP_EQriNotPt_nv_V4: - case Hexagon::JMP_EQriNotPnt_nv_V4: - case Hexagon::JMP_EQriPt_ie_nv_V4: - case Hexagon::JMP_EQriPnt_ie_nv_V4: - case Hexagon::JMP_EQriNotPt_ie_nv_V4: - case Hexagon::JMP_EQriNotPnt_ie_nv_V4: - - // JMP_EQri - with -1 - case Hexagon::JMP_EQriPtneg_nv_V4: - case Hexagon::JMP_EQriPntneg_nv_V4: - case Hexagon::JMP_EQriNotPtneg_nv_V4: - case Hexagon::JMP_EQriNotPntneg_nv_V4: - case Hexagon::JMP_EQriPtneg_ie_nv_V4: - case Hexagon::JMP_EQriPntneg_ie_nv_V4: - case Hexagon::JMP_EQriNotPtneg_ie_nv_V4: - case Hexagon::JMP_EQriNotPntneg_ie_nv_V4: - - // JMP_EQrr - case Hexagon::JMP_EQrrPt_nv_V4: - case Hexagon::JMP_EQrrPnt_nv_V4: - case Hexagon::JMP_EQrrNotPt_nv_V4: - case Hexagon::JMP_EQrrNotPnt_nv_V4: - case Hexagon::JMP_EQrrPt_ie_nv_V4: - case Hexagon::JMP_EQrrPnt_ie_nv_V4: - case Hexagon::JMP_EQrrNotPt_ie_nv_V4: - case Hexagon::JMP_EQrrNotPnt_ie_nv_V4: - - // JMP_GTri - case Hexagon::JMP_GTriPt_nv_V4: - case Hexagon::JMP_GTriPnt_nv_V4: - case Hexagon::JMP_GTriNotPt_nv_V4: - case Hexagon::JMP_GTriNotPnt_nv_V4: - case Hexagon::JMP_GTriPt_ie_nv_V4: - case Hexagon::JMP_GTriPnt_ie_nv_V4: - case Hexagon::JMP_GTriNotPt_ie_nv_V4: - case Hexagon::JMP_GTriNotPnt_ie_nv_V4: - - // JMP_GTri - with -1 - case Hexagon::JMP_GTriPtneg_nv_V4: - case Hexagon::JMP_GTriPntneg_nv_V4: - case Hexagon::JMP_GTriNotPtneg_nv_V4: - case Hexagon::JMP_GTriNotPntneg_nv_V4: - case Hexagon::JMP_GTriPtneg_ie_nv_V4: - case Hexagon::JMP_GTriPntneg_ie_nv_V4: - case Hexagon::JMP_GTriNotPtneg_ie_nv_V4: - case Hexagon::JMP_GTriNotPntneg_ie_nv_V4: - - // JMP_GTrr - case Hexagon::JMP_GTrrPt_nv_V4: - case Hexagon::JMP_GTrrPnt_nv_V4: - case Hexagon::JMP_GTrrNotPt_nv_V4: - case Hexagon::JMP_GTrrNotPnt_nv_V4: - case Hexagon::JMP_GTrrPt_ie_nv_V4: - case Hexagon::JMP_GTrrPnt_ie_nv_V4: - case Hexagon::JMP_GTrrNotPt_ie_nv_V4: - case Hexagon::JMP_GTrrNotPnt_ie_nv_V4: - - // JMP_GTrrdn - case Hexagon::JMP_GTrrdnPt_nv_V4: - case Hexagon::JMP_GTrrdnPnt_nv_V4: - case Hexagon::JMP_GTrrdnNotPt_nv_V4: - case Hexagon::JMP_GTrrdnNotPnt_nv_V4: - case Hexagon::JMP_GTrrdnPt_ie_nv_V4: - case Hexagon::JMP_GTrrdnPnt_ie_nv_V4: - case Hexagon::JMP_GTrrdnNotPt_ie_nv_V4: - case Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4: - - // JMP_GTUri - case Hexagon::JMP_GTUriPt_nv_V4: - case Hexagon::JMP_GTUriPnt_nv_V4: - case Hexagon::JMP_GTUriNotPt_nv_V4: - case Hexagon::JMP_GTUriNotPnt_nv_V4: - case Hexagon::JMP_GTUriPt_ie_nv_V4: - case Hexagon::JMP_GTUriPnt_ie_nv_V4: - case Hexagon::JMP_GTUriNotPt_ie_nv_V4: - case Hexagon::JMP_GTUriNotPnt_ie_nv_V4: - - // JMP_GTUrr - case Hexagon::JMP_GTUrrPt_nv_V4: - case Hexagon::JMP_GTUrrPnt_nv_V4: - case Hexagon::JMP_GTUrrNotPt_nv_V4: - case Hexagon::JMP_GTUrrNotPnt_nv_V4: - case Hexagon::JMP_GTUrrPt_ie_nv_V4: - case Hexagon::JMP_GTUrrPnt_ie_nv_V4: - case Hexagon::JMP_GTUrrNotPt_ie_nv_V4: - case Hexagon::JMP_GTUrrNotPnt_ie_nv_V4: - - // JMP_GTUrrdn - case Hexagon::JMP_GTUrrdnPt_nv_V4: - case Hexagon::JMP_GTUrrdnPnt_nv_V4: - case Hexagon::JMP_GTUrrdnNotPt_nv_V4: - case Hexagon::JMP_GTUrrdnNotPnt_nv_V4: - case Hexagon::JMP_GTUrrdnPt_ie_nv_V4: - case Hexagon::JMP_GTUrrdnPnt_ie_nv_V4: - case Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4: - case Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4: - return true; - - default: - return false; - } - return false; -} - -unsigned HexagonInstrInfo::getImmExtForm(const MachineInstr* MI) const { - switch(MI->getOpcode()) { - default: llvm_unreachable("Unknown type of instruction"); - - // JMP_EQri - case Hexagon::JMP_EQriPt_nv_V4: - return Hexagon::JMP_EQriPt_ie_nv_V4; - case Hexagon::JMP_EQriNotPt_nv_V4: - return Hexagon::JMP_EQriNotPt_ie_nv_V4; - case Hexagon::JMP_EQriPnt_nv_V4: - return Hexagon::JMP_EQriPnt_ie_nv_V4; - case Hexagon::JMP_EQriNotPnt_nv_V4: - return Hexagon::JMP_EQriNotPnt_ie_nv_V4; - - // JMP_EQri -- with -1 - case Hexagon::JMP_EQriPtneg_nv_V4: - return Hexagon::JMP_EQriPtneg_ie_nv_V4; - case Hexagon::JMP_EQriNotPtneg_nv_V4: - return Hexagon::JMP_EQriNotPtneg_ie_nv_V4; - case Hexagon::JMP_EQriPntneg_nv_V4: - return Hexagon::JMP_EQriPntneg_ie_nv_V4; - case Hexagon::JMP_EQriNotPntneg_nv_V4: - return Hexagon::JMP_EQriNotPntneg_ie_nv_V4; - - // JMP_EQrr - case Hexagon::JMP_EQrrPt_nv_V4: - return Hexagon::JMP_EQrrPt_ie_nv_V4; - case Hexagon::JMP_EQrrNotPt_nv_V4: - return Hexagon::JMP_EQrrNotPt_ie_nv_V4; - case Hexagon::JMP_EQrrPnt_nv_V4: - return Hexagon::JMP_EQrrPnt_ie_nv_V4; - case Hexagon::JMP_EQrrNotPnt_nv_V4: - return Hexagon::JMP_EQrrNotPnt_ie_nv_V4; - - // JMP_GTri - case Hexagon::JMP_GTriPt_nv_V4: - return Hexagon::JMP_GTriPt_ie_nv_V4; - case Hexagon::JMP_GTriNotPt_nv_V4: - return Hexagon::JMP_GTriNotPt_ie_nv_V4; - case Hexagon::JMP_GTriPnt_nv_V4: - return Hexagon::JMP_GTriPnt_ie_nv_V4; - case Hexagon::JMP_GTriNotPnt_nv_V4: - return Hexagon::JMP_GTriNotPnt_ie_nv_V4; - - // JMP_GTri -- with -1 - case Hexagon::JMP_GTriPtneg_nv_V4: - return Hexagon::JMP_GTriPtneg_ie_nv_V4; - case Hexagon::JMP_GTriNotPtneg_nv_V4: - return Hexagon::JMP_GTriNotPtneg_ie_nv_V4; - case Hexagon::JMP_GTriPntneg_nv_V4: - return Hexagon::JMP_GTriPntneg_ie_nv_V4; - case Hexagon::JMP_GTriNotPntneg_nv_V4: - return Hexagon::JMP_GTriNotPntneg_ie_nv_V4; - - // JMP_GTrr - case Hexagon::JMP_GTrrPt_nv_V4: - return Hexagon::JMP_GTrrPt_ie_nv_V4; - case Hexagon::JMP_GTrrNotPt_nv_V4: - return Hexagon::JMP_GTrrNotPt_ie_nv_V4; - case Hexagon::JMP_GTrrPnt_nv_V4: - return Hexagon::JMP_GTrrPnt_ie_nv_V4; - case Hexagon::JMP_GTrrNotPnt_nv_V4: - return Hexagon::JMP_GTrrNotPnt_ie_nv_V4; - - // JMP_GTrrdn - case Hexagon::JMP_GTrrdnPt_nv_V4: - return Hexagon::JMP_GTrrdnPt_ie_nv_V4; - case Hexagon::JMP_GTrrdnNotPt_nv_V4: - return Hexagon::JMP_GTrrdnNotPt_ie_nv_V4; - case Hexagon::JMP_GTrrdnPnt_nv_V4: - return Hexagon::JMP_GTrrdnPnt_ie_nv_V4; - case Hexagon::JMP_GTrrdnNotPnt_nv_V4: - return Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4; - - // JMP_GTUri - case Hexagon::JMP_GTUriPt_nv_V4: - return Hexagon::JMP_GTUriPt_ie_nv_V4; - case Hexagon::JMP_GTUriNotPt_nv_V4: - return Hexagon::JMP_GTUriNotPt_ie_nv_V4; - case Hexagon::JMP_GTUriPnt_nv_V4: - return Hexagon::JMP_GTUriPnt_ie_nv_V4; - case Hexagon::JMP_GTUriNotPnt_nv_V4: - return Hexagon::JMP_GTUriNotPnt_ie_nv_V4; - - // JMP_GTUrr - case Hexagon::JMP_GTUrrPt_nv_V4: - return Hexagon::JMP_GTUrrPt_ie_nv_V4; - case Hexagon::JMP_GTUrrNotPt_nv_V4: - return Hexagon::JMP_GTUrrNotPt_ie_nv_V4; - case Hexagon::JMP_GTUrrPnt_nv_V4: - return Hexagon::JMP_GTUrrPnt_ie_nv_V4; - case Hexagon::JMP_GTUrrNotPnt_nv_V4: - return Hexagon::JMP_GTUrrNotPnt_ie_nv_V4; - - // JMP_GTUrrdn - case Hexagon::JMP_GTUrrdnPt_nv_V4: - return Hexagon::JMP_GTUrrdnPt_ie_nv_V4; - case Hexagon::JMP_GTUrrdnNotPt_nv_V4: - return Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4; - case Hexagon::JMP_GTUrrdnPnt_nv_V4: - return Hexagon::JMP_GTUrrdnPnt_ie_nv_V4; - case Hexagon::JMP_GTUrrdnNotPnt_nv_V4: - return Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4; - case Hexagon::TFR_FI: - return Hexagon::TFR_FI_immext_V4; - - case Hexagon::MEMw_ADDSUBi_indexed_MEM_V4 : - case Hexagon::MEMw_ADDi_indexed_MEM_V4 : - case Hexagon::MEMw_SUBi_indexed_MEM_V4 : - case Hexagon::MEMw_ADDr_indexed_MEM_V4 : - case Hexagon::MEMw_SUBr_indexed_MEM_V4 : - case Hexagon::MEMw_ANDr_indexed_MEM_V4 : - case Hexagon::MEMw_ORr_indexed_MEM_V4 : - case Hexagon::MEMw_ADDSUBi_MEM_V4 : - case Hexagon::MEMw_ADDi_MEM_V4 : - case Hexagon::MEMw_SUBi_MEM_V4 : - case Hexagon::MEMw_ADDr_MEM_V4 : - case Hexagon::MEMw_SUBr_MEM_V4 : - case Hexagon::MEMw_ANDr_MEM_V4 : - case Hexagon::MEMw_ORr_MEM_V4 : - case Hexagon::MEMh_ADDSUBi_indexed_MEM_V4 : - case Hexagon::MEMh_ADDi_indexed_MEM_V4 : - case Hexagon::MEMh_SUBi_indexed_MEM_V4 : - case Hexagon::MEMh_ADDr_indexed_MEM_V4 : - case Hexagon::MEMh_SUBr_indexed_MEM_V4 : - case Hexagon::MEMh_ANDr_indexed_MEM_V4 : - case Hexagon::MEMh_ORr_indexed_MEM_V4 : - case Hexagon::MEMh_ADDSUBi_MEM_V4 : - case Hexagon::MEMh_ADDi_MEM_V4 : - case Hexagon::MEMh_SUBi_MEM_V4 : - case Hexagon::MEMh_ADDr_MEM_V4 : - case Hexagon::MEMh_SUBr_MEM_V4 : - case Hexagon::MEMh_ANDr_MEM_V4 : - case Hexagon::MEMh_ORr_MEM_V4 : - case Hexagon::MEMb_ADDSUBi_indexed_MEM_V4 : - case Hexagon::MEMb_ADDi_indexed_MEM_V4 : - case Hexagon::MEMb_SUBi_indexed_MEM_V4 : - case Hexagon::MEMb_ADDr_indexed_MEM_V4 : - case Hexagon::MEMb_SUBr_indexed_MEM_V4 : - case Hexagon::MEMb_ANDr_indexed_MEM_V4 : - case Hexagon::MEMb_ORr_indexed_MEM_V4 : - case Hexagon::MEMb_ADDSUBi_MEM_V4 : - case Hexagon::MEMb_ADDi_MEM_V4 : - case Hexagon::MEMb_SUBi_MEM_V4 : - case Hexagon::MEMb_ADDr_MEM_V4 : - case Hexagon::MEMb_SUBr_MEM_V4 : - case Hexagon::MEMb_ANDr_MEM_V4 : - case Hexagon::MEMb_ORr_MEM_V4 : - llvm_unreachable("Needs implementing"); - } -} - -unsigned HexagonInstrInfo::getNormalBranchForm(const MachineInstr* MI) const { - switch(MI->getOpcode()) { - default: llvm_unreachable("Unknown type of jump instruction"); - - // JMP_EQri - case Hexagon::JMP_EQriPt_ie_nv_V4: - return Hexagon::JMP_EQriPt_nv_V4; - case Hexagon::JMP_EQriNotPt_ie_nv_V4: - return Hexagon::JMP_EQriNotPt_nv_V4; - case Hexagon::JMP_EQriPnt_ie_nv_V4: - return Hexagon::JMP_EQriPnt_nv_V4; - case Hexagon::JMP_EQriNotPnt_ie_nv_V4: - return Hexagon::JMP_EQriNotPnt_nv_V4; - - // JMP_EQri -- with -1 - case Hexagon::JMP_EQriPtneg_ie_nv_V4: - return Hexagon::JMP_EQriPtneg_nv_V4; - case Hexagon::JMP_EQriNotPtneg_ie_nv_V4: - return Hexagon::JMP_EQriNotPtneg_nv_V4; - case Hexagon::JMP_EQriPntneg_ie_nv_V4: - return Hexagon::JMP_EQriPntneg_nv_V4; - case Hexagon::JMP_EQriNotPntneg_ie_nv_V4: - return Hexagon::JMP_EQriNotPntneg_nv_V4; - - // JMP_EQrr - case Hexagon::JMP_EQrrPt_ie_nv_V4: - return Hexagon::JMP_EQrrPt_nv_V4; - case Hexagon::JMP_EQrrNotPt_ie_nv_V4: - return Hexagon::JMP_EQrrNotPt_nv_V4; - case Hexagon::JMP_EQrrPnt_ie_nv_V4: - return Hexagon::JMP_EQrrPnt_nv_V4; - case Hexagon::JMP_EQrrNotPnt_ie_nv_V4: - return Hexagon::JMP_EQrrNotPnt_nv_V4; - - // JMP_GTri - case Hexagon::JMP_GTriPt_ie_nv_V4: - return Hexagon::JMP_GTriPt_nv_V4; - case Hexagon::JMP_GTriNotPt_ie_nv_V4: - return Hexagon::JMP_GTriNotPt_nv_V4; - case Hexagon::JMP_GTriPnt_ie_nv_V4: - return Hexagon::JMP_GTriPnt_nv_V4; - case Hexagon::JMP_GTriNotPnt_ie_nv_V4: - return Hexagon::JMP_GTriNotPnt_nv_V4; - - // JMP_GTri -- with -1 - case Hexagon::JMP_GTriPtneg_ie_nv_V4: - return Hexagon::JMP_GTriPtneg_nv_V4; - case Hexagon::JMP_GTriNotPtneg_ie_nv_V4: - return Hexagon::JMP_GTriNotPtneg_nv_V4; - case Hexagon::JMP_GTriPntneg_ie_nv_V4: - return Hexagon::JMP_GTriPntneg_nv_V4; - case Hexagon::JMP_GTriNotPntneg_ie_nv_V4: - return Hexagon::JMP_GTriNotPntneg_nv_V4; - - // JMP_GTrr - case Hexagon::JMP_GTrrPt_ie_nv_V4: - return Hexagon::JMP_GTrrPt_nv_V4; - case Hexagon::JMP_GTrrNotPt_ie_nv_V4: - return Hexagon::JMP_GTrrNotPt_nv_V4; - case Hexagon::JMP_GTrrPnt_ie_nv_V4: - return Hexagon::JMP_GTrrPnt_nv_V4; - case Hexagon::JMP_GTrrNotPnt_ie_nv_V4: - return Hexagon::JMP_GTrrNotPnt_nv_V4; - - // JMP_GTrrdn - case Hexagon::JMP_GTrrdnPt_ie_nv_V4: - return Hexagon::JMP_GTrrdnPt_nv_V4; - case Hexagon::JMP_GTrrdnNotPt_ie_nv_V4: - return Hexagon::JMP_GTrrdnNotPt_nv_V4; - case Hexagon::JMP_GTrrdnPnt_ie_nv_V4: - return Hexagon::JMP_GTrrdnPnt_nv_V4; - case Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4: - return Hexagon::JMP_GTrrdnNotPnt_nv_V4; - - // JMP_GTUri - case Hexagon::JMP_GTUriPt_ie_nv_V4: - return Hexagon::JMP_GTUriPt_nv_V4; - case Hexagon::JMP_GTUriNotPt_ie_nv_V4: - return Hexagon::JMP_GTUriNotPt_nv_V4; - case Hexagon::JMP_GTUriPnt_ie_nv_V4: - return Hexagon::JMP_GTUriPnt_nv_V4; - case Hexagon::JMP_GTUriNotPnt_ie_nv_V4: - return Hexagon::JMP_GTUriNotPnt_nv_V4; - - // JMP_GTUrr - case Hexagon::JMP_GTUrrPt_ie_nv_V4: - return Hexagon::JMP_GTUrrPt_nv_V4; - case Hexagon::JMP_GTUrrNotPt_ie_nv_V4: - return Hexagon::JMP_GTUrrNotPt_nv_V4; - case Hexagon::JMP_GTUrrPnt_ie_nv_V4: - return Hexagon::JMP_GTUrrPnt_nv_V4; - case Hexagon::JMP_GTUrrNotPnt_ie_nv_V4: - return Hexagon::JMP_GTUrrNotPnt_nv_V4; - - // JMP_GTUrrdn - case Hexagon::JMP_GTUrrdnPt_ie_nv_V4: - return Hexagon::JMP_GTUrrdnPt_nv_V4; - case Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4: - return Hexagon::JMP_GTUrrdnNotPt_nv_V4; - case Hexagon::JMP_GTUrrdnPnt_ie_nv_V4: - return Hexagon::JMP_GTUrrdnPnt_nv_V4; - case Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4: - return Hexagon::JMP_GTUrrdnNotPnt_nv_V4; - } -} - - -bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const { - switch (MI->getOpcode()) { - - // Store Byte - case Hexagon::STrib_nv_V4: - case Hexagon::STrib_indexed_nv_V4: - case Hexagon::STrib_indexed_shl_nv_V4: - case Hexagon::STrib_shl_nv_V4: - case Hexagon::STrib_GP_nv_V4: - case Hexagon::STb_GP_nv_V4: - case Hexagon::POST_STbri_nv_V4: - case Hexagon::STrib_cPt_nv_V4: - case Hexagon::STrib_cdnPt_nv_V4: - case Hexagon::STrib_cNotPt_nv_V4: - case Hexagon::STrib_cdnNotPt_nv_V4: - case Hexagon::STrib_indexed_cPt_nv_V4: - case Hexagon::STrib_indexed_cdnPt_nv_V4: - case Hexagon::STrib_indexed_cNotPt_nv_V4: - case Hexagon::STrib_indexed_cdnNotPt_nv_V4: - case Hexagon::STrib_indexed_shl_cPt_nv_V4: - case Hexagon::STrib_indexed_shl_cdnPt_nv_V4: - case Hexagon::STrib_indexed_shl_cNotPt_nv_V4: - case Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4: - case Hexagon::POST_STbri_cPt_nv_V4: - case Hexagon::POST_STbri_cdnPt_nv_V4: - case Hexagon::POST_STbri_cNotPt_nv_V4: - case Hexagon::POST_STbri_cdnNotPt_nv_V4: - case Hexagon::STb_GP_cPt_nv_V4: - case Hexagon::STb_GP_cNotPt_nv_V4: - case Hexagon::STb_GP_cdnPt_nv_V4: - case Hexagon::STb_GP_cdnNotPt_nv_V4: - case Hexagon::STrib_GP_cPt_nv_V4: - case Hexagon::STrib_GP_cNotPt_nv_V4: - case Hexagon::STrib_GP_cdnPt_nv_V4: - case Hexagon::STrib_GP_cdnNotPt_nv_V4: - case Hexagon::STrib_abs_nv_V4: - case Hexagon::STrib_abs_cPt_nv_V4: - case Hexagon::STrib_abs_cdnPt_nv_V4: - case Hexagon::STrib_abs_cNotPt_nv_V4: - case Hexagon::STrib_abs_cdnNotPt_nv_V4: - case Hexagon::STrib_imm_abs_nv_V4: - case Hexagon::STrib_imm_abs_cPt_nv_V4: - case Hexagon::STrib_imm_abs_cdnPt_nv_V4: - case Hexagon::STrib_imm_abs_cNotPt_nv_V4: - case Hexagon::STrib_imm_abs_cdnNotPt_nv_V4: - - // Store Halfword - case Hexagon::STrih_nv_V4: - case Hexagon::STrih_indexed_nv_V4: - case Hexagon::STrih_indexed_shl_nv_V4: - case Hexagon::STrih_shl_nv_V4: - case Hexagon::STrih_GP_nv_V4: - case Hexagon::STh_GP_nv_V4: - case Hexagon::POST_SThri_nv_V4: - case Hexagon::STrih_cPt_nv_V4: - case Hexagon::STrih_cdnPt_nv_V4: - case Hexagon::STrih_cNotPt_nv_V4: - case Hexagon::STrih_cdnNotPt_nv_V4: - case Hexagon::STrih_indexed_cPt_nv_V4: - case Hexagon::STrih_indexed_cdnPt_nv_V4: - case Hexagon::STrih_indexed_cNotPt_nv_V4: - case Hexagon::STrih_indexed_cdnNotPt_nv_V4: - case Hexagon::STrih_indexed_shl_cPt_nv_V4: - case Hexagon::STrih_indexed_shl_cdnPt_nv_V4: - case Hexagon::STrih_indexed_shl_cNotPt_nv_V4: - case Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4: - case Hexagon::POST_SThri_cPt_nv_V4: - case Hexagon::POST_SThri_cdnPt_nv_V4: - case Hexagon::POST_SThri_cNotPt_nv_V4: - case Hexagon::POST_SThri_cdnNotPt_nv_V4: - case Hexagon::STh_GP_cPt_nv_V4: - case Hexagon::STh_GP_cNotPt_nv_V4: - case Hexagon::STh_GP_cdnPt_nv_V4: - case Hexagon::STh_GP_cdnNotPt_nv_V4: - case Hexagon::STrih_GP_cPt_nv_V4: - case Hexagon::STrih_GP_cNotPt_nv_V4: - case Hexagon::STrih_GP_cdnPt_nv_V4: - case Hexagon::STrih_GP_cdnNotPt_nv_V4: - case Hexagon::STrih_abs_nv_V4: - case Hexagon::STrih_abs_cPt_nv_V4: - case Hexagon::STrih_abs_cdnPt_nv_V4: - case Hexagon::STrih_abs_cNotPt_nv_V4: - case Hexagon::STrih_abs_cdnNotPt_nv_V4: - case Hexagon::STrih_imm_abs_nv_V4: - case Hexagon::STrih_imm_abs_cPt_nv_V4: - case Hexagon::STrih_imm_abs_cdnPt_nv_V4: - case Hexagon::STrih_imm_abs_cNotPt_nv_V4: - case Hexagon::STrih_imm_abs_cdnNotPt_nv_V4: - - // Store Word - case Hexagon::STriw_nv_V4: - case Hexagon::STriw_indexed_nv_V4: - case Hexagon::STriw_indexed_shl_nv_V4: - case Hexagon::STriw_shl_nv_V4: - case Hexagon::STriw_GP_nv_V4: - case Hexagon::STw_GP_nv_V4: - case Hexagon::POST_STwri_nv_V4: - case Hexagon::STriw_cPt_nv_V4: - case Hexagon::STriw_cdnPt_nv_V4: - case Hexagon::STriw_cNotPt_nv_V4: - case Hexagon::STriw_cdnNotPt_nv_V4: - case Hexagon::STriw_indexed_cPt_nv_V4: - case Hexagon::STriw_indexed_cdnPt_nv_V4: - case Hexagon::STriw_indexed_cNotPt_nv_V4: - case Hexagon::STriw_indexed_cdnNotPt_nv_V4: - case Hexagon::STriw_indexed_shl_cPt_nv_V4: - case Hexagon::STriw_indexed_shl_cdnPt_nv_V4: - case Hexagon::STriw_indexed_shl_cNotPt_nv_V4: - case Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4: - case Hexagon::POST_STwri_cPt_nv_V4: - case Hexagon::POST_STwri_cdnPt_nv_V4: - case Hexagon::POST_STwri_cNotPt_nv_V4: - case Hexagon::POST_STwri_cdnNotPt_nv_V4: - case Hexagon::STw_GP_cPt_nv_V4: - case Hexagon::STw_GP_cNotPt_nv_V4: - case Hexagon::STw_GP_cdnPt_nv_V4: - case Hexagon::STw_GP_cdnNotPt_nv_V4: - case Hexagon::STriw_GP_cPt_nv_V4: - case Hexagon::STriw_GP_cNotPt_nv_V4: - case Hexagon::STriw_GP_cdnPt_nv_V4: - case Hexagon::STriw_GP_cdnNotPt_nv_V4: - case Hexagon::STriw_abs_nv_V4: - case Hexagon::STriw_abs_cPt_nv_V4: - case Hexagon::STriw_abs_cdnPt_nv_V4: - case Hexagon::STriw_abs_cNotPt_nv_V4: - case Hexagon::STriw_abs_cdnNotPt_nv_V4: - case Hexagon::STriw_imm_abs_nv_V4: - case Hexagon::STriw_imm_abs_cPt_nv_V4: - case Hexagon::STriw_imm_abs_cdnPt_nv_V4: - case Hexagon::STriw_imm_abs_cNotPt_nv_V4: - case Hexagon::STriw_imm_abs_cdnNotPt_nv_V4: - return true; - - default: - return false; - } - return false; -} - -bool HexagonInstrInfo::isPostIncrement (const MachineInstr* MI) const { - switch (MI->getOpcode()) - { - // Load Byte - case Hexagon::POST_LDrib: - case Hexagon::POST_LDrib_cPt: - case Hexagon::POST_LDrib_cNotPt: - case Hexagon::POST_LDrib_cdnPt_V4: - case Hexagon::POST_LDrib_cdnNotPt_V4: - - // Load unsigned byte - case Hexagon::POST_LDriub: - case Hexagon::POST_LDriub_cPt: - case Hexagon::POST_LDriub_cNotPt: - case Hexagon::POST_LDriub_cdnPt_V4: - case Hexagon::POST_LDriub_cdnNotPt_V4: - - // Load halfword - case Hexagon::POST_LDrih: - case Hexagon::POST_LDrih_cPt: - case Hexagon::POST_LDrih_cNotPt: - case Hexagon::POST_LDrih_cdnPt_V4: - case Hexagon::POST_LDrih_cdnNotPt_V4: - - // Load unsigned halfword - case Hexagon::POST_LDriuh: - case Hexagon::POST_LDriuh_cPt: - case Hexagon::POST_LDriuh_cNotPt: - case Hexagon::POST_LDriuh_cdnPt_V4: - case Hexagon::POST_LDriuh_cdnNotPt_V4: - - // Load word - case Hexagon::POST_LDriw: - case Hexagon::POST_LDriw_cPt: - case Hexagon::POST_LDriw_cNotPt: - case Hexagon::POST_LDriw_cdnPt_V4: - case Hexagon::POST_LDriw_cdnNotPt_V4: - - // Load double word - case Hexagon::POST_LDrid: - case Hexagon::POST_LDrid_cPt: - case Hexagon::POST_LDrid_cNotPt: - case Hexagon::POST_LDrid_cdnPt_V4: - case Hexagon::POST_LDrid_cdnNotPt_V4: - - // Store byte - case Hexagon::POST_STbri: - case Hexagon::POST_STbri_cPt: - case Hexagon::POST_STbri_cNotPt: - case Hexagon::POST_STbri_cdnPt_V4: - case Hexagon::POST_STbri_cdnNotPt_V4: - - // Store halfword - case Hexagon::POST_SThri: - case Hexagon::POST_SThri_cPt: - case Hexagon::POST_SThri_cNotPt: - case Hexagon::POST_SThri_cdnPt_V4: - case Hexagon::POST_SThri_cdnNotPt_V4: - - // Store word - case Hexagon::POST_STwri: - case Hexagon::POST_STwri_cPt: - case Hexagon::POST_STwri_cNotPt: - case Hexagon::POST_STwri_cdnPt_V4: - case Hexagon::POST_STwri_cdnNotPt_V4: - - // Store double word - case Hexagon::POST_STdri: - case Hexagon::POST_STdri_cPt: - case Hexagon::POST_STdri_cNotPt: - case Hexagon::POST_STdri_cdnPt_V4: - case Hexagon::POST_STdri_cdnNotPt_V4: - return true; - - default: - return false; - } -} - -bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr *MI) const { - return MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4; -} bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const { bool isPred = MI->getDesc().isPredicable(); @@ -2445,24 +1587,6 @@ isSpillPredRegOp(const MachineInstr *MI) const { return false; } -bool HexagonInstrInfo:: -isConditionalTransfer (const MachineInstr *MI) const { - switch (MI->getOpcode()) { - case Hexagon::TFR_cPt: - case Hexagon::TFR_cNotPt: - case Hexagon::TFRI_cPt: - case Hexagon::TFRI_cNotPt: - case Hexagon::TFR_cdnPt: - case Hexagon::TFR_cdnNotPt: - case Hexagon::TFRI_cdnPt: - case Hexagon::TFRI_cdnNotPt: - return true; - - default: - return false; - } - return false; -} bool HexagonInstrInfo::isConditionalALU32 (const MachineInstr* MI) const { const HexagonRegisterInfo& QRI = getRegisterInfo(); @@ -2502,6 +1626,7 @@ bool HexagonInstrInfo::isConditionalALU32 (const MachineInstr* MI) const { } } + bool HexagonInstrInfo:: isConditionalLoad (const MachineInstr* MI) const { const HexagonRegisterInfo& QRI = getRegisterInfo(); @@ -2575,136 +1700,6 @@ isConditionalLoad (const MachineInstr* MI) const { } } -// Returns true if an instruction is a conditional store. -// -// Note: It doesn't include conditional new-value stores as they can't be -// converted to .new predicate. -// -// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ] -// ^ ^ -// / \ (not OK. it will cause new-value store to be -// / X conditional on p0.new while R2 producer is -// / \ on p0) -// / \. -// p.new store p.old NV store -// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new] -// ^ ^ -// \ / -// \ / -// \ / -// p.old store -// [if (p0)memw(R0+#0)=R2] -// -// The above diagram shows the steps involoved in the conversion of a predicated -// store instruction to its .new predicated new-value form. -// -// The following set of instructions further explains the scenario where -// conditional new-value store becomes invalid when promoted to .new predicate -// form. -// -// { 1) if (p0) r0 = add(r1, r2) -// 2) p0 = cmp.eq(r3, #0) } -// -// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with -// the first two instructions because in instr 1, r0 is conditional on old value -// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which -// is not valid for new-value stores. -bool HexagonInstrInfo:: -isConditionalStore (const MachineInstr* MI) const { - const HexagonRegisterInfo& QRI = getRegisterInfo(); - switch (MI->getOpcode()) - { - case Hexagon::STrib_imm_cPt_V4 : - case Hexagon::STrib_imm_cNotPt_V4 : - case Hexagon::STrib_indexed_shl_cPt_V4 : - case Hexagon::STrib_indexed_shl_cNotPt_V4 : - case Hexagon::STrib_cPt : - case Hexagon::STrib_cNotPt : - case Hexagon::POST_STbri_cPt : - case Hexagon::POST_STbri_cNotPt : - case Hexagon::STrid_indexed_cPt : - case Hexagon::STrid_indexed_cNotPt : - case Hexagon::STrid_indexed_shl_cPt_V4 : - case Hexagon::POST_STdri_cPt : - case Hexagon::POST_STdri_cNotPt : - case Hexagon::STrih_cPt : - case Hexagon::STrih_cNotPt : - case Hexagon::STrih_indexed_cPt : - case Hexagon::STrih_indexed_cNotPt : - case Hexagon::STrih_imm_cPt_V4 : - case Hexagon::STrih_imm_cNotPt_V4 : - case Hexagon::STrih_indexed_shl_cPt_V4 : - case Hexagon::STrih_indexed_shl_cNotPt_V4 : - case Hexagon::POST_SThri_cPt : - case Hexagon::POST_SThri_cNotPt : - case Hexagon::STriw_cPt : - case Hexagon::STriw_cNotPt : - case Hexagon::STriw_indexed_cPt : - case Hexagon::STriw_indexed_cNotPt : - case Hexagon::STriw_imm_cPt_V4 : - case Hexagon::STriw_imm_cNotPt_V4 : - case Hexagon::STriw_indexed_shl_cPt_V4 : - case Hexagon::STriw_indexed_shl_cNotPt_V4 : - case Hexagon::POST_STwri_cPt : - case Hexagon::POST_STwri_cNotPt : - return QRI.Subtarget.hasV4TOps(); - - // V4 global address store before promoting to dot new. - case Hexagon::STrid_GP_cPt_V4 : - case Hexagon::STrid_GP_cNotPt_V4 : - case Hexagon::STrib_GP_cPt_V4 : - case Hexagon::STrib_GP_cNotPt_V4 : - case Hexagon::STrih_GP_cPt_V4 : - case Hexagon::STrih_GP_cNotPt_V4 : - case Hexagon::STriw_GP_cPt_V4 : - case Hexagon::STriw_GP_cNotPt_V4 : - case Hexagon::STd_GP_cPt_V4 : - case Hexagon::STd_GP_cNotPt_V4 : - case Hexagon::STb_GP_cPt_V4 : - case Hexagon::STb_GP_cNotPt_V4 : - case Hexagon::STh_GP_cPt_V4 : - case Hexagon::STh_GP_cNotPt_V4 : - case Hexagon::STw_GP_cPt_V4 : - case Hexagon::STw_GP_cNotPt_V4 : - return QRI.Subtarget.hasV4TOps(); - - // Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded - // from the "Conditional Store" list. Because a predicated new value store - // would NOT be promoted to a double dot new store. See diagram below: - // This function returns yes for those stores that are predicated but not - // yet promoted to predicate dot new instructions. - // - // +---------------------+ - // /-----| if (p0) memw(..)=r0 |---------\~ - // || +---------------------+ || - // promote || /\ /\ || promote - // || /||\ /||\ || - // \||/ demote || \||/ - // \/ || || \/ - // +-------------------------+ || +-------------------------+ - // | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new | - // +-------------------------+ || +-------------------------+ - // || || || - // || demote \||/ - // promote || \/ NOT possible - // || || /\~ - // \||/ || /||\~ - // \/ || || - // +-----------------------------+ - // | if (p0.new) memw(..)=r0.new | - // +-----------------------------+ - // Double Dot New Store - // - - default: - return false; - - } - return false; -} - - - DFAPacketizer *HexagonInstrInfo:: CreateTargetScheduleState(const TargetMachine *TM, const ScheduleDAG *DAG) const { diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h index 6a45871..7306870 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h @@ -160,20 +160,10 @@ public: bool isS8_Immediate(const int value) const; bool isS6_Immediate(const int value) const; - bool isSaveCalleeSavedRegsCall(const MachineInstr* MI) const; - bool isConditionalTransfer(const MachineInstr* MI) const; bool isConditionalALU32 (const MachineInstr* MI) const; bool isConditionalLoad (const MachineInstr* MI) const; - bool isConditionalStore(const MachineInstr* MI) const; bool isDeallocRet(const MachineInstr *MI) const; unsigned getInvertedPredicatedOpcode(const int Opc) const; - bool isExtendable(const MachineInstr* MI) const; - bool isExtended(const MachineInstr* MI) const; - bool isPostIncrement(const MachineInstr* MI) const; - bool isNewValueStore(const MachineInstr* MI) const; - bool isNewValueJump(const MachineInstr* MI) const; - unsigned getImmExtForm(const MachineInstr* MI) const; - unsigned getNormalBranchForm(const MachineInstr* MI) const; private: int getMatchingCondBranchOpcode(int Opc, bool sense) const; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index fd5adef..b563ac3 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -3046,7 +3046,3 @@ include "HexagonInstrInfoV3.td" //===----------------------------------------------------------------------===// include "HexagonInstrInfoV4.td" - -//===----------------------------------------------------------------------===// -// V4 Instructions - -//===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td index 2bd6770..a73897e 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td @@ -41,11 +41,10 @@ let isCall = 1, neverHasSideEffects = 1, } -// Jump to address from register // if(p?.new) jumpr:t r? let isReturn = 1, isTerminator = 1, isBarrier = 1, Defs = [PC], Uses = [R31] in { - def JMPR_cdnPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2), + def JMPR_cPnewt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) jumpr:t $src2", []>, Requires<[HasV3T]>; } @@ -53,7 +52,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, // if (!p?.new) jumpr:t r? let isReturn = 1, isTerminator = 1, isBarrier = 1, Defs = [PC], Uses = [R31] in { - def JMPR_cdnNotPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2), + def JMPR_cNotPnewt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) jumpr:t $src2", []>, Requires<[HasV3T]>; } @@ -62,7 +61,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, // if(p?.new) jumpr:nt r? let isReturn = 1, isTerminator = 1, isBarrier = 1, Defs = [PC], Uses = [R31] in { - def JMPR_cdnPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2), + def JMPR_cPnewNt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) jumpr:nt $src2", []>, Requires<[HasV3T]>; } @@ -70,7 +69,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, // if (!p?.new) jumpr:nt r? let isReturn = 1, isTerminator = 1, isBarrier = 1, Defs = [PC], Uses = [R31] in { - def JMPR_cdnNotPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2), + def JMPR_cNotPnewNt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) jumpr:nt $src2", []>, Requires<[HasV3T]>; } @@ -87,22 +86,20 @@ let AddedComplexity = 200 in def MAXw_dd : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = max($src2, $src1)", - [(set (i64 DoubleRegs:$dst), - (i64 (select (i1 (setlt (i64 DoubleRegs:$src2), - (i64 DoubleRegs:$src1))), - (i64 DoubleRegs:$src1), - (i64 DoubleRegs:$src2))))]>, + [(set DoubleRegs:$dst, (select (i1 (setlt DoubleRegs:$src2, + DoubleRegs:$src1)), + DoubleRegs:$src1, + DoubleRegs:$src2))]>, Requires<[HasV3T]>; let AddedComplexity = 200 in def MINw_dd : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = min($src2, $src1)", - [(set (i64 DoubleRegs:$dst), - (i64 (select (i1 (setgt (i64 DoubleRegs:$src2), - (i64 DoubleRegs:$src1))), - (i64 DoubleRegs:$src1), - (i64 DoubleRegs:$src2))))]>, + [(set DoubleRegs:$dst, (select (i1 (setgt DoubleRegs:$src2, + DoubleRegs:$src1)), + DoubleRegs:$src1, + DoubleRegs:$src2))]>, Requires<[HasV3T]>; //===----------------------------------------------------------------------===// @@ -112,25 +109,25 @@ Requires<[HasV3T]>; -//def : Pat <(brcond (i1 (seteq (i32 IntRegs:$src1), 0)), bb:$offset), -// (JMP_RegEzt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>; +//def : Pat <(brcond (i1 (seteq IntRegs:$src1, 0)), bb:$offset), +// (JMP_RegEzt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>; -//def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), 0)), bb:$offset), -// (JMP_RegNzt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>; +//def : Pat <(brcond (i1 (setne IntRegs:$src1, 0)), bb:$offset), +// (JMP_RegNzt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>; -//def : Pat <(brcond (i1 (setle (i32 IntRegs:$src1), 0)), bb:$offset), -// (JMP_RegLezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>; +//def : Pat <(brcond (i1 (setle IntRegs:$src1, 0)), bb:$offset), +// (JMP_RegLezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>; -//def : Pat <(brcond (i1 (setge (i32 IntRegs:$src1), 0)), bb:$offset), -// (JMP_RegGezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>; +//def : Pat <(brcond (i1 (setge IntRegs:$src1, 0)), bb:$offset), +// (JMP_RegGezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>; -//def : Pat <(brcond (i1 (setgt (i32 IntRegs:$src1), -1)), bb:$offset), -// (JMP_RegGezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>; +//def : Pat <(brcond (i1 (setgt IntRegs:$src1, -1)), bb:$offset), +// (JMP_RegGezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>; // Map call instruction -def : Pat<(call (i32 IntRegs:$dst)), - (CALLRv3 (i32 IntRegs:$dst))>, Requires<[HasV3T]>; +def : Pat<(call IntRegs:$dst), + (CALLRv3 IntRegs:$dst)>, Requires<[HasV3T]>; def : Pat<(call tglobaladdr:$dst), (CALLv3 tglobaladdr:$dst)>, Requires<[HasV3T]>; def : Pat<(call texternalsym:$dst), diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td index f507e4f..9e60cf2 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -11,11 +11,6 @@ // //===----------------------------------------------------------------------===// -def IMMEXT : Immext<(outs), (ins), - "##immext //should never emit this", - []>, - Requires<[HasV4T]>; - // Hexagon V4 Architecture spec defines 8 instruction classes: // LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the // compiler) @@ -255,151 +250,23 @@ def ZXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), []>, Requires<[HasV4T]>; -// Generate frame index addresses. -let neverHasSideEffects = 1, isReMaterializable = 1 in -def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins IntRegs:$src1, s32Imm:$offset), - "$dst = add($src1, ##$offset)", - []>, - Requires<[HasV4T]>; - //===----------------------------------------------------------------------===// // ALU32 - //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// ALU32/PERM + -//===----------------------------------------------------------------------===// - -// Combine -// Rdd=combine(Rs, #s8) -let neverHasSideEffects = 1 in -def COMBINE_ri_V4 : ALU32_ri<(outs DoubleRegs:$dst), - (ins IntRegs:$src1, s8Imm:$src2), - "$dst = combine($src1, #$src2)", - []>, - Requires<[HasV4T]>; -// Rdd=combine(#s8, Rs) -let neverHasSideEffects = 1 in -def COMBINE_ir_V4 : ALU32_ir<(outs DoubleRegs:$dst), - (ins s8Imm:$src1, IntRegs:$src2), - "$dst = combine(#$src1, $src2)", - []>, - Requires<[HasV4T]>; -//===----------------------------------------------------------------------===// -// ALU32/PERM + -//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // LD + //===----------------------------------------------------------------------===// -// -// These absolute set addressing mode instructions accept immediate as -// an operand. We have duplicated these patterns to take global address. - -let neverHasSideEffects = 1 in -def LDrid_abs_setimm_V4 : LDInst<(outs DoubleRegs:$dst1, IntRegs:$dst2), - (ins u6Imm:$addr), - "$dst1 = memd($dst2=#$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memb(Re=#U6) -let neverHasSideEffects = 1 in -def LDrib_abs_setimm_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins u6Imm:$addr), - "$dst1 = memb($dst2=#$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memh(Re=#U6) -let neverHasSideEffects = 1 in -def LDrih_abs_setimm_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins u6Imm:$addr), - "$dst1 = memh($dst2=#$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memub(Re=#U6) -let neverHasSideEffects = 1 in -def LDriub_abs_setimm_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins u6Imm:$addr), - "$dst1 = memub($dst2=#$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memuh(Re=#U6) -let neverHasSideEffects = 1 in -def LDriuh_abs_setimm_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins u6Imm:$addr), - "$dst1 = memuh($dst2=#$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memw(Re=#U6) -let neverHasSideEffects = 1 in -def LDriw_abs_setimm_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins u6Imm:$addr), - "$dst1 = memw($dst2=#$addr)", - []>, - Requires<[HasV4T]>; - -// Following patterns are defined for absolute set addressing mode -// instruction which take global address as operand. -let mayLoad = 1, neverHasSideEffects = 1 in -def LDrid_abs_set_V4 : LDInst<(outs DoubleRegs:$dst1, IntRegs:$dst2), - (ins globaladdress:$addr), - "$dst1 = memd($dst2=##$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memb(Re=#U6) -let mayLoad = 1, neverHasSideEffects = 1 in -def LDrib_abs_set_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins globaladdress:$addr), - "$dst1 = memb($dst2=##$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memh(Re=#U6) -let mayLoad = 1, neverHasSideEffects = 1 in -def LDrih_abs_set_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins globaladdress:$addr), - "$dst1 = memh($dst2=##$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memub(Re=#U6) -let mayLoad = 1, neverHasSideEffects = 1 in -def LDriub_abs_set_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins globaladdress:$addr), - "$dst1 = memub($dst2=##$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memuh(Re=#U6) -let mayLoad = 1, neverHasSideEffects = 1 in -def LDriuh_abs_set_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins globaladdress:$addr), - "$dst1 = memuh($dst2=##$addr)", - []>, - Requires<[HasV4T]>; - -// Rd=memw(Re=#U6) -let mayLoad = 1, neverHasSideEffects = 1 in -def LDriw_abs_set_V4 : LDInst<(outs IntRegs:$dst1, IntRegs:$dst2), - (ins globaladdress:$addr), - "$dst1 = memw($dst2=##$addr)", - []>, - Requires<[HasV4T]>; +/// +/// Make sure that in post increment load, the first operand is always the post +/// increment operand. +/// +//// Load doubleword. +// Rdd=memd(Re=#U6) -// Load doubleword. -// -// Make sure that in post increment load, the first operand is always the post -// increment operand. -// // Rdd=memd(Rs+Rt<<#u2) // Special case pattern for indexed load without offset which is easier to // match. AddedComplexity of this pattern should be lower than base+offset load @@ -409,19 +276,17 @@ let AddedComplexity = 10, isPredicable = 1 in def LDrid_indexed_V4 : LDInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst=memd($src1+$src2<<#0)", - [(set (i64 DoubleRegs:$dst), - (i64 (load (add (i32 IntRegs:$src1), - (i32 IntRegs:$src2)))))]>, + [(set DoubleRegs:$dst, (load (add IntRegs:$src1, + IntRegs:$src2)))]>, Requires<[HasV4T]>; let AddedComplexity = 40, isPredicable = 1 in def LDrid_indexed_shl_V4 : LDInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), "$dst=memd($src1+$src2<<#$offset)", - [(set (i64 DoubleRegs:$dst), - (i64 (load (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$offset)))))]>, + [(set DoubleRegs:$dst, (load (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$offset))))]>, Requires<[HasV4T]>; //// Load doubleword conditionally. @@ -497,62 +362,60 @@ def LDrid_indexed_shl_cdnNotPt_V4 : LDInst<(outs DoubleRegs:$dst), // Rdd=memd(Rt<<#u2+#U6) //// Load byte. +// Rd=memb(Re=#U6) + // Rd=memb(Rs+Rt<<#u2) let AddedComplexity = 10, isPredicable = 1 in def LDrib_indexed_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst=memb($src1+$src2<<#0)", - [(set (i32 IntRegs:$dst), - (i32 (sextloadi8 (add (i32 IntRegs:$src1), - (i32 IntRegs:$src2)))))]>, + [(set IntRegs:$dst, (sextloadi8 (add IntRegs:$src1, + IntRegs:$src2)))]>, Requires<[HasV4T]>; let AddedComplexity = 10, isPredicable = 1 in def LDriub_indexed_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst=memub($src1+$src2<<#0)", - [(set (i32 IntRegs:$dst), - (i32 (zextloadi8 (add (i32 IntRegs:$src1), - (i32 IntRegs:$src2)))))]>, + [(set IntRegs:$dst, (zextloadi8 (add IntRegs:$src1, + IntRegs:$src2)))]>, Requires<[HasV4T]>; let AddedComplexity = 10, isPredicable = 1 in def LDriub_ae_indexed_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst=memub($src1+$src2<<#0)", - [(set (i32 IntRegs:$dst), - (i32 (extloadi8 (add (i32 IntRegs:$src1), - (i32 IntRegs:$src2)))))]>, + [(set IntRegs:$dst, (extloadi8 (add IntRegs:$src1, + IntRegs:$src2)))]>, Requires<[HasV4T]>; let AddedComplexity = 40, isPredicable = 1 in def LDrib_indexed_shl_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), "$dst=memb($src1+$src2<<#$offset)", - [(set (i32 IntRegs:$dst), - (i32 (sextloadi8 (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$offset)))))]>, + [(set IntRegs:$dst, + (sextloadi8 (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$offset))))]>, Requires<[HasV4T]>; let AddedComplexity = 40, isPredicable = 1 in def LDriub_indexed_shl_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), "$dst=memub($src1+$src2<<#$offset)", - [(set (i32 IntRegs:$dst), - (i32 (zextloadi8 (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$offset)))))]>, + [(set IntRegs:$dst, + (zextloadi8 (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$offset))))]>, Requires<[HasV4T]>; let AddedComplexity = 40, isPredicable = 1 in def LDriub_ae_indexed_shl_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), "$dst=memub($src1+$src2<<#$offset)", - [(set (i32 IntRegs:$dst), - (i32 (extloadi8 (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$offset)))))]>, + [(set IntRegs:$dst, (extloadi8 (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$offset))))]>, Requires<[HasV4T]>; //// Load byte conditionally. @@ -698,32 +561,31 @@ def LDriub_indexed_shl_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), // Rd=memb(Rt<<#u2+#U6) //// Load halfword +// Rd=memh(Re=#U6) + // Rd=memh(Rs+Rt<<#u2) let AddedComplexity = 10, isPredicable = 1 in def LDrih_indexed_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst=memh($src1+$src2<<#0)", - [(set (i32 IntRegs:$dst), - (i32 (sextloadi16 (add (i32 IntRegs:$src1), - (i32 IntRegs:$src2)))))]>, + [(set IntRegs:$dst, (sextloadi16 (add IntRegs:$src1, + IntRegs:$src2)))]>, Requires<[HasV4T]>; let AddedComplexity = 10, isPredicable = 1 in def LDriuh_indexed_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst=memuh($src1+$src2<<#0)", - [(set (i32 IntRegs:$dst), - (i32 (zextloadi16 (add (i32 IntRegs:$src1), - (i32 IntRegs:$src2)))))]>, + [(set IntRegs:$dst, (zextloadi16 (add IntRegs:$src1, + IntRegs:$src2)))]>, Requires<[HasV4T]>; let AddedComplexity = 10, isPredicable = 1 in def LDriuh_ae_indexed_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst=memuh($src1+$src2<<#0)", - [(set (i32 IntRegs:$dst), - (i32 (extloadi16 (add (i32 IntRegs:$src1), - (i32 IntRegs:$src2)))))]>, + [(set IntRegs:$dst, (extloadi16 (add IntRegs:$src1, + IntRegs:$src2)))]>, Requires<[HasV4T]>; // Rd=memh(Rs+Rt<<#u2) @@ -731,30 +593,30 @@ let AddedComplexity = 40, isPredicable = 1 in def LDrih_indexed_shl_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), "$dst=memh($src1+$src2<<#$offset)", - [(set (i32 IntRegs:$dst), - (i32 (sextloadi16 (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$offset)))))]>, + [(set IntRegs:$dst, + (sextloadi16 (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$offset))))]>, Requires<[HasV4T]>; let AddedComplexity = 40, isPredicable = 1 in def LDriuh_indexed_shl_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), "$dst=memuh($src1+$src2<<#$offset)", - [(set (i32 IntRegs:$dst), - (i32 (zextloadi16 (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$offset)))))]>, + [(set IntRegs:$dst, + (zextloadi16 (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$offset))))]>, Requires<[HasV4T]>; let AddedComplexity = 40, isPredicable = 1 in def LDriuh_ae_indexed_shl_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), "$dst=memuh($src1+$src2<<#$offset)", - [(set (i32 IntRegs:$dst), - (i32 (extloadi16 (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$offset)))))]>, + [(set IntRegs:$dst, + (extloadi16 (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$offset))))]>, Requires<[HasV4T]>; //// Load halfword conditionally. @@ -900,14 +762,6 @@ def LDriuh_indexed_shl_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), // Rd=memh(Rt<<#u2+#U6) //// Load word. -// Load predicate: Fix for bug 5279. -let mayLoad = 1, neverHasSideEffects = 1 in -def LDriw_pred_V4 : LDInst<(outs PredRegs:$dst), - (ins MEMri:$addr), - "Error; should not emit", - []>, - Requires<[HasV4T]>; - // Rd=memw(Re=#U6) // Rd=memw(Rs+Rt<<#u2) @@ -915,9 +769,8 @@ let AddedComplexity = 10, isPredicable = 1 in def LDriw_indexed_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst=memw($src1+$src2<<#0)", - [(set (i32 IntRegs:$dst), - (i32 (load (add (i32 IntRegs:$src1), - (i32 IntRegs:$src2)))))]>, + [(set IntRegs:$dst, (load (add IntRegs:$src1, + IntRegs:$src2)))]>, Requires<[HasV4T]>; // Rd=memw(Rs+Rt<<#u2) @@ -925,10 +778,9 @@ let AddedComplexity = 40, isPredicable = 1 in def LDriw_indexed_shl_V4 : LDInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), "$dst=memw($src1+$src2<<#$offset)", - [(set (i32 IntRegs:$dst), - (i32 (load (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$offset)))))]>, + [(set IntRegs:$dst, (load (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$offset))))]>, Requires<[HasV4T]>; //// Load word conditionally. @@ -1103,633 +955,6 @@ def POST_LDriw_cdnNotPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), "$src2 = $dst2">, Requires<[HasV4T]>; -/// Load from global offset - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDrid_GP_V4 : LDInst<(outs DoubleRegs:$dst), - (ins globaladdress:$global, u16Imm:$offset), - "$dst=memd(#$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrid_GP_cPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1) $dst=memd(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrid_GP_cNotPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1) $dst=memd(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrid_GP_cdnPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1.new) $dst=memd(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrid_GP_cdnNotPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1.new) $dst=memd(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDrib_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global, u16Imm:$offset), - "$dst=memb(#$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrib_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1) $dst=memb(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrib_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1) $dst=memb(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrib_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1.new) $dst=memb(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrib_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1.new) $dst=memb(##$global+$offset)", - []>, - Requires<[HasV4T]>; - - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDriub_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global, u16Imm:$offset), - "$dst=memub(#$global+$offset)", - []>, - Requires<[HasV4T]>; - - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriub_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1) $dst=memub(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriub_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1) $dst=memub(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriub_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1.new) $dst=memub(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriub_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1.new) $dst=memub(##$global+$offset)", - []>, - Requires<[HasV4T]>; - - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDrih_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global, u16Imm:$offset), - "$dst=memh(#$global+$offset)", - []>, - Requires<[HasV4T]>; - - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrih_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1) $dst=memh(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrih_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1) $dst=memh(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrih_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1.new) $dst=memh(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDrih_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1.new) $dst=memh(##$global+$offset)", - []>, - Requires<[HasV4T]>; - - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDriuh_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global, u16Imm:$offset), - "$dst=memuh(#$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriuh_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1) $dst=memuh(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriuh_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1) $dst=memuh(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriuh_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1.new) $dst=memuh(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriuh_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1.new) $dst=memuh(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDriw_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global, u16Imm:$offset), - "$dst=memw(#$global+$offset)", - []>, - Requires<[HasV4T]>; - - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriw_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1) $dst=memw(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriw_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1) $dst=memw(##$global+$offset)", - []>, - Requires<[HasV4T]>; - - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriw_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if ($src1.new) $dst=memw(##$global+$offset)", - []>, - Requires<[HasV4T]>; - -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDriw_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset), - "if (!$src1.new) $dst=memw(##$global+$offset)", - []>, - Requires<[HasV4T]>; - - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDd_GP_V4 : LDInst<(outs DoubleRegs:$dst), - (ins globaladdress:$global), - "$dst=memd(#$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rtt=memd(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDd_GP_cPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1) $dst=memd(##$global)", - []>, - Requires<[HasV4T]>; - - -// if (!Pv) Rtt=memd(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDd_GP_cNotPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1) $dst=memd(##$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rtt=memd(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDd_GP_cdnPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1.new) $dst=memd(##$global)", - []>, - Requires<[HasV4T]>; - - -// if (!Pv) Rtt=memd(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDd_GP_cdnNotPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1.new) $dst=memd(##$global)", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDb_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global), - "$dst=memb(#$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memb(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDb_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1) $dst=memb(##$global)", - []>, - Requires<[HasV4T]>; - -// if (!Pv) Rt=memb(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDb_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1) $dst=memb(##$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memb(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDb_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1.new) $dst=memb(##$global)", - []>, - Requires<[HasV4T]>; - -// if (!Pv) Rt=memb(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDb_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1.new) $dst=memb(##$global)", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDub_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global), - "$dst=memub(#$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memub(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDub_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1) $dst=memub(##$global)", - []>, - Requires<[HasV4T]>; - - -// if (!Pv) Rt=memub(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDub_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1) $dst=memub(##$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memub(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDub_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1.new) $dst=memub(##$global)", - []>, - Requires<[HasV4T]>; - - -// if (!Pv) Rt=memub(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDub_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1.new) $dst=memub(##$global)", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDh_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global), - "$dst=memh(#$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memh(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDh_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1) $dst=memh(##$global)", - []>, - Requires<[HasV4T]>; - -// if (!Pv) Rt=memh(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDh_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1) $dst=memh(##$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memh(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDh_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1.new) $dst=memh(##$global)", - []>, - Requires<[HasV4T]>; - -// if (!Pv) Rt=memh(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDh_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1.new) $dst=memh(##$global)", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDuh_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global), - "$dst=memuh(#$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memuh(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDuh_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1) $dst=memuh(##$global)", - []>, - Requires<[HasV4T]>; - -// if (!Pv) Rt=memuh(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDuh_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1) $dst=memuh(##$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memuh(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDuh_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1.new) $dst=memuh(##$global)", - []>, - Requires<[HasV4T]>; - -// if (!Pv) Rt=memuh(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDuh_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1.new) $dst=memuh(##$global)", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayLoad = 1, neverHasSideEffects = 1 in -def LDw_GP_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$global), - "$dst=memw(#$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memw(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDw_GP_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1) $dst=memw(##$global)", - []>, - Requires<[HasV4T]>; - - -// if (!Pv) Rt=memw(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDw_GP_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1) $dst=memw(##$global)", - []>, - Requires<[HasV4T]>; - -// if (Pv) Rt=memw(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDw_GP_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if ($src1.new) $dst=memw(##$global)", - []>, - Requires<[HasV4T]>; - - -// if (!Pv) Rt=memw(##global) -let mayLoad = 1, neverHasSideEffects = 1, isPredicated = 1 in -def LDw_GP_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$global), - "if (!$src1.new) $dst=memw(##$global)", - []>, - Requires<[HasV4T]>; - - - -def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)), - (i64 (LDd_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)), - (i32 (LDw_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)), - (i32 (LDuh_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)), - (i32 (LDub_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress) -> memw(#foo + 0) -let AddedComplexity = 100 in -def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))), - (i64 (LDd_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd -let AddedComplexity = 100 in -def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))), - (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>, - Requires<[HasV4T]>; - -// When the Interprocedural Global Variable optimizer realizes that a certain -// global variable takes only two constant values, it shrinks the global to -// a boolean. Catch those loads here in the following 3 patterns. -let AddedComplexity = 100 in -def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDb_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -let AddedComplexity = 100 in -def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDb_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress) -> memb(#foo) -let AddedComplexity = 100 in -def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDb_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress) -> memb(#foo) -let AddedComplexity = 100 in -def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDb_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -let AddedComplexity = 100 in -def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDub_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress) -> memub(#foo) -let AddedComplexity = 100 in -def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDub_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress) -> memh(#foo) -let AddedComplexity = 100 in -def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDh_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress) -> memh(#foo) -let AddedComplexity = 100 in -def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDh_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress) -> memuh(#foo) -let AddedComplexity = 100 in -def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDuh_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress) -> memw(#foo) -let AddedComplexity = 100 in -def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))), - (i32 (LDw_GP_V4 tglobaladdr:$global))>, - Requires<[HasV4T]>; - -def : Pat <(atomic_load_64 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset)), - (i64 (LDrid_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -def : Pat <(atomic_load_32 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset)), - (i32 (LDriw_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -def : Pat <(atomic_load_16 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset)), - (i32 (LDriuh_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -def : Pat <(atomic_load_8 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset)), - (i32 (LDriub_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress + x) -> memd(#foo + x) -let AddedComplexity = 100 in -def : Pat <(i64 (load (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset))), - (i64 (LDrid_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress + x) -> memb(#foo + x) -let AddedComplexity = 100 in -def : Pat <(i32 (extloadi8 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset))), - (i32 (LDrib_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress + x) -> memb(#foo + x) -let AddedComplexity = 100 in -def : Pat <(i32 (sextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset))), - (i32 (LDrib_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress + x) -> memub(#foo + x) -let AddedComplexity = 100 in -def : Pat <(i32 (zextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset))), - (i32 (LDriub_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress + x) -> memuh(#foo + x) -let AddedComplexity = 100 in -def : Pat <(i32 (extloadi16 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset))), - (i32 (LDrih_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress + x) -> memh(#foo + x) -let AddedComplexity = 100 in -def : Pat <(i32 (sextloadi16 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset))), - (i32 (LDrih_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - - -// Map from load(globaladdress + x) -> memuh(#foo + x) -let AddedComplexity = 100 in -def : Pat <(i32 (zextloadi16 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset))), - (i32 (LDriuh_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - -// Map from load(globaladdress + x) -> memw(#foo + x) -let AddedComplexity = 100 in -def : Pat <(i32 (load (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset))), - (i32 (LDriw_GP_V4 tglobaladdr:$global, u16ImmPred:$offset))>, - Requires<[HasV4T]>; - //===----------------------------------------------------------------------===// // LD - @@ -1746,70 +971,18 @@ def : Pat <(i32 (load (add (HexagonCONST32_GP tglobaladdr:$global), /// last operand. /// +// Store doubleword. // memd(Re=#U6)=Rtt -def STrid_abs_setimm_V4 : STInst<(outs IntRegs:$dst1), - (ins DoubleRegs:$src1, u6Imm:$src2), - "memd($dst1=#$src2) = $src1", - []>, - Requires<[HasV4T]>; - -// memb(Re=#U6)=Rs -def STrib_abs_setimm_V4 : STInst<(outs IntRegs:$dst1), - (ins IntRegs:$src1, u6Imm:$src2), - "memb($dst1=#$src2) = $src1", - []>, - Requires<[HasV4T]>; - -// memh(Re=#U6)=Rs -def STrih_abs_setimm_V4 : STInst<(outs IntRegs:$dst1), - (ins IntRegs:$src1, u6Imm:$src2), - "memh($dst1=#$src2) = $src1", - []>, - Requires<[HasV4T]>; - -// memw(Re=#U6)=Rs -def STriw_abs_setimm_V4 : STInst<(outs IntRegs:$dst1), - (ins IntRegs:$src1, u6Imm:$src2), - "memw($dst1=#$src2) = $src1", - []>, - Requires<[HasV4T]>; - -// memd(Re=#U6)=Rtt -def STrid_abs_set_V4 : STInst<(outs IntRegs:$dst1), - (ins DoubleRegs:$src1, globaladdress:$src2), - "memd($dst1=##$src2) = $src1", - []>, - Requires<[HasV4T]>; - -// memb(Re=#U6)=Rs -def STrib_abs_set_V4 : STInst<(outs IntRegs:$dst1), - (ins IntRegs:$src1, globaladdress:$src2), - "memb($dst1=##$src2) = $src1", - []>, - Requires<[HasV4T]>; - -// memh(Re=#U6)=Rs -def STrih_abs_set_V4 : STInst<(outs IntRegs:$dst1), - (ins IntRegs:$src1, globaladdress:$src2), - "memh($dst1=##$src2) = $src1", - []>, - Requires<[HasV4T]>; - -// memw(Re=#U6)=Rs -def STriw_abs_set_V4 : STInst<(outs IntRegs:$dst1), - (ins IntRegs:$src1, globaladdress:$src2), - "memw($dst1=##$src2) = $src1", - []>, - Requires<[HasV4T]>; +// TODO: needs to be implemented +// memd(Rs+#s11:3)=Rtt // memd(Rs+Ru<<#u2)=Rtt let AddedComplexity = 10, isPredicable = 1 in def STrid_indexed_shl_V4 : STInst<(outs), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, DoubleRegs:$src4), "memd($src1+$src2<<#$src3) = $src4", - [(store (i64 DoubleRegs:$src4), - (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), u2ImmPred:$src3)))]>, + [(store DoubleRegs:$src4, (add IntRegs:$src1, + (shl IntRegs:$src2, u2ImmPred:$src3)))]>, Requires<[HasV4T]>; // memd(Ru<<#u2+#U6)=Rtt @@ -1817,9 +990,9 @@ let AddedComplexity = 10 in def STrid_shl_V4 : STInst<(outs), (ins IntRegs:$src1, u2Imm:$src2, u6Imm:$src3, DoubleRegs:$src4), "memd($src1<<#$src2+#$src3) = $src4", - [(store (i64 DoubleRegs:$src4), - (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2), - u6ImmPred:$src3))]>, + [(store DoubleRegs:$src4, (shl IntRegs:$src1, + (add u2ImmPred:$src2, + u6ImmPred:$src3)))]>, Requires<[HasV4T]>; // memd(Rx++#s4:3)=Rtt @@ -1836,8 +1009,7 @@ def STrid_shl_V4 : STInst<(outs), // if ([!]Pv[.new]) memd(Rs+#u6:3)=Rtt // if (Pv) memd(Rs+#u6:3)=Rtt // if (Pv.new) memd(Rs+#u6:3)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def STrid_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, MEMri:$addr, DoubleRegs:$src2), "if ($src1.new) memd($addr) = $src2", @@ -1846,8 +1018,7 @@ def STrid_cdnPt_V4 : STInst<(outs), // if (!Pv) memd(Rs+#u6:3)=Rtt // if (!Pv.new) memd(Rs+#u6:3)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def STrid_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, MEMri:$addr, DoubleRegs:$src2), "if (!$src1.new) memd($addr) = $src2", @@ -1856,8 +1027,7 @@ def STrid_cdnNotPt_V4 : STInst<(outs), // if (Pv) memd(Rs+#u6:3)=Rtt // if (Pv.new) memd(Rs+#u6:3)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def STrid_indexed_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3, DoubleRegs:$src4), @@ -1867,8 +1037,7 @@ def STrid_indexed_cdnPt_V4 : STInst<(outs), // if (!Pv) memd(Rs+#u6:3)=Rtt // if (!Pv.new) memd(Rs+#u6:3)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def STrid_indexed_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3, DoubleRegs:$src4), @@ -1878,8 +1047,7 @@ def STrid_indexed_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memd(Rs+Ru<<#u2)=Rtt // if (Pv) memd(Rs+Ru<<#u2)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def STrid_indexed_shl_cPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, DoubleRegs:$src5), @@ -1888,17 +1056,15 @@ def STrid_indexed_shl_cPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (Pv.new) memd(Rs+Ru<<#u2)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def STrid_indexed_shl_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, DoubleRegs:$src5), - "if ($src1.new) memd($src2+$src3<<#$src4) = $src5", + "if ($src1) memd($src2+$src3<<#$src4) = $src5", []>, Requires<[HasV4T]>; // if (!Pv) memd(Rs+Ru<<#u2)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def STrid_indexed_shl_cNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, DoubleRegs:$src5), @@ -1906,8 +1072,7 @@ def STrid_indexed_shl_cNotPt_V4 : STInst<(outs), []>, Requires<[HasV4T]>; // if (!Pv.new) memd(Rs+Ru<<#u2)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def STrid_indexed_shl_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, DoubleRegs:$src5), @@ -1918,8 +1083,7 @@ def STrid_indexed_shl_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memd(Rx++#s4:3)=Rtt // if (Pv) memd(Rx++#s4:3)=Rtt // if (Pv.new) memd(Rx++#s4:3)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def POST_STdri_cdnPt_V4 : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, DoubleRegs:$src2, IntRegs:$src3, s4_3Imm:$offset), @@ -1930,8 +1094,7 @@ def POST_STdri_cdnPt_V4 : STInstPI<(outs IntRegs:$dst), // if (!Pv) memd(Rx++#s4:3)=Rtt // if (!Pv.new) memd(Rx++#s4:3)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in def POST_STdri_cdnNotPt_V4 : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, DoubleRegs:$src2, IntRegs:$src3, s4_3Imm:$offset), @@ -1942,12 +1105,15 @@ def POST_STdri_cdnNotPt_V4 : STInstPI<(outs IntRegs:$dst), // Store byte. +// memb(Re=#U6)=Rt +// TODO: needs to be implemented. +// memb(Rs+#s11:0)=Rt // memb(Rs+#u6:0)=#S8 let AddedComplexity = 10, isPredicable = 1 in def STrib_imm_V4 : STInst<(outs), (ins IntRegs:$src1, u6_0Imm:$src2, s8Imm:$src3), "memb($src1+#$src2) = #$src3", - [(truncstorei8 s8ImmPred:$src3, (add (i32 IntRegs:$src1), + [(truncstorei8 s8ImmPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2))]>, Requires<[HasV4T]>; @@ -1956,10 +1122,9 @@ let AddedComplexity = 10, isPredicable = 1 in def STrib_indexed_shl_V4 : STInst<(outs), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4), "memb($src1+$src2<<#$src3) = $src4", - [(truncstorei8 (i32 IntRegs:$src4), - (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$src3)))]>, + [(truncstorei8 IntRegs:$src4, (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$src3)))]>, Requires<[HasV4T]>; // memb(Ru<<#u2+#U6)=Rt @@ -1967,9 +1132,9 @@ let AddedComplexity = 10 in def STrib_shl_V4 : STInst<(outs), (ins IntRegs:$src1, u2Imm:$src2, u6Imm:$src3, IntRegs:$src4), "memb($src1<<#$src2+#$src3) = $src4", - [(truncstorei8 (i32 IntRegs:$src4), - (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2), - u6ImmPred:$src3))]>, + [(truncstorei8 IntRegs:$src4, (shl IntRegs:$src1, + (add u2ImmPred:$src2, + u6ImmPred:$src3)))]>, Requires<[HasV4T]>; // memb(Rx++#s4:0:circ(Mu))=Rt @@ -1983,8 +1148,7 @@ def STrib_shl_V4 : STInst<(outs), // if ([!]Pv[.new]) memb(#u6)=Rt // if ([!]Pv[.new]) memb(Rs+#u6:0)=#S6 // if (Pv) memb(Rs+#u6:0)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_imm_cPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, s6Imm:$src4), "if ($src1) memb($src2+#$src3) = #$src4", @@ -1992,8 +1156,7 @@ def STrib_imm_cPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (Pv.new) memb(Rs+#u6:0)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_imm_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, s6Imm:$src4), "if ($src1.new) memb($src2+#$src3) = #$src4", @@ -2001,8 +1164,7 @@ def STrib_imm_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv) memb(Rs+#u6:0)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_imm_cNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, s6Imm:$src4), "if (!$src1) memb($src2+#$src3) = #$src4", @@ -2010,8 +1172,7 @@ def STrib_imm_cNotPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memb(Rs+#u6:0)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_imm_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, s6Imm:$src4), "if (!$src1.new) memb($src2+#$src3) = #$src4", @@ -2021,8 +1182,7 @@ def STrib_imm_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memb(Rs+#u6:0)=Rt // if (Pv) memb(Rs+#u6:0)=Rt // if (Pv.new) memb(Rs+#u6:0)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1.new) memb($addr) = $src2", @@ -2031,8 +1191,7 @@ def STrib_cdnPt_V4 : STInst<(outs), // if (!Pv) memb(Rs+#u6:0)=Rt // if (!Pv.new) memb(Rs+#u6:0)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1.new) memb($addr) = $src2", @@ -2042,8 +1201,7 @@ def STrib_cdnNotPt_V4 : STInst<(outs), // if (Pv) memb(Rs+#u6:0)=Rt // if (!Pv) memb(Rs+#u6:0)=Rt // if (Pv.new) memb(Rs+#u6:0)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_indexed_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4), "if ($src1.new) memb($src2+#$src3) = $src4", @@ -2051,8 +1209,7 @@ def STrib_indexed_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memb(Rs+#u6:0)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_indexed_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4), "if (!$src1.new) memb($src2+#$src3) = $src4", @@ -2061,8 +1218,7 @@ def STrib_indexed_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memb(Rs+Ru<<#u2)=Rt // if (Pv) memb(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrib_indexed_shl_cPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2071,8 +1227,7 @@ def STrib_indexed_shl_cPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (Pv.new) memb(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrib_indexed_shl_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2081,8 +1236,7 @@ def STrib_indexed_shl_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv) memb(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrib_indexed_shl_cNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2091,8 +1245,7 @@ def STrib_indexed_shl_cNotPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memb(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrib_indexed_shl_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2103,8 +1256,7 @@ def STrib_indexed_shl_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memb(Rx++#s4:0)=Rt // if (Pv) memb(Rx++#s4:0)=Rt // if (Pv.new) memb(Rx++#s4:0)=Rt -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STbri_cdnPt_V4 : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset), "if ($src1.new) memb($src3++#$offset) = $src2", @@ -2113,8 +1265,7 @@ def POST_STbri_cdnPt_V4 : STInstPI<(outs IntRegs:$dst), // if (!Pv) memb(Rx++#s4:0)=Rt // if (!Pv.new) memb(Rx++#s4:0)=Rt -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STbri_cdnNotPt_V4 : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset), "if (!$src1.new) memb($src3++#$offset) = $src2", @@ -2123,15 +1274,20 @@ def POST_STbri_cdnNotPt_V4 : STInstPI<(outs IntRegs:$dst), // Store halfword. -// TODO: needs to be implemented // memh(Re=#U6)=Rt.H +// TODO: needs to be implemented + +// memh(Re=#U6)=Rt +// TODO: needs to be implemented + // memh(Rs+#s11:1)=Rt.H +// memh(Rs+#s11:1)=Rt // memh(Rs+#u6:1)=#S8 let AddedComplexity = 10, isPredicable = 1 in def STrih_imm_V4 : STInst<(outs), (ins IntRegs:$src1, u6_1Imm:$src2, s8Imm:$src3), "memh($src1+#$src2) = #$src3", - [(truncstorei16 s8ImmPred:$src3, (add (i32 IntRegs:$src1), + [(truncstorei16 s8ImmPred:$src3, (add IntRegs:$src1, u6_1ImmPred:$src2))]>, Requires<[HasV4T]>; @@ -2143,10 +1299,9 @@ let AddedComplexity = 10, isPredicable = 1 in def STrih_indexed_shl_V4 : STInst<(outs), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4), "memh($src1+$src2<<#$src3) = $src4", - [(truncstorei16 (i32 IntRegs:$src4), - (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$src3)))]>, + [(truncstorei16 IntRegs:$src4, (add IntRegs:$src1, + (shl IntRegs:$src2, + u2ImmPred:$src3)))]>, Requires<[HasV4T]>; // memh(Ru<<#u2+#U6)=Rt.H @@ -2155,9 +1310,9 @@ let AddedComplexity = 10 in def STrih_shl_V4 : STInst<(outs), (ins IntRegs:$src1, u2Imm:$src2, u6Imm:$src3, IntRegs:$src4), "memh($src1<<#$src2+#$src3) = $src4", - [(truncstorei16 (i32 IntRegs:$src4), - (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2), - u6ImmPred:$src3))]>, + [(truncstorei16 IntRegs:$src4, (shl IntRegs:$src1, + (add u2ImmPred:$src2, + u6ImmPred:$src3)))]>, Requires<[HasV4T]>; // memh(Rx++#s4:1:circ(Mu))=Rt.H @@ -2168,14 +1323,17 @@ def STrih_shl_V4 : STInst<(outs), // memh(Rx++Mu)=Rt // memh(Rx++Mu:brev)=Rt.H // memh(Rx++Mu:brev)=Rt +// memh(gp+#u16:1)=Rt.H // memh(gp+#u16:1)=Rt + + +// Store halfword conditionally. // if ([!]Pv[.new]) memh(#u6)=Rt.H // if ([!]Pv[.new]) memh(#u6)=Rt // if ([!]Pv[.new]) memh(Rs+#u6:1)=#S6 // if (Pv) memh(Rs+#u6:1)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_imm_cPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, s6Imm:$src4), "if ($src1) memh($src2+#$src3) = #$src4", @@ -2183,8 +1341,7 @@ def STrih_imm_cPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (Pv.new) memh(Rs+#u6:1)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_imm_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, s6Imm:$src4), "if ($src1.new) memh($src2+#$src3) = #$src4", @@ -2192,8 +1349,7 @@ def STrih_imm_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv) memh(Rs+#u6:1)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_imm_cNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, s6Imm:$src4), "if (!$src1) memh($src2+#$src3) = #$src4", @@ -2201,8 +1357,7 @@ def STrih_imm_cNotPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memh(Rs+#u6:1)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_imm_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, s6Imm:$src4), "if (!$src1.new) memh($src2+#$src3) = #$src4", @@ -2215,8 +1370,7 @@ def STrih_imm_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt // if (Pv) memh(Rs+#u6:1)=Rt // if (Pv.new) memh(Rs+#u6:1)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1.new) memh($addr) = $src2", @@ -2225,8 +1379,7 @@ def STrih_cdnPt_V4 : STInst<(outs), // if (!Pv) memh(Rs+#u6:1)=Rt // if (!Pv.new) memh(Rs+#u6:1)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1.new) memh($addr) = $src2", @@ -2234,8 +1387,7 @@ def STrih_cdnNotPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (Pv.new) memh(Rs+#u6:1)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_indexed_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4), "if ($src1.new) memh($src2+#$src3) = $src4", @@ -2243,8 +1395,7 @@ def STrih_indexed_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memh(Rs+#u6:1)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_indexed_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4), "if (!$src1.new) memh($src2+#$src3) = $src4", @@ -2254,8 +1405,7 @@ def STrih_indexed_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memh(Rs+Ru<<#u2)=Rt.H // if ([!]Pv[.new]) memh(Rs+Ru<<#u2)=Rt // if (Pv) memh(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrih_indexed_shl_cPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2264,8 +1414,6 @@ def STrih_indexed_shl_cPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (Pv.new) memh(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in def STrih_indexed_shl_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2274,8 +1422,7 @@ def STrih_indexed_shl_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv) memh(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrih_indexed_shl_cNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2284,8 +1431,7 @@ def STrih_indexed_shl_cNotPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memh(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrih_indexed_shl_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2299,8 +1445,7 @@ def STrih_indexed_shl_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt // if (Pv) memh(Rx++#s4:1)=Rt // if (Pv.new) memh(Rx++#s4:1)=Rt -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_SThri_cdnPt_V4 : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset), "if ($src1.new) memh($src3++#$offset) = $src2", @@ -2309,8 +1454,7 @@ def POST_SThri_cdnPt_V4 : STInstPI<(outs IntRegs:$dst), // if (!Pv) memh(Rx++#s4:1)=Rt // if (!Pv.new) memh(Rx++#s4:1)=Rt -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_SThri_cdnNotPt_V4 : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset), "if (!$src1.new) memh($src3++#$offset) = $src2", @@ -2322,22 +1466,13 @@ def POST_SThri_cdnNotPt_V4 : STInstPI<(outs IntRegs:$dst), // memw(Re=#U6)=Rt // TODO: Needs to be implemented. -// Store predicate: -let mayStore = 1, neverHasSideEffects = 1 in -def STriw_pred_V4 : STInst<(outs), - (ins MEMri:$addr, PredRegs:$src1), - "Error; should not emit", - []>, - Requires<[HasV4T]>; - - +// memw(Rs+#s11:2)=Rt // memw(Rs+#u6:2)=#S8 let AddedComplexity = 10, isPredicable = 1 in def STriw_imm_V4 : STInst<(outs), (ins IntRegs:$src1, u6_2Imm:$src2, s8Imm:$src3), "memw($src1+#$src2) = #$src3", - [(store s8ImmPred:$src3, (add (i32 IntRegs:$src1), - u6_2ImmPred:$src2))]>, + [(store s8ImmPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2))]>, Requires<[HasV4T]>; // memw(Rs+Ru<<#u2)=Rt @@ -2345,9 +1480,8 @@ let AddedComplexity = 10, isPredicable = 1 in def STriw_indexed_shl_V4 : STInst<(outs), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4), "memw($src1+$src2<<#$src3) = $src4", - [(store (i32 IntRegs:$src4), (add (i32 IntRegs:$src1), - (shl (i32 IntRegs:$src2), - u2ImmPred:$src3)))]>, + [(store IntRegs:$src4, (add IntRegs:$src1, + (shl IntRegs:$src2, u2ImmPred:$src3)))]>, Requires<[HasV4T]>; // memw(Ru<<#u2+#U6)=Rt @@ -2355,9 +1489,8 @@ let AddedComplexity = 10 in def STriw_shl_V4 : STInst<(outs), (ins IntRegs:$src1, u2Imm:$src2, u6Imm:$src3, IntRegs:$src4), "memw($src1<<#$src2+#$src3) = $src4", - [(store (i32 IntRegs:$src4), - (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2), - u6ImmPred:$src3))]>, + [(store IntRegs:$src4, (shl IntRegs:$src1, + (add u2ImmPred:$src2, u6ImmPred:$src3)))]>, Requires<[HasV4T]>; // memw(Rx++#s4:2)=Rt @@ -2369,11 +1502,12 @@ def STriw_shl_V4 : STInst<(outs), // Store word conditionally. +// if ([!]Pv[.new]) memw(#u6)=Rt +// TODO: Needs to be implemented. // if ([!]Pv[.new]) memw(Rs+#u6:2)=#S6 // if (Pv) memw(Rs+#u6:2)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_imm_cPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, s6Imm:$src4), "if ($src1) memw($src2+#$src3) = #$src4", @@ -2381,8 +1515,7 @@ def STriw_imm_cPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (Pv.new) memw(Rs+#u6:2)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_imm_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, s6Imm:$src4), "if ($src1.new) memw($src2+#$src3) = #$src4", @@ -2390,8 +1523,7 @@ def STriw_imm_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv) memw(Rs+#u6:2)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_imm_cNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, s6Imm:$src4), "if (!$src1) memw($src2+#$src3) = #$src4", @@ -2399,8 +1531,7 @@ def STriw_imm_cNotPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memw(Rs+#u6:2)=#S6 -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_imm_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, s6Imm:$src4), "if (!$src1.new) memw($src2+#$src3) = #$src4", @@ -2410,8 +1541,7 @@ def STriw_imm_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memw(Rs+#u6:2)=Rt // if (Pv) memw(Rs+#u6:2)=Rt // if (Pv.new) memw(Rs+#u6:2)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1.new) memw($addr) = $src2", @@ -2420,8 +1550,7 @@ def STriw_cdnPt_V4 : STInst<(outs), // if (!Pv) memw(Rs+#u6:2)=Rt // if (!Pv.new) memw(Rs+#u6:2)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1.new) memw($addr) = $src2", @@ -2431,8 +1560,7 @@ def STriw_cdnNotPt_V4 : STInst<(outs), // if (Pv) memw(Rs+#u6:2)=Rt // if (!Pv) memw(Rs+#u6:2)=Rt // if (Pv.new) memw(Rs+#u6:2)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_indexed_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4), "if ($src1.new) memw($src2+#$src3) = $src4", @@ -2440,8 +1568,7 @@ def STriw_indexed_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memw(Rs+#u6:2)=Rt -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_indexed_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4), "if (!$src1.new) memw($src2+#$src3) = $src4", @@ -2450,8 +1577,7 @@ def STriw_indexed_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memw(Rs+Ru<<#u2)=Rt // if (Pv) memw(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STriw_indexed_shl_cPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2460,8 +1586,7 @@ def STriw_indexed_shl_cPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (Pv.new) memw(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STriw_indexed_shl_cdnPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2470,8 +1595,7 @@ def STriw_indexed_shl_cdnPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv) memw(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STriw_indexed_shl_cNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2480,8 +1604,7 @@ def STriw_indexed_shl_cNotPt_V4 : STInst<(outs), Requires<[HasV4T]>; // if (!Pv.new) memw(Rs+Ru<<#u2)=Rt -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STriw_indexed_shl_cdnNotPt_V4 : STInst<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -2492,8 +1615,7 @@ def STriw_indexed_shl_cdnNotPt_V4 : STInst<(outs), // if ([!]Pv[.new]) memw(Rx++#s4:2)=Rt // if (Pv) memw(Rx++#s4:2)=Rt // if (Pv.new) memw(Rx++#s4:2)=Rt -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STwri_cdnPt_V4 : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset), "if ($src1.new) memw($src3++#$offset) = $src2", @@ -2502,8 +1624,7 @@ def POST_STwri_cdnPt_V4 : STInstPI<(outs IntRegs:$dst), // if (!Pv) memw(Rx++#s4:2)=Rt // if (!Pv.new) memw(Rx++#s4:2)=Rt -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STwri_cdnNotPt_V4 : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset), "if (!$src1.new) memw($src3++#$offset) = $src2", @@ -2511,439 +1632,6 @@ def POST_STwri_cdnNotPt_V4 : STInstPI<(outs IntRegs:$dst), Requires<[HasV4T]>; -/// store to global address - -let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1 in -def STrid_GP_V4 : STInst<(outs), - (ins globaladdress:$global, u16Imm:$offset, DoubleRegs:$src), - "memd(#$global+$offset) = $src", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrid_GP_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - DoubleRegs:$src2), - "if ($src1) memd(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrid_GP_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - DoubleRegs:$src2), - "if (!$src1) memd(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrid_GP_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - DoubleRegs:$src2), - "if ($src1.new) memd(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrid_GP_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - DoubleRegs:$src2), - "if (!$src1.new) memd(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1 in -def STrib_GP_V4 : STInst<(outs), - (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src), - "memb(#$global+$offset) = $src", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrib_GP_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1) memb(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrib_GP_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1) memb(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrib_GP_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1.new) memb(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrib_GP_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1.new) memb(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1 in -def STrih_GP_V4 : STInst<(outs), - (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src), - "memh(#$global+$offset) = $src", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrih_GP_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1) memh(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrih_GP_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1) memh(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrih_GP_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1.new) memh(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STrih_GP_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1.new) memh(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1 in -def STriw_GP_V4 : STInst<(outs), - (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src), - "memw(#$global+$offset) = $src", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STriw_GP_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1) memw(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STriw_GP_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1) memw(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STriw_GP_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1.new) memw(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STriw_GP_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1.new) memw(##$global+$offset) = $src2", - []>, - Requires<[HasV4T]>; - -// memd(#global)=Rtt -let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1 in -def STd_GP_V4 : STInst<(outs), - (ins globaladdress:$global, DoubleRegs:$src), - "memd(#$global) = $src", - []>, - Requires<[HasV4T]>; - -// if (Pv) memd(##global) = Rtt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STd_GP_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2), - "if ($src1) memd(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memd(##global) = Rtt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STd_GP_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2), - "if (!$src1) memd(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (Pv) memd(##global) = Rtt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STd_GP_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2), - "if ($src1.new) memd(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memd(##global) = Rtt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STd_GP_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2), - "if (!$src1.new) memd(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// memb(#global)=Rt -let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1 in -def STb_GP_V4 : STInst<(outs), - (ins globaladdress:$global, IntRegs:$src), - "memb(#$global) = $src", - []>, - Requires<[HasV4T]>; - -// if (Pv) memb(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STb_GP_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1) memb(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memb(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STb_GP_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1) memb(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (Pv) memb(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STb_GP_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1.new) memb(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memb(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STb_GP_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1.new) memb(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// memh(#global)=Rt -let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1 in -def STh_GP_V4 : STInst<(outs), - (ins globaladdress:$global, IntRegs:$src), - "memh(#$global) = $src", - []>, - Requires<[HasV4T]>; - -// if (Pv) memh(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STh_GP_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1) memh(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memh(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STh_GP_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1) memh(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (Pv) memh(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STh_GP_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1.new) memh(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memh(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STh_GP_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1.new) memh(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// memw(#global)=Rt -let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1 in -def STw_GP_V4 : STInst<(outs), - (ins globaladdress:$global, IntRegs:$src), - "memw(#$global) = $src", - []>, - Requires<[HasV4T]>; - -// if (Pv) memw(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STw_GP_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1) memw(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memw(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STw_GP_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1) memw(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (Pv) memw(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STw_GP_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1.new) memw(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memw(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1 in -def STw_GP_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1.new) memw(##$global) = $src2", - []>, - Requires<[HasV4T]>; - -// 64 bit atomic store -def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global), - (i64 DoubleRegs:$src1)), - (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from store(globaladdress) -> memd(#foo) -let AddedComplexity = 100 in -def : Pat <(store (i64 DoubleRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)), - (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>, - Requires<[HasV4T]>; - -// 8 bit atomic store -def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global), - (i32 IntRegs:$src1)), - (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from store(globaladdress) -> memb(#foo) -let AddedComplexity = 100 in -def : Pat<(truncstorei8 (i32 IntRegs:$src1), - (HexagonCONST32_GP tglobaladdr:$global)), - (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1" -// to "r0 = 1; memw(#foo) = r0" -let AddedComplexity = 100 in -def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)), - (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>, - Requires<[HasV4T]>; - -def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global), - (i32 IntRegs:$src1)), - (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from store(globaladdress) -> memh(#foo) -let AddedComplexity = 100 in -def : Pat<(truncstorei16 (i32 IntRegs:$src1), - (HexagonCONST32_GP tglobaladdr:$global)), - (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -// 32 bit atomic store -def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global), - (i32 IntRegs:$src1)), - (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from store(globaladdress) -> memw(#foo) -let AddedComplexity = 100 in -def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)), - (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -def : Pat<(atomic_store_64 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset), - (i64 DoubleRegs:$src1)), - (STrid_GP_V4 tglobaladdr:$global, u16ImmPred:$offset, - (i64 DoubleRegs:$src1))>, - Requires<[HasV4T]>; - -def : Pat<(atomic_store_32 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset), - (i32 IntRegs:$src1)), - (STriw_GP_V4 tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -def : Pat<(atomic_store_16 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset), - (i32 IntRegs:$src1)), - (STrih_GP_V4 tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -def : Pat<(atomic_store_8 (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset), - (i32 IntRegs:$src1)), - (STrib_GP_V4 tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from store(globaladdress + x) -> memd(#foo + x) -let AddedComplexity = 100 in -def : Pat<(store (i64 DoubleRegs:$src1), (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset)), - (STrid_GP_V4 tglobaladdr:$global, u16ImmPred:$offset, - (i64 DoubleRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from store(globaladdress + x) -> memb(#foo + x) -let AddedComplexity = 100 in -def : Pat<(truncstorei8 (i32 IntRegs:$src1), - (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset)), - (STrib_GP_V4 tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from store(globaladdress + x) -> memh(#foo + x) -let AddedComplexity = 100 in -def : Pat<(truncstorei16 (i32 IntRegs:$src1), - (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset)), - (STrih_GP_V4 tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - -// Map from store(globaladdress + x) -> memw(#foo + x) -let AddedComplexity = 100 in -def : Pat<(store (i32 IntRegs:$src1), - (add (HexagonCONST32_GP tglobaladdr:$global), - u16ImmPred:$offset)), - (STriw_GP_V4 tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>, - Requires<[HasV4T]>; - - - //===----------------------------------------------------------------------=== // ST - //===----------------------------------------------------------------------=== @@ -3008,19 +1696,11 @@ def STrib_GP_nv_V4 : NVInst_V4<(outs), []>, Requires<[HasV4T]>; -// memb(#global)=Nt.new -let mayStore = 1, neverHasSideEffects = 1 in -def STb_GP_nv_V4 : NVInst_V4<(outs), - (ins globaladdress:$global, IntRegs:$src), - "memb(#$global) = $src.new", - []>, - Requires<[HasV4T]>; // Store new-value byte conditionally. // if ([!]Pv[.new]) memb(#u6)=Nt.new // if (Pv) memb(Rs+#u6:0)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1) memb($addr) = $src2.new", @@ -3028,8 +1708,7 @@ def STrib_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memb(Rs+#u6:0)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1.new) memb($addr) = $src2.new", @@ -3037,8 +1716,7 @@ def STrib_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memb(Rs+#u6:0)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1) memb($addr) = $src2.new", @@ -3046,8 +1724,7 @@ def STrib_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memb(Rs+#u6:0)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1.new) memb($addr) = $src2.new", @@ -3055,8 +1732,7 @@ def STrib_cdnNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv) memb(Rs+#u6:0)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_indexed_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4), "if ($src1) memb($src2+#$src3) = $src4.new", @@ -3064,8 +1740,7 @@ def STrib_indexed_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memb(Rs+#u6:0)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_indexed_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4), "if ($src1.new) memb($src2+#$src3) = $src4.new", @@ -3073,8 +1748,7 @@ def STrib_indexed_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memb(Rs+#u6:0)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_indexed_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4), "if (!$src1) memb($src2+#$src3) = $src4.new", @@ -3082,8 +1756,7 @@ def STrib_indexed_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memb(Rs+#u6:0)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrib_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4), "if (!$src1.new) memb($src2+#$src3) = $src4.new", @@ -3093,8 +1766,7 @@ def STrib_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs), // if ([!]Pv[.new]) memb(Rs+Ru<<#u2)=Nt.new // if (Pv) memb(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrib_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3103,8 +1775,7 @@ def STrib_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memb(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrib_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3113,8 +1784,7 @@ def STrib_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memb(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrib_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3123,8 +1793,7 @@ def STrib_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memb(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrib_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3134,8 +1803,7 @@ def STrib_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs), // if ([!]Pv[.new]) memb(Rx++#s4:0)=Nt.new // if (Pv) memb(Rx++#s4:0)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STbri_cPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset), "if ($src1) memb($src3++#$offset) = $src2.new", @@ -3143,8 +1811,7 @@ def POST_STbri_cPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (Pv.new) memb(Rx++#s4:0)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STbri_cdnPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset), "if ($src1.new) memb($src3++#$offset) = $src2.new", @@ -3152,8 +1819,7 @@ def POST_STbri_cdnPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (!Pv) memb(Rx++#s4:0)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STbri_cNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset), "if (!$src1) memb($src3++#$offset) = $src2.new", @@ -3161,8 +1827,7 @@ def POST_STbri_cNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (!Pv.new) memb(Rx++#s4:0)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STbri_cdnNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset), "if (!$src1.new) memb($src3++#$offset) = $src2.new", @@ -3224,14 +1889,6 @@ def STrih_GP_nv_V4 : NVInst_V4<(outs), []>, Requires<[HasV4T]>; -// memh(#global)=Nt.new -let mayStore = 1, neverHasSideEffects = 1 in -def STh_GP_nv_V4 : NVInst_V4<(outs), - (ins globaladdress:$global, IntRegs:$src), - "memh(#$global) = $src.new", - []>, - Requires<[HasV4T]>; - // Store new-value halfword conditionally. @@ -3239,8 +1896,7 @@ def STh_GP_nv_V4 : NVInst_V4<(outs), // if ([!]Pv[.new]) memh(Rs+#u6:1)=Nt.new // if (Pv) memh(Rs+#u6:1)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1) memh($addr) = $src2.new", @@ -3248,8 +1904,7 @@ def STrih_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memh(Rs+#u6:1)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1.new) memh($addr) = $src2.new", @@ -3257,8 +1912,7 @@ def STrih_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memh(Rs+#u6:1)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1) memh($addr) = $src2.new", @@ -3266,8 +1920,7 @@ def STrih_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memh(Rs+#u6:1)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1.new) memh($addr) = $src2.new", @@ -3275,8 +1928,7 @@ def STrih_cdnNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv) memh(Rs+#u6:1)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_indexed_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4), "if ($src1) memh($src2+#$src3) = $src4.new", @@ -3284,8 +1936,7 @@ def STrih_indexed_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memh(Rs+#u6:1)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_indexed_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4), "if ($src1.new) memh($src2+#$src3) = $src4.new", @@ -3293,8 +1944,7 @@ def STrih_indexed_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memh(Rs+#u6:1)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_indexed_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4), "if (!$src1) memh($src2+#$src3) = $src4.new", @@ -3302,8 +1952,7 @@ def STrih_indexed_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memh(Rs+#u6:1)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STrih_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4), "if (!$src1.new) memh($src2+#$src3) = $src4.new", @@ -3312,8 +1961,7 @@ def STrih_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs), // if ([!]Pv[.new]) memh(Rs+Ru<<#u2)=Nt.new // if (Pv) memh(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrih_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3322,8 +1970,7 @@ def STrih_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memh(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrih_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3332,8 +1979,7 @@ def STrih_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memh(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrih_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3342,8 +1988,7 @@ def STrih_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memh(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STrih_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3353,8 +1998,7 @@ def STrih_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs), // if ([!]Pv[]) memh(Rx++#s4:1)=Nt.new // if (Pv) memh(Rx++#s4:1)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_SThri_cPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset), "if ($src1) memh($src3++#$offset) = $src2.new", @@ -3362,8 +2006,7 @@ def POST_SThri_cPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (Pv.new) memh(Rx++#s4:1)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_SThri_cdnPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset), "if ($src1.new) memh($src3++#$offset) = $src2.new", @@ -3371,8 +2014,7 @@ def POST_SThri_cdnPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (!Pv) memh(Rx++#s4:1)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_SThri_cNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset), "if (!$src1) memh($src3++#$offset) = $src2.new", @@ -3380,8 +2022,7 @@ def POST_SThri_cNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (!Pv.new) memh(Rx++#s4:1)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_SThri_cdnNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset), "if (!$src1.new) memh($src3++#$offset) = $src2.new", @@ -3444,12 +2085,6 @@ def STriw_GP_nv_V4 : NVInst_V4<(outs), []>, Requires<[HasV4T]>; -let mayStore = 1, neverHasSideEffects = 1 in -def STw_GP_nv_V4 : NVInst_V4<(outs), - (ins globaladdress:$global, IntRegs:$src), - "memw(#$global) = $src.new", - []>, - Requires<[HasV4T]>; // Store new-value word conditionally. @@ -3457,8 +2092,7 @@ def STw_GP_nv_V4 : NVInst_V4<(outs), // if ([!]Pv[.new]) memw(Rs+#u6:2)=Nt.new // if (Pv) memw(Rs+#u6:2)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1) memw($addr) = $src2.new", @@ -3466,8 +2100,7 @@ def STriw_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memw(Rs+#u6:2)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if ($src1.new) memw($addr) = $src2.new", @@ -3475,8 +2108,7 @@ def STriw_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memw(Rs+#u6:2)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1) memw($addr) = $src2.new", @@ -3484,8 +2116,7 @@ def STriw_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memw(Rs+#u6:2)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2), "if (!$src1.new) memw($addr) = $src2.new", @@ -3493,8 +2124,7 @@ def STriw_cdnNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv) memw(Rs+#u6:2)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_indexed_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4), "if ($src1) memw($src2+#$src3) = $src4.new", @@ -3502,8 +2132,7 @@ def STriw_indexed_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memw(Rs+#u6:2)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_indexed_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4), "if ($src1.new) memw($src2+#$src3) = $src4.new", @@ -3511,8 +2140,7 @@ def STriw_indexed_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memw(Rs+#u6:2)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_indexed_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4), "if (!$src1) memw($src2+#$src3) = $src4.new", @@ -3520,8 +2148,7 @@ def STriw_indexed_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memw(Rs+#u6:2)=Nt.new -let mayStore = 1, neverHasSideEffects = 1, - isPredicated = 1 in +let mayStore = 1, neverHasSideEffects = 1 in def STriw_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4), "if (!$src1.new) memw($src2+#$src3) = $src4.new", @@ -3531,8 +2158,7 @@ def STriw_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs), // if ([!]Pv[.new]) memw(Rs+Ru<<#u2)=Nt.new // if (Pv) memw(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STriw_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3541,8 +2167,7 @@ def STriw_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (Pv.new) memw(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STriw_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3551,8 +2176,7 @@ def STriw_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv) memw(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STriw_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3561,8 +2185,7 @@ def STriw_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs), Requires<[HasV4T]>; // if (!Pv.new) memw(Rs+Ru<<#u2)=Nt.new -let mayStore = 1, AddedComplexity = 10, - isPredicated = 1 in +let mayStore = 1, AddedComplexity = 10 in def STriw_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, IntRegs:$src5), @@ -3572,8 +2195,7 @@ def STriw_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs), // if ([!]Pv[.new]) memw(Rx++#s4:2)=Nt.new // if (Pv) memw(Rx++#s4:2)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STwri_cPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset), "if ($src1) memw($src3++#$offset) = $src2.new", @@ -3581,8 +2203,7 @@ def POST_STwri_cPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (Pv.new) memw(Rx++#s4:2)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STwri_cdnPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset), "if ($src1.new) memw($src3++#$offset) = $src2.new", @@ -3590,8 +2211,7 @@ def POST_STwri_cdnPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (!Pv) memw(Rx++#s4:2)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STwri_cNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset), "if (!$src1) memw($src3++#$offset) = $src2.new", @@ -3599,8 +2219,7 @@ def POST_STwri_cNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; // if (!Pv.new) memw(Rx++#s4:2)=Nt.new -let mayStore = 1, hasCtrlDep = 1, - isPredicated = 1 in +let mayStore = 1, hasCtrlDep = 1 in def POST_STwri_cdnNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset), "if (!$src1.new) memw($src3++#$offset) = $src2.new", @@ -3608,199 +2227,6 @@ def POST_STwri_cdnNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), Requires<[HasV4T]>; - -// if (Pv) memb(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STb_GP_cPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1) memb(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memb(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STb_GP_cNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1) memb(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (Pv) memb(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STb_GP_cdnPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1.new) memb(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memb(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STb_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1.new) memb(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (Pv) memh(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STh_GP_cPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1) memh(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memh(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STh_GP_cNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1) memh(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (Pv) memh(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STh_GP_cdnPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1.new) memh(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memh(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STh_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1.new) memh(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (Pv) memw(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STw_GP_cPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1) memw(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memw(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STw_GP_cNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1) memw(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (Pv) memw(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STw_GP_cdnPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if ($src1.new) memw(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -// if (!Pv) memw(##global) = Rt -let mayStore = 1, neverHasSideEffects = 1 in -def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2), - "if (!$src1.new) memw(##$global) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STrib_GP_cPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1) memb(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STrib_GP_cNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1) memb(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STrib_GP_cdnPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1.new) memb(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STrib_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1.new) memb(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STrih_GP_cPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1) memh(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STrih_GP_cNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1) memh(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STrih_GP_cdnPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1.new) memh(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STrih_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1.new) memh(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STriw_GP_cPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1) memw(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STriw_GP_cNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1) memw(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STriw_GP_cdnPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if ($src1.new) memw(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - -let mayStore = 1, neverHasSideEffects = 1 in -def STriw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, globaladdress:$global, u16Imm:$offset, - IntRegs:$src2), - "if (!$src1.new) memw(##$global+$offset) = $src2.new", - []>, - Requires<[HasV4T]>; - //===----------------------------------------------------------------------===// // NV/ST - //===----------------------------------------------------------------------===// @@ -3990,18 +2416,16 @@ let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in { def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, s6Imm:$src3), "$dst = add($src1, add($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2), - s6ImmPred:$src3)))]>, + [(set IntRegs:$dst, + (add IntRegs:$src1, (add IntRegs:$src2, s6ImmPred:$src3)))]>, Requires<[HasV4T]>; // Rd=add(Rs,sub(#s6,Ru)) def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s6Imm:$src2, IntRegs:$src3), "$dst = add($src1, sub(#$src2, $src3))", - [(set (i32 IntRegs:$dst), - (add (i32 IntRegs:$src1), (sub s6ImmPred:$src2, - (i32 IntRegs:$src3))))]>, + [(set IntRegs:$dst, + (add IntRegs:$src1, (sub s6ImmPred:$src2, IntRegs:$src3)))]>, Requires<[HasV4T]>; // Generates the same instruction as ADDr_SUBri_V4 but matches different @@ -4010,9 +2434,8 @@ def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst), def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s6Imm:$src2, IntRegs:$src3), "$dst = add($src1, sub(#$src2, $src3))", - [(set (i32 IntRegs:$dst), - (sub (add (i32 IntRegs:$src1), s6ImmPred:$src2), - (i32 IntRegs:$src3)))]>, + [(set IntRegs:$dst, + (sub (add IntRegs:$src1, s6ImmPred:$src2), IntRegs:$src3))]>, Requires<[HasV4T]>; @@ -4028,16 +2451,16 @@ def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst), def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = and($src1, ~$src2)", - [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1), - (not (i64 DoubleRegs:$src2))))]>, + [(set DoubleRegs:$dst, (and DoubleRegs:$src1, + (not DoubleRegs:$src2)))]>, Requires<[HasV4T]>; // Rdd=or(Rtt,~Rss) def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = or($src1, ~$src2)", - [(set (i64 DoubleRegs:$dst), - (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>, + [(set DoubleRegs:$dst, + (or DoubleRegs:$src1, (not DoubleRegs:$src2)))]>, Requires<[HasV4T]>; @@ -4046,9 +2469,8 @@ def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst), def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3), "$dst ^= xor($src2, $src3)", - [(set (i64 DoubleRegs:$dst), - (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2), - (i64 DoubleRegs:$src3))))], + [(set DoubleRegs:$dst, + (xor DoubleRegs:$src1, (xor DoubleRegs:$src2, DoubleRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4058,9 +2480,8 @@ def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst), def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, s10Imm:$src3), "$dst = or($src1, and($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - s10ImmPred:$src3)))], + [(set IntRegs:$dst, + (or IntRegs:$src1, (and IntRegs:$src2, s10ImmPred:$src3)))], "$src2 = $dst">, Requires<[HasV4T]>; @@ -4069,9 +2490,8 @@ def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst), def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst &= and($src2, $src3)", - [(set (i32 IntRegs:$dst), - (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (and IntRegs:$src1, (and IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4079,9 +2499,8 @@ def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst |= and($src2, $src3)", - [(set (i32 IntRegs:$dst), - (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (or IntRegs:$src1, (and IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4089,9 +2508,8 @@ def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst ^= and($src2, $src3)", - [(set (i32 IntRegs:$dst), - (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (xor IntRegs:$src1, (and IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4100,9 +2518,8 @@ def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst &= and($src2, ~$src3)", - [(set (i32 IntRegs:$dst), - (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - (not (i32 IntRegs:$src3)))))], + [(set IntRegs:$dst, + (and IntRegs:$src1, (and IntRegs:$src2, (not IntRegs:$src3))))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4110,9 +2527,8 @@ def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst |= and($src2, ~$src3)", - [(set (i32 IntRegs:$dst), - (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - (not (i32 IntRegs:$src3)))))], + [(set IntRegs:$dst, + (or IntRegs:$src1, (and IntRegs:$src2, (not IntRegs:$src3))))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4120,9 +2536,8 @@ def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst ^= and($src2, ~$src3)", - [(set (i32 IntRegs:$dst), - (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - (not (i32 IntRegs:$src3)))))], + [(set IntRegs:$dst, + (xor IntRegs:$src1, (and IntRegs:$src2, (not IntRegs:$src3))))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4131,9 +2546,8 @@ def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst &= or($src2, $src3)", - [(set (i32 IntRegs:$dst), - (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (and IntRegs:$src1, (or IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4141,9 +2555,8 @@ def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst |= or($src2, $src3)", - [(set (i32 IntRegs:$dst), - (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (or IntRegs:$src1, (or IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4151,9 +2564,8 @@ def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst ^= or($src2, $src3)", - [(set (i32 IntRegs:$dst), - (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (xor IntRegs:$src1, (or IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4162,9 +2574,8 @@ def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst &= xor($src2, $src3)", - [(set (i32 IntRegs:$dst), - (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (and IntRegs:$src1, (xor IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4172,9 +2583,8 @@ def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst |= xor($src2, $src3)", - [(set (i32 IntRegs:$dst), - (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (and IntRegs:$src1, (xor IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4182,9 +2592,8 @@ def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), "$dst ^= xor($src2, $src3)", - [(set (i32 IntRegs:$dst), - (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (and IntRegs:$src1, (xor IntRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4192,9 +2601,8 @@ def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, s10Imm:$src3), "$dst |= and($src2, #$src3)", - [(set (i32 IntRegs:$dst), - (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - s10ImmPred:$src3)))], + [(set IntRegs:$dst, + (or IntRegs:$src1, (and IntRegs:$src2, s10ImmPred:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4202,9 +2610,8 @@ def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst), def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs: $src2, s10Imm:$src3), "$dst |= or($src2, #$src3)", - [(set (i32 IntRegs:$dst), - (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), - s10ImmPred:$src3)))], + [(set IntRegs:$dst, + (or IntRegs:$src1, (and IntRegs:$src2, s10ImmPred:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4256,9 +2663,8 @@ def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst), def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst), (ins u6Imm:$src1, IntRegs:$src2, u6Imm:$src3), "$dst = add(#$src1, mpyi($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3), - u6ImmPred:$src1))]>, + [(set IntRegs:$dst, + (add (mul IntRegs:$src2, u6ImmPred:$src3), u6ImmPred:$src1))]>, Requires<[HasV4T]>; // Rd=add(#u6,mpyi(Rs,Rt)) @@ -4266,36 +2672,32 @@ def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst), def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst), (ins u6Imm:$src1, IntRegs:$src2, IntRegs:$src3), "$dst = add(#$src1, mpyi($src2, $src3))", - [(set (i32 IntRegs:$dst), - (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)), - u6ImmPred:$src1))]>, + [(set IntRegs:$dst, + (add (mul IntRegs:$src2, IntRegs:$src3), u6ImmPred:$src1))]>, Requires<[HasV4T]>; // Rd=add(Ru,mpyi(#u6:2,Rs)) def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3), "$dst = add($src1, mpyi(#$src2, $src3))", - [(set (i32 IntRegs:$dst), - (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3), - u6_2ImmPred:$src2)))]>, + [(set IntRegs:$dst, + (add IntRegs:$src1, (mul IntRegs:$src3, u6_2ImmPred:$src2)))]>, Requires<[HasV4T]>; // Rd=add(Ru,mpyi(Rs,#u6)) def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, u6Imm:$src3), "$dst = add($src1, mpyi($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2), - u6ImmPred:$src3)))]>, + [(set IntRegs:$dst, + (add IntRegs:$src1, (mul IntRegs:$src2, u6ImmPred:$src3)))]>, Requires<[HasV4T]>; // Rx=add(Ru,mpyi(Rx,Rs)) def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3), "$dst = add($src1, mpyi($src2, $src3))", - [(set (i32 IntRegs:$dst), - (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))], + [(set IntRegs:$dst, + (add IntRegs:$src1, (mul IntRegs:$src2, IntRegs:$src3)))], "$src2 = $dst">, Requires<[HasV4T]>; @@ -4343,9 +2745,8 @@ def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst), def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), (ins u8Imm:$src1, IntRegs:$src2, u5Imm:$src3), "$dst = add(#$src1, asl($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3), - u8ImmPred:$src1))], + [(set IntRegs:$dst, + (add (shl IntRegs:$src2, u5ImmPred:$src3), u8ImmPred:$src1))], "$src2 = $dst">, Requires<[HasV4T]>; @@ -4353,9 +2754,8 @@ def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), (ins u8Imm:$src1, IntRegs:$src2, u5Imm:$src3), "$dst = add(#$src1, lsr($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3), - u8ImmPred:$src1))], + [(set IntRegs:$dst, + (add (srl IntRegs:$src2, u5ImmPred:$src3), u8ImmPred:$src1))], "$src2 = $dst">, Requires<[HasV4T]>; @@ -4363,9 +2763,8 @@ def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), (ins u8Imm:$src1, IntRegs:$src2, u5Imm:$src3), "$dst = sub(#$src1, asl($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3), - u8ImmPred:$src1))], + [(set IntRegs:$dst, + (sub (shl IntRegs:$src2, u5ImmPred:$src3), u8ImmPred:$src1))], "$src2 = $dst">, Requires<[HasV4T]>; @@ -4373,9 +2772,8 @@ def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), (ins u8Imm:$src1, IntRegs:$src2, u5Imm:$src3), "$dst = sub(#$src1, lsr($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3), - u8ImmPred:$src1))], + [(set IntRegs:$dst, + (sub (srl IntRegs:$src2, u5ImmPred:$src3), u8ImmPred:$src1))], "$src2 = $dst">, Requires<[HasV4T]>; @@ -4385,9 +2783,8 @@ def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), (ins u8Imm:$src1, IntRegs:$src2, u5Imm:$src3), "$dst = and(#$src1, asl($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3), - u8ImmPred:$src1))], + [(set IntRegs:$dst, + (and (shl IntRegs:$src2, u5ImmPred:$src3), u8ImmPred:$src1))], "$src2 = $dst">, Requires<[HasV4T]>; @@ -4395,31 +2792,26 @@ def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), (ins u8Imm:$src1, IntRegs:$src2, u5Imm:$src3), "$dst = and(#$src1, lsr($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3), - u8ImmPred:$src1))], + [(set IntRegs:$dst, + (and (srl IntRegs:$src2, u5ImmPred:$src3), u8ImmPred:$src1))], "$src2 = $dst">, Requires<[HasV4T]>; //Rx=or(#u8,asl(Rx,#U5)) -let AddedComplexity = 30 in def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), (ins u8Imm:$src1, IntRegs:$src2, u5Imm:$src3), "$dst = or(#$src1, asl($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3), - u8ImmPred:$src1))], + [(set IntRegs:$dst, + (or (shl IntRegs:$src2, u5ImmPred:$src3), u8ImmPred:$src1))], "$src2 = $dst">, Requires<[HasV4T]>; //Rx=or(#u8,lsr(Rx,#U5)) -let AddedComplexity = 30 in def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), (ins u8Imm:$src1, IntRegs:$src2, u5Imm:$src3), "$dst = or(#$src1, lsr($src2, #$src3))", - [(set (i32 IntRegs:$dst), - (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3), - u8ImmPred:$src1))], + [(set IntRegs:$dst, + (or (srl IntRegs:$src2, u5ImmPred:$src3), u8ImmPred:$src1))], "$src2 = $dst">, Requires<[HasV4T]>; @@ -4428,8 +2820,7 @@ def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), //Rd=lsl(#s6,Rt) def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2), "$dst = lsl(#$src1, $src2)", - [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1, - (i32 IntRegs:$src2)))]>, + [(set IntRegs:$dst, (shl s6ImmPred:$src1, IntRegs:$src2))]>, Requires<[HasV4T]>; @@ -4438,9 +2829,8 @@ def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2), def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), "$dst ^= asl($src2, $src3)", - [(set (i64 DoubleRegs:$dst), - (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2), - (i32 IntRegs:$src3))))], + [(set DoubleRegs:$dst, + (xor DoubleRegs:$src1, (shl DoubleRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4448,9 +2838,8 @@ def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), "$dst ^= asr($src2, $src3)", - [(set (i64 DoubleRegs:$dst), - (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2), - (i32 IntRegs:$src3))))], + [(set DoubleRegs:$dst, + (xor DoubleRegs:$src1, (sra DoubleRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4458,9 +2847,8 @@ def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), "$dst ^= lsl($src2, $src3)", - [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1), - (shl (i64 DoubleRegs:$src2), - (i32 IntRegs:$src3))))], + [(set DoubleRegs:$dst, + (xor DoubleRegs:$src1, (shl DoubleRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4468,9 +2856,8 @@ def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), "$dst ^= lsr($src2, $src3)", - [(set (i64 DoubleRegs:$dst), - (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2), - (i32 IntRegs:$src3))))], + [(set DoubleRegs:$dst, + (xor DoubleRegs:$src1, (srl DoubleRegs:$src2, IntRegs:$src3)))], "$src1 = $dst">, Requires<[HasV4T]>; @@ -4516,16 +2903,16 @@ let AddedComplexity = 30 in def MEMw_ADDSUBi_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_2Imm:$offset, m6Imm:$addend), "Error; should not emit", - [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)), - m6ImmPred:$addend), - (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>, + [(store (add (load (add IntRegs:$base, u6_2ImmPred:$offset)), +m6ImmPred:$addend), + (add IntRegs:$base, u6_2ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memw(Rs+#u6:2) += #U5 let AddedComplexity = 30 in def MEMw_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$addend), - "memw($base+#$offset) += #$addend", + "memw($base+#$offset) += $addend", []>, Requires<[HasV4T, UseMEMOP]>; @@ -4533,7 +2920,7 @@ def MEMw_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs), let AddedComplexity = 30 in def MEMw_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$subend), - "memw($base+#$offset) -= #$subend", + "memw($base+#$offset) -= $subend", []>, Requires<[HasV4T, UseMEMOP]>; @@ -4542,9 +2929,9 @@ let AddedComplexity = 30 in def MEMw_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$addend), "memw($base+#$offset) += $addend", - [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)), - (i32 IntRegs:$addend)), - (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>, + [(store (add (load (add IntRegs:$base, u6_2ImmPred:$offset)), +IntRegs:$addend), + (add IntRegs:$base, u6_2ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memw(Rs+#u6:2) -= Rt @@ -4552,19 +2939,19 @@ let AddedComplexity = 30 in def MEMw_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$subend), "memw($base+#$offset) -= $subend", - [(store (sub (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)), - (i32 IntRegs:$subend)), - (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>, + [(store (sub (load (add IntRegs:$base, u6_2ImmPred:$offset)), +IntRegs:$subend), + (add IntRegs:$base, u6_2ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memw(Rs+#u6:2) &= Rt let AddedComplexity = 30 in def MEMw_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$andend), - "memw($base+#$offset) &= $andend", - [(store (and (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)), - (i32 IntRegs:$andend)), - (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>, + "memw($base+#$offset) += $andend", + [(store (and (load (add IntRegs:$base, u6_2ImmPred:$offset)), +IntRegs:$andend), + (add IntRegs:$base, u6_2ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memw(Rs+#u6:2) |= Rt @@ -4572,9 +2959,9 @@ let AddedComplexity = 30 in def MEMw_ORr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$orend), "memw($base+#$offset) |= $orend", - [(store (or (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)), - (i32 IntRegs:$orend)), - (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>, + [(store (or (load (add IntRegs:$base, u6_2ImmPred:$offset)), + IntRegs:$orend), + (add IntRegs:$base, u6_2ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // MEMw_ADDSUBi_V4: @@ -4609,7 +2996,7 @@ let AddedComplexity = 30 in def MEMw_ADDr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$addend), "memw($addr) += $addend", - [(store (add (load ADDRriU6_2:$addr), (i32 IntRegs:$addend)), + [(store (add (load ADDRriU6_2:$addr), IntRegs:$addend), ADDRriU6_2:$addr)]>, Requires<[HasV4T, UseMEMOP]>; @@ -4618,7 +3005,7 @@ let AddedComplexity = 30 in def MEMw_SUBr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$subend), "memw($addr) -= $subend", - [(store (sub (load ADDRriU6_2:$addr), (i32 IntRegs:$subend)), + [(store (sub (load ADDRriU6_2:$addr), IntRegs:$subend), ADDRriU6_2:$addr)]>, Requires<[HasV4T, UseMEMOP]>; @@ -4627,7 +3014,7 @@ let AddedComplexity = 30 in def MEMw_ANDr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$andend), "memw($addr) &= $andend", - [(store (and (load ADDRriU6_2:$addr), (i32 IntRegs:$andend)), + [(store (and (load ADDRriU6_2:$addr), IntRegs:$andend), ADDRriU6_2:$addr)]>, Requires<[HasV4T, UseMEMOP]>; @@ -4636,8 +3023,8 @@ let AddedComplexity = 30 in def MEMw_ORr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$orend), "memw($addr) |= $orend", - [(store (or (load ADDRriU6_2:$addr), (i32 IntRegs:$orend)), - ADDRriU6_2:$addr)]>, + [(store (or (load ADDRriU6_2:$addr), IntRegs:$orend), +ADDRriU6_2:$addr)]>, Requires<[HasV4T, UseMEMOP]>; //===----------------------------------------------------------------------===// @@ -4673,10 +3060,10 @@ let AddedComplexity = 30 in def MEMh_ADDSUBi_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_1Imm:$offset, m6Imm:$addend), "Error; should not emit", - [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base), + [(truncstorei16 (add (sextloadi16 (add IntRegs:$base, u6_1ImmPred:$offset)), m6ImmPred:$addend), - (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>, + (add IntRegs:$base, u6_1ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memh(Rs+#u6:1) += #U5 @@ -4700,10 +3087,10 @@ let AddedComplexity = 30 in def MEMh_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$addend), "memh($base+#$offset) += $addend", - [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base), + [(truncstorei16 (add (sextloadi16 (add IntRegs:$base, u6_1ImmPred:$offset)), - (i32 IntRegs:$addend)), - (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>, + IntRegs:$addend), + (add IntRegs:$base, u6_1ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memh(Rs+#u6:1) -= Rt @@ -4711,10 +3098,10 @@ let AddedComplexity = 30 in def MEMh_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$subend), "memh($base+#$offset) -= $subend", - [(truncstorei16 (sub (sextloadi16 (add (i32 IntRegs:$base), + [(truncstorei16 (sub (sextloadi16 (add IntRegs:$base, u6_1ImmPred:$offset)), - (i32 IntRegs:$subend)), - (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>, + IntRegs:$subend), + (add IntRegs:$base, u6_1ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memh(Rs+#u6:1) &= Rt @@ -4722,10 +3109,10 @@ let AddedComplexity = 30 in def MEMh_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$andend), "memh($base+#$offset) += $andend", - [(truncstorei16 (and (sextloadi16 (add (i32 IntRegs:$base), + [(truncstorei16 (and (sextloadi16 (add IntRegs:$base, u6_1ImmPred:$offset)), - (i32 IntRegs:$andend)), - (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>, + IntRegs:$andend), + (add IntRegs:$base, u6_1ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memh(Rs+#u6:1) |= Rt @@ -4733,10 +3120,10 @@ let AddedComplexity = 30 in def MEMh_ORr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$orend), "memh($base+#$offset) |= $orend", - [(truncstorei16 (or (sextloadi16 (add (i32 IntRegs:$base), + [(truncstorei16 (or (sextloadi16 (add IntRegs:$base, u6_1ImmPred:$offset)), - (i32 IntRegs:$orend)), - (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>, + IntRegs:$orend), + (add IntRegs:$base, u6_1ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // MEMh_ADDSUBi_V4: @@ -4772,7 +3159,7 @@ def MEMh_ADDr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$addend), "memh($addr) += $addend", [(truncstorei16 (add (sextloadi16 ADDRriU6_1:$addr), - (i32 IntRegs:$addend)), ADDRriU6_1:$addr)]>, + IntRegs:$addend), ADDRriU6_1:$addr)]>, Requires<[HasV4T, UseMEMOP]>; // memh(Rs+#u6:1) -= Rt @@ -4781,7 +3168,7 @@ def MEMh_SUBr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$subend), "memh($addr) -= $subend", [(truncstorei16 (sub (sextloadi16 ADDRriU6_1:$addr), - (i32 IntRegs:$subend)), ADDRriU6_1:$addr)]>, + IntRegs:$subend), ADDRriU6_1:$addr)]>, Requires<[HasV4T, UseMEMOP]>; // memh(Rs+#u6:1) &= Rt @@ -4790,7 +3177,7 @@ def MEMh_ANDr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$andend), "memh($addr) &= $andend", [(truncstorei16 (and (sextloadi16 ADDRriU6_1:$addr), - (i32 IntRegs:$andend)), ADDRriU6_1:$addr)]>, + IntRegs:$andend), ADDRriU6_1:$addr)]>, Requires<[HasV4T, UseMEMOP]>; // memh(Rs+#u6:1) |= Rt @@ -4799,7 +3186,7 @@ def MEMh_ORr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$orend), "memh($addr) |= $orend", [(truncstorei16 (or (sextloadi16 ADDRriU6_1:$addr), - (i32 IntRegs:$orend)), ADDRriU6_1:$addr)]>, + IntRegs:$orend), ADDRriU6_1:$addr)]>, Requires<[HasV4T, UseMEMOP]>; @@ -4836,10 +3223,10 @@ let AddedComplexity = 30 in def MEMb_ADDSUBi_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_0Imm:$offset, m6Imm:$addend), "Error; should not emit", - [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base), + [(truncstorei8 (add (sextloadi8 (add IntRegs:$base, u6_0ImmPred:$offset)), m6ImmPred:$addend), - (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>, + (add IntRegs:$base, u6_0ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memb(Rs+#u6:0) += #U5 @@ -4863,10 +3250,10 @@ let AddedComplexity = 30 in def MEMb_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$addend), "memb($base+#$offset) += $addend", - [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base), + [(truncstorei8 (add (sextloadi8 (add IntRegs:$base, u6_0ImmPred:$offset)), - (i32 IntRegs:$addend)), - (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>, + IntRegs:$addend), + (add IntRegs:$base, u6_0ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memb(Rs+#u6:0) -= Rt @@ -4874,10 +3261,10 @@ let AddedComplexity = 30 in def MEMb_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$subend), "memb($base+#$offset) -= $subend", - [(truncstorei8 (sub (sextloadi8 (add (i32 IntRegs:$base), + [(truncstorei8 (sub (sextloadi8 (add IntRegs:$base, u6_0ImmPred:$offset)), - (i32 IntRegs:$subend)), - (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>, + IntRegs:$subend), + (add IntRegs:$base, u6_0ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memb(Rs+#u6:0) &= Rt @@ -4885,10 +3272,10 @@ let AddedComplexity = 30 in def MEMb_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$andend), "memb($base+#$offset) += $andend", - [(truncstorei8 (and (sextloadi8 (add (i32 IntRegs:$base), + [(truncstorei8 (and (sextloadi8 (add IntRegs:$base, u6_0ImmPred:$offset)), - (i32 IntRegs:$andend)), - (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>, + IntRegs:$andend), + (add IntRegs:$base, u6_0ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // memb(Rs+#u6:0) |= Rt @@ -4896,10 +3283,10 @@ let AddedComplexity = 30 in def MEMb_ORr_indexed_MEM_V4 : MEMInst_V4<(outs), (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$orend), "memb($base+#$offset) |= $orend", - [(truncstorei8 (or (sextloadi8 (add (i32 IntRegs:$base), + [(truncstorei8 (or (sextloadi8 (add IntRegs:$base, u6_0ImmPred:$offset)), - (i32 IntRegs:$orend)), - (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>, + IntRegs:$orend), + (add IntRegs:$base, u6_0ImmPred:$offset))]>, Requires<[HasV4T, UseMEMOP]>; // MEMb_ADDSUBi_V4: @@ -4935,7 +3322,7 @@ def MEMb_ADDr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$addend), "memb($addr) += $addend", [(truncstorei8 (add (sextloadi8 ADDRriU6_0:$addr), - (i32 IntRegs:$addend)), ADDRriU6_0:$addr)]>, + IntRegs:$addend), ADDRriU6_0:$addr)]>, Requires<[HasV4T, UseMEMOP]>; // memb(Rs+#u6:0) -= Rt @@ -4944,7 +3331,7 @@ def MEMb_SUBr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$subend), "memb($addr) -= $subend", [(truncstorei8 (sub (sextloadi8 ADDRriU6_0:$addr), - (i32 IntRegs:$subend)), ADDRriU6_0:$addr)]>, + IntRegs:$subend), ADDRriU6_0:$addr)]>, Requires<[HasV4T, UseMEMOP]>; // memb(Rs+#u6:0) &= Rt @@ -4953,7 +3340,7 @@ def MEMb_ANDr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$andend), "memb($addr) &= $andend", [(truncstorei8 (and (sextloadi8 ADDRriU6_0:$addr), - (i32 IntRegs:$andend)), ADDRriU6_0:$addr)]>, + IntRegs:$andend), ADDRriU6_0:$addr)]>, Requires<[HasV4T, UseMEMOP]>; // memb(Rs+#u6:0) |= Rt @@ -4962,7 +3349,7 @@ def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs), (ins MEMri:$addr, IntRegs:$orend), "memb($addr) |= $orend", [(truncstorei8 (or (sextloadi8 ADDRriU6_0:$addr), - (i32 IntRegs:$orend)), ADDRriU6_0:$addr)]>, + IntRegs:$orend), ADDRriU6_0:$addr)]>, Requires<[HasV4T, UseMEMOP]>; @@ -4977,16 +3364,13 @@ def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs), // The implemented patterns are: EQ/GT/GTU. // Missing patterns are: GE/GEU/LT/LTU/LE/LEU. -// Following instruction is not being extended as it results into the -// incorrect code for negative numbers. // Pd=cmpb.eq(Rs,#u8) - let isCompare = 1 in def CMPbEQri_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u8Imm:$src2), "$dst = cmpb.eq($src1, #$src2)", - [(set (i1 PredRegs:$dst), - (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>, + [(set PredRegs:$dst, (seteq (and IntRegs:$src1, 255), + u8ImmPred:$src2))]>, Requires<[HasV4T]>; // Pd=cmpb.eq(Rs,Rt) @@ -4994,9 +3378,10 @@ let isCompare = 1 in def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = cmpb.eq($src1, $src2)", - [(set (i1 PredRegs:$dst), - (seteq (and (xor (i32 IntRegs:$src1), - (i32 IntRegs:$src2)), 255), 0))]>, + [(set PredRegs:$dst, (seteq (and (xor IntRegs:$src1, + IntRegs:$src2), + 255), + 0))]>, Requires<[HasV4T]>; // Pd=cmpb.eq(Rs,Rt) @@ -5004,31 +3389,26 @@ let isCompare = 1 in def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = cmpb.eq($src1, $src2)", - [(set (i1 PredRegs:$dst), - (seteq (shl (i32 IntRegs:$src1), (i32 24)), - (shl (i32 IntRegs:$src2), (i32 24))))]>, + [(set PredRegs:$dst, (seteq (shl IntRegs:$src1, (i32 24)), + (shl IntRegs:$src2, (i32 24))))]>, Requires<[HasV4T]>; -/* Incorrect Pattern -- immediate should be right shifted before being -used in the cmpb.gt instruction. // Pd=cmpb.gt(Rs,#s8) let isCompare = 1 in def CMPbGTri_V4 : MInst<(outs PredRegs:$dst), - (ins IntRegs:$src1, s8Imm:$src2), + (ins IntRegs:$src1, s32Imm:$src2), "$dst = cmpb.gt($src1, #$src2)", - [(set (i1 PredRegs:$dst), (setgt (shl (i32 IntRegs:$src1), (i32 24)), - s8ImmPred:$src2))]>, + [(set PredRegs:$dst, (setgt (shl IntRegs:$src1, (i32 24)), + s32_24ImmPred:$src2))]>, Requires<[HasV4T]>; -*/ // Pd=cmpb.gt(Rs,Rt) let isCompare = 1 in def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = cmpb.gt($src1, $src2)", - [(set (i1 PredRegs:$dst), - (setgt (shl (i32 IntRegs:$src1), (i32 24)), - (shl (i32 IntRegs:$src2), (i32 24))))]>, + [(set PredRegs:$dst, (setgt (shl IntRegs:$src1, (i32 24)), + (shl IntRegs:$src2, (i32 24))))]>, Requires<[HasV4T]>; // Pd=cmpb.gtu(Rs,#u7) @@ -5036,8 +3416,8 @@ let isCompare = 1 in def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u7Imm:$src2), "$dst = cmpb.gtu($src1, #$src2)", - [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255), - u7ImmPred:$src2))]>, + [(set PredRegs:$dst, (setugt (and IntRegs:$src1, 255), + u7ImmPred:$src2))]>, Requires<[HasV4T]>; // Pd=cmpb.gtu(Rs,Rt) @@ -5045,21 +3425,18 @@ let isCompare = 1 in def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = cmpb.gtu($src1, $src2)", - [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255), - (and (i32 IntRegs:$src2), 255)))]>, + [(set PredRegs:$dst, (setugt (and IntRegs:$src1, 255), + (and IntRegs:$src2, 255)))]>, Requires<[HasV4T]>; -// Following instruction is not being extended as it results into the incorrect -// code for negative numbers. - // Signed half compare(.eq) ri. // Pd=cmph.eq(Rs,#s8) let isCompare = 1 in def CMPhEQri_V4 : MInst<(outs PredRegs:$dst), - (ins IntRegs:$src1, s8Imm:$src2), + (ins IntRegs:$src1, u16Imm:$src2), "$dst = cmph.eq($src1, #$src2)", - [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535), - s8ImmPred:$src2))]>, + [(set PredRegs:$dst, (seteq (and IntRegs:$src1, 65535), + u16_s8ImmPred:$src2))]>, Requires<[HasV4T]>; // Signed half compare(.eq) rr. @@ -5072,9 +3449,10 @@ let isCompare = 1 in def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = cmph.eq($src1, $src2)", - [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1), - (i32 IntRegs:$src2)), - 65535), 0))]>, + [(set PredRegs:$dst, (seteq (and (xor IntRegs:$src1, + IntRegs:$src2), + 65535), + 0))]>, Requires<[HasV4T]>; // Signed half compare(.eq) rr. @@ -5087,25 +3465,19 @@ let isCompare = 1 in def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = cmph.eq($src1, $src2)", - [(set (i1 PredRegs:$dst), - (seteq (shl (i32 IntRegs:$src1), (i32 16)), - (shl (i32 IntRegs:$src2), (i32 16))))]>, + [(set PredRegs:$dst, (seteq (shl IntRegs:$src1, (i32 16)), + (shl IntRegs:$src2, (i32 16))))]>, Requires<[HasV4T]>; -/* Incorrect Pattern -- immediate should be right shifted before being -used in the cmph.gt instruction. // Signed half compare(.gt) ri. // Pd=cmph.gt(Rs,#s8) - let isCompare = 1 in def CMPhGTri_V4 : MInst<(outs PredRegs:$dst), - (ins IntRegs:$src1, s8Imm:$src2), + (ins IntRegs:$src1, s32Imm:$src2), "$dst = cmph.gt($src1, #$src2)", - [(set (i1 PredRegs:$dst), - (setgt (shl (i32 IntRegs:$src1), (i32 16)), - s8ImmPred:$src2))]>, + [(set PredRegs:$dst, (setgt (shl IntRegs:$src1, (i32 16)), + s32_16s8ImmPred:$src2))]>, Requires<[HasV4T]>; -*/ // Signed half compare(.gt) rr. // Pd=cmph.gt(Rs,Rt) @@ -5113,9 +3485,8 @@ let isCompare = 1 in def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = cmph.gt($src1, $src2)", - [(set (i1 PredRegs:$dst), - (setgt (shl (i32 IntRegs:$src1), (i32 16)), - (shl (i32 IntRegs:$src2), (i32 16))))]>, + [(set PredRegs:$dst, (setgt (shl IntRegs:$src1, (i32 16)), + (shl IntRegs:$src2, (i32 16))))]>, Requires<[HasV4T]>; // Unsigned half compare rr (.gtu). @@ -5124,9 +3495,8 @@ let isCompare = 1 in def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = cmph.gtu($src1, $src2)", - [(set (i1 PredRegs:$dst), - (setugt (and (i32 IntRegs:$src1), 65535), - (and (i32 IntRegs:$src2), 65535)))]>, + [(set PredRegs:$dst, (setugt (and IntRegs:$src1, 65535), + (and IntRegs:$src2, 65535)))]>, Requires<[HasV4T]>; // Unsigned half compare ri (.gtu). @@ -5135,8 +3505,8 @@ let isCompare = 1 in def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u7Imm:$src2), "$dst = cmph.gtu($src1, #$src2)", - [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535), - u7ImmPred:$src2))]>, + [(set PredRegs:$dst, (setugt (and IntRegs:$src1, 65535), + u7ImmPred:$src2))]>, Requires<[HasV4T]>; //===----------------------------------------------------------------------===// @@ -5153,37 +3523,9 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1, Requires<[HasV4T]>; } -// Restore registers and dealloc return function call. -let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC] in { - def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs), (ins calltarget:$dst, variable_ops), - "jump $dst // Restore_and_dealloc_return", - []>, - Requires<[HasV4T]>; -} - -// Restore registers and dealloc frame before a tail call. -let isCall = 1, isBarrier = 1, - Defs = [R29, R30, R31, PC] in { - def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs), (ins calltarget:$dst, variable_ops), - "call $dst // Restore_and_dealloc_before_tailcall", - []>, - Requires<[HasV4T]>; -} - -// Save registers function call. -let isCall = 1, isBarrier = 1, - Uses = [R29, R31] in { - def SAVE_REGISTERS_CALL_V4 : JInst<(outs), (ins calltarget:$dst, variable_ops), - "call $dst // Save_calle_saved_registers", - []>, - Requires<[HasV4T]>; -} - // if (Ps) dealloc_return let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { + Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in { def DEALLOC_RET_cPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, i32imm:$amt1), "if ($src1) dealloc_return", []>, @@ -5192,8 +3534,7 @@ let isReturn = 1, isTerminator = 1, // if (!Ps) dealloc_return let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { + Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in { def DEALLOC_RET_cNotPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, i32imm:$amt1), "if (!$src1) dealloc_return", @@ -5203,8 +3544,7 @@ let isReturn = 1, isTerminator = 1, // if (Ps.new) dealloc_return:nt let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { + Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in { def DEALLOC_RET_cdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, i32imm:$amt1), "if ($src1.new) dealloc_return:nt", @@ -5214,8 +3554,7 @@ let isReturn = 1, isTerminator = 1, // if (!Ps.new) dealloc_return:nt let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { + Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in { def DEALLOC_RET_cNotdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, i32imm:$amt1), "if (!$src1.new) dealloc_return:nt", @@ -5225,8 +3564,7 @@ let isReturn = 1, isTerminator = 1, // if (Ps.new) dealloc_return:t let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { + Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in { def DEALLOC_RET_cdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, i32imm:$amt1), "if ($src1.new) dealloc_return:t", @@ -5236,511 +3574,10 @@ let isReturn = 1, isTerminator = 1, // if (!Ps.new) dealloc_return:nt let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { + Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in { def DEALLOC_RET_cNotdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, i32imm:$amt1), "if (!$src1.new) dealloc_return:t", []>, Requires<[HasV4T]>; } - - -// Load/Store with absolute addressing mode -// memw(#u6)=Rt - -multiclass ST_abs<string OpcStr> { - let isPredicable = 1 in - def _abs_V4 : STInst<(outs), - (ins globaladdress:$absaddr, IntRegs:$src), - !strconcat(OpcStr, "(##$absaddr) = $src"), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, IntRegs:$src2), - !strconcat("if ($src1)", !strconcat(OpcStr, "(##$absaddr) = $src2")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, IntRegs:$src2), - !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$absaddr) = $src2")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, IntRegs:$src2), - !strconcat("if ($src1.new)", !strconcat(OpcStr, "(##$absaddr) = $src2")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, IntRegs:$src2), - !strconcat("if (!$src1.new)", !strconcat(OpcStr, "(##$absaddr) = $src2")), - []>, - Requires<[HasV4T]>; - - def _abs_nv_V4 : STInst<(outs), - (ins globaladdress:$absaddr, IntRegs:$src), - !strconcat(OpcStr, "(##$absaddr) = $src.new"), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cPt_nv_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, IntRegs:$src2), - !strconcat("if ($src1)", !strconcat(OpcStr, "(##$absaddr) = $src2.new")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cNotPt_nv_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, IntRegs:$src2), - !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$absaddr) = $src2.new")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnPt_nv_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, IntRegs:$src2), - !strconcat("if ($src1.new)", !strconcat(OpcStr, "(##$absaddr) = $src2.new")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnNotPt_nv_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, IntRegs:$src2), - !strconcat("if (!$src1.new)", !strconcat(OpcStr, "(##$absaddr) = $src2.new")), - []>, - Requires<[HasV4T]>; -} - -let AddedComplexity = 30, isPredicable = 1 in -def STrid_abs_V4 : STInst<(outs), - (ins globaladdress:$absaddr, DoubleRegs:$src), - "memd(##$absaddr) = $src", - [(store (i64 DoubleRegs:$src), (HexagonCONST32 tglobaladdr:$absaddr))]>, - Requires<[HasV4T]>; - -let AddedComplexity = 30, isPredicated = 1 in -def STrid_abs_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, DoubleRegs:$src2), - "if ($src1) memd(##$absaddr) = $src2", - []>, - Requires<[HasV4T]>; - -let AddedComplexity = 30, isPredicated = 1 in -def STrid_abs_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, DoubleRegs:$src2), - "if (!$src1) memd(##$absaddr) = $src2", - []>, - Requires<[HasV4T]>; - -let AddedComplexity = 30, isPredicated = 1 in -def STrid_abs_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, DoubleRegs:$src2), - "if ($src1.new) memd(##$absaddr) = $src2", - []>, - Requires<[HasV4T]>; - -let AddedComplexity = 30, isPredicated = 1 in -def STrid_abs_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, globaladdress:$absaddr, DoubleRegs:$src2), - "if (!$src1.new) memd(##$absaddr) = $src2", - []>, - Requires<[HasV4T]>; - -defm STrib : ST_abs<"memb">; -defm STrih : ST_abs<"memh">; -defm STriw : ST_abs<"memw">; - -let Predicates = [HasV4T], AddedComplexity = 30 in -def : Pat<(truncstorei8 (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)), - (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; - -let Predicates = [HasV4T], AddedComplexity = 30 in -def : Pat<(truncstorei16 (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)), - (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; - -let Predicates = [HasV4T], AddedComplexity = 30 in -def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)), - (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; - - -multiclass LD_abs<string OpcStr> { - let isPredicable = 1 in - def _abs_V4 : LDInst<(outs IntRegs:$dst), - (ins globaladdress:$absaddr), - !strconcat("$dst = ", !strconcat(OpcStr, "(##$absaddr)")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$absaddr), - !strconcat("if ($src1) $dst = ", !strconcat(OpcStr, "(##$absaddr)")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$absaddr), - !strconcat("if (!$src1) $dst = ", !strconcat(OpcStr, "(##$absaddr)")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$absaddr), - !strconcat("if ($src1.new) $dst = ", !strconcat(OpcStr, "(##$absaddr)")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$absaddr), - !strconcat("if (!$src1.new) $dst = ", !strconcat(OpcStr, "(##$absaddr)")), - []>, - Requires<[HasV4T]>; -} - -let AddedComplexity = 30 in -def LDrid_abs_V4 : LDInst<(outs DoubleRegs:$dst), - (ins globaladdress:$absaddr), - "$dst = memd(##$absaddr)", - [(set (i64 DoubleRegs:$dst), (load (HexagonCONST32 tglobaladdr:$absaddr)))]>, - Requires<[HasV4T]>; - -let AddedComplexity = 30, isPredicated = 1 in -def LDrid_abs_cPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$absaddr), - "if ($src1) $dst = memd(##$absaddr)", - []>, - Requires<[HasV4T]>; - -let AddedComplexity = 30, isPredicated = 1 in -def LDrid_abs_cNotPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$absaddr), - "if (!$src1) $dst = memd(##$absaddr)", - []>, - Requires<[HasV4T]>; - -let AddedComplexity = 30, isPredicated = 1 in -def LDrid_abs_cdnPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$absaddr), - "if ($src1.new) $dst = memd(##$absaddr)", - []>, - Requires<[HasV4T]>; - -let AddedComplexity = 30, isPredicated = 1 in -def LDrid_abs_cdnNotPt_V4 : LDInst<(outs DoubleRegs:$dst), - (ins PredRegs:$src1, globaladdress:$absaddr), - "if (!$src1.new) $dst = memd(##$absaddr)", - []>, - Requires<[HasV4T]>; - -defm LDrib : LD_abs<"memb">; -defm LDriub : LD_abs<"memub">; -defm LDrih : LD_abs<"memh">; -defm LDriuh : LD_abs<"memuh">; -defm LDriw : LD_abs<"memw">; - - -let Predicates = [HasV4T], AddedComplexity = 30 in -def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))), - (LDriw_abs_V4 tglobaladdr: $absaddr)>; - -let Predicates = [HasV4T], AddedComplexity=30 in -def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), - (LDrib_abs_V4 tglobaladdr:$absaddr)>; - -let Predicates = [HasV4T], AddedComplexity=30 in -def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), - (LDriub_abs_V4 tglobaladdr:$absaddr)>; - -let Predicates = [HasV4T], AddedComplexity=30 in -def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), - (LDrih_abs_V4 tglobaladdr:$absaddr)>; - -let Predicates = [HasV4T], AddedComplexity=30 in -def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), - (LDriuh_abs_V4 tglobaladdr:$absaddr)>; - -// Transfer global address into a register -let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in -def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1), - "$dst = ##$src1", - [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>, - Requires<[HasV4T]>; - -let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in -def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$src2), - "if($src1) $dst = ##$src2", - []>, - Requires<[HasV4T]>; - -let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in -def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$src2), - "if(!$src1) $dst = ##$src2", - []>, - Requires<[HasV4T]>; - -let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in -def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$src2), - "if($src1.new) $dst = ##$src2", - []>, - Requires<[HasV4T]>; - -let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in -def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$src2), - "if(!$src1.new) $dst = ##$src2", - []>, - Requires<[HasV4T]>; - -let AddedComplexity = 50, Predicates = [HasV4T] in -def : Pat<(HexagonCONST32_GP tglobaladdr:$src1), - (TFRI_V4 tglobaladdr:$src1)>; - - -// Load - Indirect with long offset: These instructions take global address -// as an operand -let AddedComplexity = 10 in -def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst), - (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset), - "$dst=memd($src1<<#$src2+##$offset)", - [(set (i64 DoubleRegs:$dst), - (load (add (shl IntRegs:$src1, u2ImmPred:$src2), - (HexagonCONST32 tglobaladdr:$offset))))]>, - Requires<[HasV4T]>; - -let AddedComplexity = 10 in -multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> { - def _lo_V4 : LDInst<(outs IntRegs:$dst), - (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset), - !strconcat("$dst = ", !strconcat(OpcStr, "($src1<<#$src2+##$offset)")), - [(set IntRegs:$dst, - (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2), - (HexagonCONST32 tglobaladdr:$offset)))))]>, - Requires<[HasV4T]>; -} - -defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>; -defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>; -defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>; -defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>; -defm LDriw_ind : LD_indirect_lo<"memw", load>; - -// Store - Indirect with long offset: These instructions take global address -// as an operand -let AddedComplexity = 10 in -def STrid_ind_lo_V4 : STInst<(outs), - (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3, - DoubleRegs:$src4), - "memd($src1<<#$src2+#$src3) = $src4", - [(store (i64 DoubleRegs:$src4), - (add (shl IntRegs:$src1, u2ImmPred:$src2), - (HexagonCONST32 tglobaladdr:$src3)))]>, - Requires<[HasV4T]>; - -let AddedComplexity = 10 in -multiclass ST_indirect_lo<string OpcStr, PatFrag OpNode> { - def _lo_V4 : STInst<(outs), - (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3, - IntRegs:$src4), - !strconcat(OpcStr, "($src1<<#$src2+##$src3) = $src4"), - [(OpNode (i32 IntRegs:$src4), - (add (shl IntRegs:$src1, u2ImmPred:$src2), - (HexagonCONST32 tglobaladdr:$src3)))]>, - Requires<[HasV4T]>; -} - -defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>; -defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>; -defm STriw_ind : ST_indirect_lo<"memw", store>; - -// Store - absolute addressing mode: These instruction take constant -// value as the extended operand -multiclass ST_absimm<string OpcStr> { - let isPredicable = 1 in - def _abs_V4 : STInst<(outs), - (ins u6Imm:$src1, IntRegs:$src2), - !strconcat(OpcStr, "(#$src1) = $src2"), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cPt_V4 : STInst<(outs), - (ins PredRegs:$src1, u6Imm:$src2, IntRegs:$src3), - !strconcat("if ($src1)", !strconcat(OpcStr, "(#$src2) = $src3")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, u6Imm:$src2, IntRegs:$src3), - !strconcat("if (!$src1)", !strconcat(OpcStr, "(#$src2) = $src3")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnPt_V4 : STInst<(outs), - (ins PredRegs:$src1, u6Imm:$src2, IntRegs:$src3), - !strconcat("if ($src1.new)", !strconcat(OpcStr, "(#$src2) = $src3")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnNotPt_V4 : STInst<(outs), - (ins PredRegs:$src1, u6Imm:$src2, IntRegs:$src3), - !strconcat("if (!$src1.new)", !strconcat(OpcStr, "(#$src2) = $src3")), - []>, - Requires<[HasV4T]>; - - def _abs_nv_V4 : STInst<(outs), - (ins u6Imm:$src1, IntRegs:$src2), - !strconcat(OpcStr, "(#$src1) = $src2.new"), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cPt_nv_V4 : STInst<(outs), - (ins PredRegs:$src1, u6Imm:$src2, IntRegs:$src3), - !strconcat("if ($src1)", !strconcat(OpcStr, "(#$src2) = $src3.new")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cNotPt_nv_V4 : STInst<(outs), - (ins PredRegs:$src1, u6Imm:$src2, IntRegs:$src3), - !strconcat("if (!$src1)", !strconcat(OpcStr, "(#$src2) = $src3.new")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnPt_nv_V4 : STInst<(outs), - (ins PredRegs:$src1, u6Imm:$src2, IntRegs:$src3), - !strconcat("if ($src1.new)", !strconcat(OpcStr, "(#$src2) = $src3.new")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnNotPt_nv_V4 : STInst<(outs), - (ins PredRegs:$src1, u6Imm:$src2, IntRegs:$src3), - !strconcat("if (!$src1.new)", !strconcat(OpcStr, "(#$src2) = $src3.new")), - []>, - Requires<[HasV4T]>; -} - -defm STrib_imm : ST_absimm<"memb">; -defm STrih_imm : ST_absimm<"memh">; -defm STriw_imm : ST_absimm<"memw">; - -let Predicates = [HasV4T], AddedComplexity = 30 in -def : Pat<(truncstorei8 (i32 IntRegs:$src1), u6ImmPred:$src2), - (STrib_imm_abs_V4 u6ImmPred:$src2, IntRegs: $src1)>; - -let Predicates = [HasV4T], AddedComplexity = 30 in -def : Pat<(truncstorei16 (i32 IntRegs:$src1), u6ImmPred:$src2), - (STrih_imm_abs_V4 u6ImmPred:$src2, IntRegs: $src1)>; - -let Predicates = [HasV4T], AddedComplexity = 30 in -def : Pat<(store (i32 IntRegs:$src1), u6ImmPred:$src2), - (STriw_imm_abs_V4 u6ImmPred:$src2, IntRegs: $src1)>; - - -// Load - absolute addressing mode: These instruction take constant -// value as the extended operand - -multiclass LD_absimm<string OpcStr> { - let isPredicable = 1 in - def _abs_V4 : LDInst<(outs IntRegs:$dst), - (ins u6Imm:$src), - !strconcat("$dst = ", !strconcat(OpcStr, "(#$src)")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, u6Imm:$src2), - !strconcat("if ($src1) $dst = ", !strconcat(OpcStr, "(#$src2)")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, u6Imm:$src2), - !strconcat("if (!$src1) $dst = ", !strconcat(OpcStr, "(#$src2)")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, u6Imm:$src2), - !strconcat("if ($src1.new) $dst = ", !strconcat(OpcStr, "(#$src2)")), - []>, - Requires<[HasV4T]>; - - let isPredicated = 1 in - def _abs_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), - (ins PredRegs:$src1, u6Imm:$src2), - !strconcat("if (!$src1.new) $dst = ", !strconcat(OpcStr, "(#$src2)")), - []>, - Requires<[HasV4T]>; -} - -defm LDrib_imm : LD_absimm<"memb">; -defm LDriub_imm : LD_absimm<"memub">; -defm LDrih_imm : LD_absimm<"memh">; -defm LDriuh_imm : LD_absimm<"memuh">; -defm LDriw_imm : LD_absimm<"memw">; - -let Predicates = [HasV4T], AddedComplexity = 30 in -def : Pat<(i32 (load u6ImmPred:$src)), - (LDriw_imm_abs_V4 u6ImmPred:$src)>; - -let Predicates = [HasV4T], AddedComplexity=30 in -def : Pat<(i32 (sextloadi8 u6ImmPred:$src)), - (LDrib_imm_abs_V4 u6ImmPred:$src)>; - -let Predicates = [HasV4T], AddedComplexity=30 in -def : Pat<(i32 (zextloadi8 u6ImmPred:$src)), - (LDriub_imm_abs_V4 u6ImmPred:$src)>; - -let Predicates = [HasV4T], AddedComplexity=30 in -def : Pat<(i32 (sextloadi16 u6ImmPred:$src)), - (LDrih_imm_abs_V4 u6ImmPred:$src)>; - -let Predicates = [HasV4T], AddedComplexity=30 in -def : Pat<(i32 (zextloadi16 u6ImmPred:$src)), - (LDriuh_imm_abs_V4 u6ImmPred:$src)>; - - -// Indexed store double word - global address. -// memw(Rs+#u6:2)=#S8 -let AddedComplexity = 10 in -def STriw_offset_ext_V4 : STInst<(outs), - (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3), - "memw($src1+#$src2) = ##$src3", - [(store (HexagonCONST32 tglobaladdr:$src3), - (add IntRegs:$src1, u6_2ImmPred:$src2))]>, - Requires<[HasV4T]>; - - -// Indexed store double word - global address. -// memw(Rs+#u6:2)=#S8 -let AddedComplexity = 10 in -def STrih_offset_ext_V4 : STInst<(outs), - (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3), - "memh($src1+#$src2) = ##$src3", - [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3), - (add IntRegs:$src1, u6_1ImmPred:$src2))]>, - Requires<[HasV4T]>; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonMCInst.h b/contrib/llvm/lib/Target/Hexagon/HexagonMCInst.h deleted file mode 100644 index 16ea7cf..0000000 --- a/contrib/llvm/lib/Target/Hexagon/HexagonMCInst.h +++ /dev/null @@ -1,41 +0,0 @@ -//===- HexagonMCInst.h - Hexagon sub-class of MCInst ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class extends MCInst to allow some VLIW annotation. -// -//===----------------------------------------------------------------------===// - -#ifndef HEXAGONMCINST_H -#define HEXAGONMCINST_H - -#include "llvm/MC/MCInst.h" -#include "llvm/CodeGen/MachineInstr.h" - -namespace llvm { - class HexagonMCInst: public MCInst { - // Packet start and end markers - unsigned startPacket: 1, endPacket: 1; - const MachineInstr *MachineI; - public: - explicit HexagonMCInst(): MCInst(), - startPacket(0), endPacket(0) {} - - const MachineInstr* getMI() const { return MachineI; }; - - void setMI(const MachineInstr *MI) { MachineI = MI; }; - - bool isStartPacket() const { return (startPacket); }; - bool isEndPacket() const { return (endPacket); }; - - void setStartPacket(bool yes) { startPacket = yes; }; - void setEndPacket(bool yes) { endPacket = yes; }; - }; -} - -#endif diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp index 70bddcc..fbb331b 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp @@ -49,7 +49,7 @@ void llvm::HexagonLowerToMC(const MachineInstr* MI, MCInst& MCI, switch (MO.getType()) { default: MI->dump(); - llvm_unreachable("unknown operand type"); + assert(0 && "unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. if (MO.isImplicit()) continue; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonSchedule.td b/contrib/llvm/lib/Target/Hexagon/HexagonSchedule.td index c488796..fbea445 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonSchedule.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonSchedule.td @@ -13,6 +13,7 @@ def LSUNIT : FuncUnit; def MUNIT : FuncUnit; def SUNIT : FuncUnit; + // Itinerary classes def ALU32 : InstrItinClass; def ALU64 : InstrItinClass; @@ -23,25 +24,23 @@ def LD : InstrItinClass; def M : InstrItinClass; def ST : InstrItinClass; def S : InstrItinClass; -def SYS : InstrItinClass; -def MARKER : InstrItinClass; def PSEUDO : InstrItinClass; + def HexagonItineraries : - ProcessorItineraries<[LUNIT, LSUNIT, MUNIT, SUNIT], [], [ - InstrItinData<ALU32 , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>, - InstrItinData<ALU64 , [InstrStage<1, [MUNIT, SUNIT]>]>, - InstrItinData<CR , [InstrStage<1, [SUNIT]>]>, - InstrItinData<J , [InstrStage<1, [SUNIT, MUNIT]>]>, - InstrItinData<JR , [InstrStage<1, [MUNIT]>]>, - InstrItinData<LD , [InstrStage<1, [LUNIT, LSUNIT]>]>, - InstrItinData<M , [InstrStage<1, [MUNIT, SUNIT]>]>, - InstrItinData<ST , [InstrStage<1, [LSUNIT]>]>, - InstrItinData<S , [InstrStage<1, [SUNIT, MUNIT]>]>, - InstrItinData<SYS , [InstrStage<1, [LSUNIT]>]>, - InstrItinData<MARKER , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>, - InstrItinData<PSEUDO , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]> - ]>; + ProcessorItineraries<[LUNIT, LSUNIT, MUNIT, SUNIT], [], [ + InstrItinData<ALU32 , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>, + InstrItinData<ALU64 , [InstrStage<1, [MUNIT, SUNIT]>]>, + InstrItinData<CR , [InstrStage<1, [SUNIT]>]>, + InstrItinData<J , [InstrStage<1, [SUNIT, MUNIT]>]>, + InstrItinData<JR , [InstrStage<1, [MUNIT]>]>, + InstrItinData<LD , [InstrStage<1, [LUNIT, LSUNIT]>]>, + InstrItinData<M , [InstrStage<1, [MUNIT, SUNIT]>]>, + InstrItinData<ST , [InstrStage<1, [LSUNIT]>]>, + InstrItinData<S , [InstrStage<1, [SUNIT, MUNIT]>]>, + InstrItinData<PSEUDO , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]> +]>; + //===----------------------------------------------------------------------===// // V4 Machine Info + diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonScheduleV4.td b/contrib/llvm/lib/Target/Hexagon/HexagonScheduleV4.td index 1d82dbb..4cf66fe 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonScheduleV4.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonScheduleV4.td @@ -23,6 +23,7 @@ // | SLOT3 | XTYPE ALU32 J CR | // |===========|==================================================| + // Functional Units. def SLOT0 : FuncUnit; def SLOT1 : FuncUnit; @@ -33,26 +34,22 @@ def SLOT3 : FuncUnit; def NV_V4 : InstrItinClass; def MEM_V4 : InstrItinClass; // ALU64/M/S Instruction classes of V2 are collectively knownn as XTYPE in V4. -def PREFIX : InstrItinClass; -def HexagonItinerariesV4 : - ProcessorItineraries<[SLOT0, SLOT1, SLOT2, SLOT3], [], [ - InstrItinData<ALU32 , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, - InstrItinData<ALU64 , [InstrStage<1, [SLOT2, SLOT3]>]>, - InstrItinData<CR , [InstrStage<1, [SLOT3]>]>, - InstrItinData<J , [InstrStage<1, [SLOT2, SLOT3]>]>, - InstrItinData<JR , [InstrStage<1, [SLOT2]>]>, - InstrItinData<LD , [InstrStage<1, [SLOT0, SLOT1]>]>, - InstrItinData<M , [InstrStage<1, [SLOT2, SLOT3]>]>, - InstrItinData<ST , [InstrStage<1, [SLOT0, SLOT1]>]>, - InstrItinData<S , [InstrStage<1, [SLOT2, SLOT3]>]>, - InstrItinData<SYS , [InstrStage<1, [SLOT0]>]>, - InstrItinData<NV_V4 , [InstrStage<1, [SLOT0]>]>, - InstrItinData<MEM_V4 , [InstrStage<1, [SLOT0]>]>, - InstrItinData<MARKER , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, - InstrItinData<PREFIX , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, - InstrItinData<PSEUDO , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]> - ]>; +def HexagonItinerariesV4 : ProcessorItineraries< + [SLOT0, SLOT1, SLOT2, SLOT3], [], [ + InstrItinData<LD , [InstrStage<1, [SLOT0, SLOT1]>]>, + InstrItinData<ST , [InstrStage<1, [SLOT0, SLOT1]>]>, + InstrItinData<ALU32 , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + InstrItinData<NV_V4 , [InstrStage<1, [SLOT0]>]>, + InstrItinData<MEM_V4 , [InstrStage<1, [SLOT0]>]>, + InstrItinData<J , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<JR , [InstrStage<1, [SLOT2]>]>, + InstrItinData<CR , [InstrStage<1, [SLOT3]>]>, + InstrItinData<PSEUDO , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + InstrItinData<ALU64 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<M , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S , [InstrStage<1, [SLOT2, SLOT3]>]> +]>; //===----------------------------------------------------------------------===// // Hexagon V4 Resource Definitions - diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp index 411325b..55bbba7 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -100,23 +100,23 @@ TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { } bool HexagonPassConfig::addInstSelector() { - PM.add(createHexagonRemoveExtendOps(getHexagonTargetMachine())); - PM.add(createHexagonISelDag(getHexagonTargetMachine())); - PM.add(createHexagonPeephole()); + PM->add(createHexagonRemoveExtendOps(getHexagonTargetMachine())); + PM->add(createHexagonISelDag(getHexagonTargetMachine())); + PM->add(createHexagonPeephole()); return false; } bool HexagonPassConfig::addPreRegAlloc() { if (!DisableHardwareLoops) { - PM.add(createHexagonHardwareLoops()); + PM->add(createHexagonHardwareLoops()); } return false; } bool HexagonPassConfig::addPostRegAlloc() { - PM.add(createHexagonCFGOptimizer(getHexagonTargetMachine())); + PM->add(createHexagonCFGOptimizer(getHexagonTargetMachine())); return true; } @@ -129,17 +129,14 @@ bool HexagonPassConfig::addPreSched2() { bool HexagonPassConfig::addPreEmitPass() { if (!DisableHardwareLoops) { - PM.add(createHexagonFixupHwLoops()); + PM->add(createHexagonFixupHwLoops()); } // Expand Spill code for predicate registers. - PM.add(createHexagonExpandPredSpillCode(getHexagonTargetMachine())); + PM->add(createHexagonExpandPredSpillCode(getHexagonTargetMachine())); // Split up TFRcondsets into conditional transfers. - PM.add(createHexagonSplitTFRCondSets(getHexagonTargetMachine())); - - // Create Packets. - PM.add(createHexagonPacketizer()); + PM->add(createHexagonSplitTFRCondSets(getHexagonTargetMachine())); return false; } diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp deleted file mode 100644 index c6e7bd1..0000000 --- a/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ /dev/null @@ -1,3642 +0,0 @@ -//===----- HexagonPacketizer.cpp - vliw packetizer ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This implements a simple VLIW packetizer using DFA. The packetizer works on -// machine basic blocks. For each instruction I in BB, the packetizer consults -// the DFA to see if machine resources are available to execute I. If so, the -// packetizer checks if I depends on any instruction J in the current packet. -// If no dependency is found, I is added to current packet and machine resource -// is marked as taken. If any dependency is found, a target API call is made to -// prune the dependence. -// -//===----------------------------------------------------------------------===// -#define DEBUG_TYPE "packets" -#include "llvm/CodeGen/DFAPacketizer.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineLoopInfo.h" -#include "llvm/CodeGen/ScheduleDAG.h" -#include "llvm/CodeGen/ScheduleDAGInstrs.h" -#include "llvm/CodeGen/LatencyPriorityQueue.h" -#include "llvm/CodeGen/SchedulerRegistry.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/MachineFunctionAnalysis.h" -#include "llvm/CodeGen/ScheduleHazardRecognizer.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/MC/MCInstrItineraries.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "Hexagon.h" -#include "HexagonTargetMachine.h" -#include "HexagonRegisterInfo.h" -#include "HexagonSubtarget.h" -#include "HexagonMachineFunctionInfo.h" - -#include <map> - -using namespace llvm; - -namespace { - class HexagonPacketizer : public MachineFunctionPass { - - public: - static char ID; - HexagonPacketizer() : MachineFunctionPass(ID) {} - - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); - AU.addRequired<MachineDominatorTree>(); - AU.addPreserved<MachineDominatorTree>(); - AU.addRequired<MachineLoopInfo>(); - AU.addPreserved<MachineLoopInfo>(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - const char *getPassName() const { - return "Hexagon Packetizer"; - } - - bool runOnMachineFunction(MachineFunction &Fn); - }; - char HexagonPacketizer::ID = 0; - - class HexagonPacketizerList : public VLIWPacketizerList { - - private: - - // Has the instruction been promoted to a dot-new instruction. - bool PromotedToDotNew; - - // Has the instruction been glued to allocframe. - bool GlueAllocframeStore; - - // Has the feeder instruction been glued to new value jump. - bool GlueToNewValueJump; - - // Check if there is a dependence between some instruction already in this - // packet and this instruction. - bool Dependence; - - // Only check for dependence if there are resources available to - // schedule this instruction. - bool FoundSequentialDependence; - - public: - // Ctor. - HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, - MachineDominatorTree &MDT); - - // initPacketizerState - initialize some internal flags. - void initPacketizerState(); - - // ignorePseudoInstruction - Ignore bundling of pseudo instructions. - bool ignorePseudoInstruction(MachineInstr *MI, MachineBasicBlock *MBB); - - // isSoloInstruction - return true if instruction MI can not be packetized - // with any other instruction, which means that MI itself is a packet. - bool isSoloInstruction(MachineInstr *MI); - - // isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ - // together. - bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ); - - // isLegalToPruneDependencies - Is it legal to prune dependece between SUI - // and SUJ. - bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ); - - MachineBasicBlock::iterator addToPacket(MachineInstr *MI); - private: - bool IsCallDependent(MachineInstr* MI, SDep::Kind DepType, unsigned DepReg); - bool PromoteToDotNew(MachineInstr* MI, SDep::Kind DepType, - MachineBasicBlock::iterator &MII, - const TargetRegisterClass* RC); - bool CanPromoteToDotNew(MachineInstr* MI, SUnit* PacketSU, - unsigned DepReg, - std::map <MachineInstr*, SUnit*> MIToSUnit, - MachineBasicBlock::iterator &MII, - const TargetRegisterClass* RC); - bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU, - unsigned DepReg, - std::map <MachineInstr*, SUnit*> MIToSUnit, - MachineBasicBlock::iterator &MII); - bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI, - unsigned DepReg, - std::map <MachineInstr*, SUnit*> MIToSUnit); - bool DemoteToDotOld(MachineInstr* MI); - bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2, - std::map <MachineInstr*, SUnit*> MIToSUnit); - bool RestrictingDepExistInPacket(MachineInstr*, - unsigned, std::map <MachineInstr*, SUnit*>); - bool isNewifiable(MachineInstr* MI); - bool isCondInst(MachineInstr* MI); - bool IsNewifyStore (MachineInstr* MI); - bool tryAllocateResourcesForConstExt(MachineInstr* MI); - bool canReserveResourcesForConstExt(MachineInstr *MI); - void reserveResourcesForConstExt(MachineInstr* MI); - bool isNewValueInst(MachineInstr* MI); - bool isDotNewInst(MachineInstr* MI); - }; -} - -// HexagonPacketizerList Ctor. -HexagonPacketizerList::HexagonPacketizerList( - MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT) - : VLIWPacketizerList(MF, MLI, MDT, true){ -} - -bool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) { - const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); - MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); - MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); - - // Instantiate the packetizer. - HexagonPacketizerList Packetizer(Fn, MLI, MDT); - - // DFA state table should not be empty. - assert(Packetizer.getResourceTracker() && "Empty DFA table!"); - - // - // Loop over all basic blocks and remove KILL pseudo-instructions - // These instructions confuse the dependence analysis. Consider: - // D0 = ... (Insn 0) - // R0 = KILL R0, D0 (Insn 1) - // R0 = ... (Insn 2) - // Here, Insn 1 will result in the dependence graph not emitting an output - // dependence between Insn 0 and Insn 2. This can lead to incorrect - // packetization - // - for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); - MBB != MBBe; ++MBB) { - MachineBasicBlock::iterator End = MBB->end(); - MachineBasicBlock::iterator MI = MBB->begin(); - while (MI != End) { - if (MI->isKill()) { - MachineBasicBlock::iterator DeleteMI = MI; - ++MI; - MBB->erase(DeleteMI); - End = MBB->end(); - continue; - } - ++MI; - } - } - - // Loop over all of the basic blocks. - for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); - MBB != MBBe; ++MBB) { - // Find scheduling regions and schedule / packetize each region. - unsigned RemainingCount = MBB->size(); - for(MachineBasicBlock::iterator RegionEnd = MBB->end(); - RegionEnd != MBB->begin();) { - // The next region starts above the previous region. Look backward in the - // instruction stream until we find the nearest boundary. - MachineBasicBlock::iterator I = RegionEnd; - for(;I != MBB->begin(); --I, --RemainingCount) { - if (TII->isSchedulingBoundary(llvm::prior(I), MBB, Fn)) - break; - } - I = MBB->begin(); - - // Skip empty scheduling regions. - if (I == RegionEnd) { - RegionEnd = llvm::prior(RegionEnd); - --RemainingCount; - continue; - } - // Skip regions with one instruction. - if (I == llvm::prior(RegionEnd)) { - RegionEnd = llvm::prior(RegionEnd); - continue; - } - - Packetizer.PacketizeMIs(MBB, I, RegionEnd); - RegionEnd = I; - } - } - - return true; -} - - -static bool IsIndirectCall(MachineInstr* MI) { - return ((MI->getOpcode() == Hexagon::CALLR) || - (MI->getOpcode() == Hexagon::CALLRv3)); -} - -// Reserve resources for constant extender. Trigure an assertion if -// reservation fail. -void HexagonPacketizerList::reserveResourcesForConstExt(MachineInstr* MI) { - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - MachineInstr *PseudoMI = MI->getParent()->getParent()->CreateMachineInstr( - QII->get(Hexagon::IMMEXT), MI->getDebugLoc()); - - if (ResourceTracker->canReserveResources(PseudoMI)) { - ResourceTracker->reserveResources(PseudoMI); - MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); - } else { - MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); - llvm_unreachable("can not reserve resources for constant extender."); - } - return; -} - -bool HexagonPacketizerList::canReserveResourcesForConstExt(MachineInstr *MI) { - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - assert(QII->isExtended(MI) && - "Should only be called for constant extended instructions"); - MachineFunction *MF = MI->getParent()->getParent(); - MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT), - MI->getDebugLoc()); - bool CanReserve = ResourceTracker->canReserveResources(PseudoMI); - MF->DeleteMachineInstr(PseudoMI); - return CanReserve; -} - -// Allocate resources (i.e. 4 bytes) for constant extender. If succeed, return -// true, otherwise, return false. -bool HexagonPacketizerList::tryAllocateResourcesForConstExt(MachineInstr* MI) { - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - MachineInstr *PseudoMI = MI->getParent()->getParent()->CreateMachineInstr( - QII->get(Hexagon::IMMEXT), MI->getDebugLoc()); - - if (ResourceTracker->canReserveResources(PseudoMI)) { - ResourceTracker->reserveResources(PseudoMI); - MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); - return true; - } else { - MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); - return false; - } -} - - -bool HexagonPacketizerList::IsCallDependent(MachineInstr* MI, - SDep::Kind DepType, - unsigned DepReg) { - - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - const HexagonRegisterInfo* QRI = (const HexagonRegisterInfo *) TM.getRegisterInfo(); - - // Check for lr dependence - if (DepReg == QRI->getRARegister()) { - return true; - } - - if (QII->isDeallocRet(MI)) { - if (DepReg == QRI->getFrameRegister() || - DepReg == QRI->getStackRegister()) - return true; - } - - // Check if this is a predicate dependence - const TargetRegisterClass* RC = QRI->getMinimalPhysRegClass(DepReg); - if (RC == Hexagon::PredRegsRegisterClass) { - return true; - } - - // - // Lastly check for an operand used in an indirect call - // If we had an attribute for checking if an instruction is an indirect call, - // then we could have avoided this relatively brittle implementation of - // IsIndirectCall() - // - // Assumes that the first operand of the CALLr is the function address - // - if (IsIndirectCall(MI) && (DepType == SDep::Data)) { - MachineOperand MO = MI->getOperand(0); - if (MO.isReg() && MO.isUse() && (MO.getReg() == DepReg)) { - return true; - } - } - - return false; -} - -static bool IsRegDependence(const SDep::Kind DepType) { - return (DepType == SDep::Data || DepType == SDep::Anti || - DepType == SDep::Output); -} - -static bool IsDirectJump(MachineInstr* MI) { - return (MI->getOpcode() == Hexagon::JMP); -} - -static bool IsSchedBarrier(MachineInstr* MI) { - switch (MI->getOpcode()) { - case Hexagon::BARRIER: - return true; - } - return false; -} - -static bool IsControlFlow(MachineInstr* MI) { - return (MI->getDesc().isTerminator() || MI->getDesc().isCall()); -} - -bool HexagonPacketizerList::isNewValueInst(MachineInstr* MI) { - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - if (QII->isNewValueJump(MI)) - return true; - - if (QII->isNewValueStore(MI)) - return true; - - return false; -} - -// Function returns true if an instruction can be promoted to the new-value -// store. It will always return false for v2 and v3. -// It lists all the conditional and unconditional stores that can be promoted -// to the new-value stores. - -bool HexagonPacketizerList::IsNewifyStore (MachineInstr* MI) { - const HexagonRegisterInfo* QRI = (const HexagonRegisterInfo *) TM.getRegisterInfo(); - switch (MI->getOpcode()) - { - // store byte - case Hexagon::STrib: - case Hexagon::STrib_indexed: - case Hexagon::STrib_indexed_shl_V4: - case Hexagon::STrib_shl_V4: - case Hexagon::STrib_GP_V4: - case Hexagon::STb_GP_V4: - case Hexagon::POST_STbri: - case Hexagon::STrib_cPt: - case Hexagon::STrib_cdnPt_V4: - case Hexagon::STrib_cNotPt: - case Hexagon::STrib_cdnNotPt_V4: - case Hexagon::STrib_indexed_cPt: - case Hexagon::STrib_indexed_cdnPt_V4: - case Hexagon::STrib_indexed_cNotPt: - case Hexagon::STrib_indexed_cdnNotPt_V4: - case Hexagon::STrib_indexed_shl_cPt_V4: - case Hexagon::STrib_indexed_shl_cdnPt_V4: - case Hexagon::STrib_indexed_shl_cNotPt_V4: - case Hexagon::STrib_indexed_shl_cdnNotPt_V4: - case Hexagon::POST_STbri_cPt: - case Hexagon::POST_STbri_cdnPt_V4: - case Hexagon::POST_STbri_cNotPt: - case Hexagon::POST_STbri_cdnNotPt_V4: - case Hexagon::STb_GP_cPt_V4: - case Hexagon::STb_GP_cNotPt_V4: - case Hexagon::STb_GP_cdnPt_V4: - case Hexagon::STb_GP_cdnNotPt_V4: - case Hexagon::STrib_GP_cPt_V4: - case Hexagon::STrib_GP_cNotPt_V4: - case Hexagon::STrib_GP_cdnPt_V4: - case Hexagon::STrib_GP_cdnNotPt_V4: - - // store halfword - case Hexagon::STrih: - case Hexagon::STrih_indexed: - case Hexagon::STrih_indexed_shl_V4: - case Hexagon::STrih_shl_V4: - case Hexagon::STrih_GP_V4: - case Hexagon::STh_GP_V4: - case Hexagon::POST_SThri: - case Hexagon::STrih_cPt: - case Hexagon::STrih_cdnPt_V4: - case Hexagon::STrih_cNotPt: - case Hexagon::STrih_cdnNotPt_V4: - case Hexagon::STrih_indexed_cPt: - case Hexagon::STrih_indexed_cdnPt_V4: - case Hexagon::STrih_indexed_cNotPt: - case Hexagon::STrih_indexed_cdnNotPt_V4: - case Hexagon::STrih_indexed_shl_cPt_V4: - case Hexagon::STrih_indexed_shl_cdnPt_V4: - case Hexagon::STrih_indexed_shl_cNotPt_V4: - case Hexagon::STrih_indexed_shl_cdnNotPt_V4: - case Hexagon::POST_SThri_cPt: - case Hexagon::POST_SThri_cdnPt_V4: - case Hexagon::POST_SThri_cNotPt: - case Hexagon::POST_SThri_cdnNotPt_V4: - case Hexagon::STh_GP_cPt_V4: - case Hexagon::STh_GP_cNotPt_V4: - case Hexagon::STh_GP_cdnPt_V4: - case Hexagon::STh_GP_cdnNotPt_V4: - case Hexagon::STrih_GP_cPt_V4: - case Hexagon::STrih_GP_cNotPt_V4: - case Hexagon::STrih_GP_cdnPt_V4: - case Hexagon::STrih_GP_cdnNotPt_V4: - - // store word - case Hexagon::STriw: - case Hexagon::STriw_indexed: - case Hexagon::STriw_indexed_shl_V4: - case Hexagon::STriw_shl_V4: - case Hexagon::STriw_GP_V4: - case Hexagon::STw_GP_V4: - case Hexagon::POST_STwri: - case Hexagon::STriw_cPt: - case Hexagon::STriw_cdnPt_V4: - case Hexagon::STriw_cNotPt: - case Hexagon::STriw_cdnNotPt_V4: - case Hexagon::STriw_indexed_cPt: - case Hexagon::STriw_indexed_cdnPt_V4: - case Hexagon::STriw_indexed_cNotPt: - case Hexagon::STriw_indexed_cdnNotPt_V4: - case Hexagon::STriw_indexed_shl_cPt_V4: - case Hexagon::STriw_indexed_shl_cdnPt_V4: - case Hexagon::STriw_indexed_shl_cNotPt_V4: - case Hexagon::STriw_indexed_shl_cdnNotPt_V4: - case Hexagon::POST_STwri_cPt: - case Hexagon::POST_STwri_cdnPt_V4: - case Hexagon::POST_STwri_cNotPt: - case Hexagon::POST_STwri_cdnNotPt_V4: - case Hexagon::STw_GP_cPt_V4: - case Hexagon::STw_GP_cNotPt_V4: - case Hexagon::STw_GP_cdnPt_V4: - case Hexagon::STw_GP_cdnNotPt_V4: - case Hexagon::STriw_GP_cPt_V4: - case Hexagon::STriw_GP_cNotPt_V4: - case Hexagon::STriw_GP_cdnPt_V4: - case Hexagon::STriw_GP_cdnNotPt_V4: - return QRI->Subtarget.hasV4TOps(); - } - return false; -} - -static bool IsLoopN(MachineInstr *MI) { - return (MI->getOpcode() == Hexagon::LOOP0_i || - MI->getOpcode() == Hexagon::LOOP0_r); -} - -/// DoesModifyCalleeSavedReg - Returns true if the instruction modifies a -/// callee-saved register. -static bool DoesModifyCalleeSavedReg(MachineInstr *MI, - const TargetRegisterInfo *TRI) { - for (const uint16_t *CSR = TRI->getCalleeSavedRegs(); *CSR; ++CSR) { - unsigned CalleeSavedReg = *CSR; - if (MI->modifiesRegister(CalleeSavedReg, TRI)) - return true; - } - return false; -} - -// Return the new value instruction for a given store. -static int GetDotNewOp(const int opc) { - switch (opc) { - default: llvm_unreachable("Unknown .new type"); - - // store new value byte - case Hexagon::STrib: - return Hexagon::STrib_nv_V4; - - case Hexagon::STrib_indexed: - return Hexagon::STrib_indexed_nv_V4; - - case Hexagon::STrib_indexed_shl_V4: - return Hexagon::STrib_indexed_shl_nv_V4; - - case Hexagon::STrib_shl_V4: - return Hexagon::STrib_shl_nv_V4; - - case Hexagon::STrib_GP_V4: - return Hexagon::STrib_GP_nv_V4; - - case Hexagon::STb_GP_V4: - return Hexagon::STb_GP_nv_V4; - - case Hexagon::POST_STbri: - return Hexagon::POST_STbri_nv_V4; - - case Hexagon::STrib_cPt: - return Hexagon::STrib_cPt_nv_V4; - - case Hexagon::STrib_cdnPt_V4: - return Hexagon::STrib_cdnPt_nv_V4; - - case Hexagon::STrib_cNotPt: - return Hexagon::STrib_cNotPt_nv_V4; - - case Hexagon::STrib_cdnNotPt_V4: - return Hexagon::STrib_cdnNotPt_nv_V4; - - case Hexagon::STrib_indexed_cPt: - return Hexagon::STrib_indexed_cPt_nv_V4; - - case Hexagon::STrib_indexed_cdnPt_V4: - return Hexagon::STrib_indexed_cdnPt_nv_V4; - - case Hexagon::STrib_indexed_cNotPt: - return Hexagon::STrib_indexed_cNotPt_nv_V4; - - case Hexagon::STrib_indexed_cdnNotPt_V4: - return Hexagon::STrib_indexed_cdnNotPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cPt_V4: - return Hexagon::STrib_indexed_shl_cPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cdnPt_V4: - return Hexagon::STrib_indexed_shl_cdnPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cNotPt_V4: - return Hexagon::STrib_indexed_shl_cNotPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cdnNotPt_V4: - return Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_STbri_cPt: - return Hexagon::POST_STbri_cPt_nv_V4; - - case Hexagon::POST_STbri_cdnPt_V4: - return Hexagon::POST_STbri_cdnPt_nv_V4; - - case Hexagon::POST_STbri_cNotPt: - return Hexagon::POST_STbri_cNotPt_nv_V4; - - case Hexagon::POST_STbri_cdnNotPt_V4: - return Hexagon::POST_STbri_cdnNotPt_nv_V4; - - case Hexagon::STb_GP_cPt_V4: - return Hexagon::STb_GP_cPt_nv_V4; - - case Hexagon::STb_GP_cNotPt_V4: - return Hexagon::STb_GP_cNotPt_nv_V4; - - case Hexagon::STb_GP_cdnPt_V4: - return Hexagon::STb_GP_cdnPt_nv_V4; - - case Hexagon::STb_GP_cdnNotPt_V4: - return Hexagon::STb_GP_cdnNotPt_nv_V4; - - case Hexagon::STrib_GP_cPt_V4: - return Hexagon::STrib_GP_cPt_nv_V4; - - case Hexagon::STrib_GP_cNotPt_V4: - return Hexagon::STrib_GP_cNotPt_nv_V4; - - case Hexagon::STrib_GP_cdnPt_V4: - return Hexagon::STrib_GP_cdnPt_nv_V4; - - case Hexagon::STrib_GP_cdnNotPt_V4: - return Hexagon::STrib_GP_cdnNotPt_nv_V4; - - // store new value halfword - case Hexagon::STrih: - return Hexagon::STrih_nv_V4; - - case Hexagon::STrih_indexed: - return Hexagon::STrih_indexed_nv_V4; - - case Hexagon::STrih_indexed_shl_V4: - return Hexagon::STrih_indexed_shl_nv_V4; - - case Hexagon::STrih_shl_V4: - return Hexagon::STrih_shl_nv_V4; - - case Hexagon::STrih_GP_V4: - return Hexagon::STrih_GP_nv_V4; - - case Hexagon::STh_GP_V4: - return Hexagon::STh_GP_nv_V4; - - case Hexagon::POST_SThri: - return Hexagon::POST_SThri_nv_V4; - - case Hexagon::STrih_cPt: - return Hexagon::STrih_cPt_nv_V4; - - case Hexagon::STrih_cdnPt_V4: - return Hexagon::STrih_cdnPt_nv_V4; - - case Hexagon::STrih_cNotPt: - return Hexagon::STrih_cNotPt_nv_V4; - - case Hexagon::STrih_cdnNotPt_V4: - return Hexagon::STrih_cdnNotPt_nv_V4; - - case Hexagon::STrih_indexed_cPt: - return Hexagon::STrih_indexed_cPt_nv_V4; - - case Hexagon::STrih_indexed_cdnPt_V4: - return Hexagon::STrih_indexed_cdnPt_nv_V4; - - case Hexagon::STrih_indexed_cNotPt: - return Hexagon::STrih_indexed_cNotPt_nv_V4; - - case Hexagon::STrih_indexed_cdnNotPt_V4: - return Hexagon::STrih_indexed_cdnNotPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cPt_V4: - return Hexagon::STrih_indexed_shl_cPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cdnPt_V4: - return Hexagon::STrih_indexed_shl_cdnPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cNotPt_V4: - return Hexagon::STrih_indexed_shl_cNotPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cdnNotPt_V4: - return Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_SThri_cPt: - return Hexagon::POST_SThri_cPt_nv_V4; - - case Hexagon::POST_SThri_cdnPt_V4: - return Hexagon::POST_SThri_cdnPt_nv_V4; - - case Hexagon::POST_SThri_cNotPt: - return Hexagon::POST_SThri_cNotPt_nv_V4; - - case Hexagon::POST_SThri_cdnNotPt_V4: - return Hexagon::POST_SThri_cdnNotPt_nv_V4; - - case Hexagon::STh_GP_cPt_V4: - return Hexagon::STh_GP_cPt_nv_V4; - - case Hexagon::STh_GP_cNotPt_V4: - return Hexagon::STh_GP_cNotPt_nv_V4; - - case Hexagon::STh_GP_cdnPt_V4: - return Hexagon::STh_GP_cdnPt_nv_V4; - - case Hexagon::STh_GP_cdnNotPt_V4: - return Hexagon::STh_GP_cdnNotPt_nv_V4; - - case Hexagon::STrih_GP_cPt_V4: - return Hexagon::STrih_GP_cPt_nv_V4; - - case Hexagon::STrih_GP_cNotPt_V4: - return Hexagon::STrih_GP_cNotPt_nv_V4; - - case Hexagon::STrih_GP_cdnPt_V4: - return Hexagon::STrih_GP_cdnPt_nv_V4; - - case Hexagon::STrih_GP_cdnNotPt_V4: - return Hexagon::STrih_GP_cdnNotPt_nv_V4; - - // store new value word - case Hexagon::STriw: - return Hexagon::STriw_nv_V4; - - case Hexagon::STriw_indexed: - return Hexagon::STriw_indexed_nv_V4; - - case Hexagon::STriw_indexed_shl_V4: - return Hexagon::STriw_indexed_shl_nv_V4; - - case Hexagon::STriw_shl_V4: - return Hexagon::STriw_shl_nv_V4; - - case Hexagon::STriw_GP_V4: - return Hexagon::STriw_GP_nv_V4; - - case Hexagon::STw_GP_V4: - return Hexagon::STw_GP_nv_V4; - - case Hexagon::POST_STwri: - return Hexagon::POST_STwri_nv_V4; - - case Hexagon::STriw_cPt: - return Hexagon::STriw_cPt_nv_V4; - - case Hexagon::STriw_cdnPt_V4: - return Hexagon::STriw_cdnPt_nv_V4; - - case Hexagon::STriw_cNotPt: - return Hexagon::STriw_cNotPt_nv_V4; - - case Hexagon::STriw_cdnNotPt_V4: - return Hexagon::STriw_cdnNotPt_nv_V4; - - case Hexagon::STriw_indexed_cPt: - return Hexagon::STriw_indexed_cPt_nv_V4; - - case Hexagon::STriw_indexed_cdnPt_V4: - return Hexagon::STriw_indexed_cdnPt_nv_V4; - - case Hexagon::STriw_indexed_cNotPt: - return Hexagon::STriw_indexed_cNotPt_nv_V4; - - case Hexagon::STriw_indexed_cdnNotPt_V4: - return Hexagon::STriw_indexed_cdnNotPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cPt_V4: - return Hexagon::STriw_indexed_shl_cPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cdnPt_V4: - return Hexagon::STriw_indexed_shl_cdnPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cNotPt_V4: - return Hexagon::STriw_indexed_shl_cNotPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cdnNotPt_V4: - return Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_STwri_cPt: - return Hexagon::POST_STwri_cPt_nv_V4; - - case Hexagon::POST_STwri_cdnPt_V4: - return Hexagon::POST_STwri_cdnPt_nv_V4; - - case Hexagon::POST_STwri_cNotPt: - return Hexagon::POST_STwri_cNotPt_nv_V4; - - case Hexagon::POST_STwri_cdnNotPt_V4: - return Hexagon::POST_STwri_cdnNotPt_nv_V4; - - case Hexagon::STw_GP_cPt_V4: - return Hexagon::STw_GP_cPt_nv_V4; - - case Hexagon::STw_GP_cNotPt_V4: - return Hexagon::STw_GP_cNotPt_nv_V4; - - case Hexagon::STw_GP_cdnPt_V4: - return Hexagon::STw_GP_cdnPt_nv_V4; - - case Hexagon::STw_GP_cdnNotPt_V4: - return Hexagon::STw_GP_cdnNotPt_nv_V4; - - case Hexagon::STriw_GP_cPt_V4: - return Hexagon::STriw_GP_cPt_nv_V4; - - case Hexagon::STriw_GP_cNotPt_V4: - return Hexagon::STriw_GP_cNotPt_nv_V4; - - case Hexagon::STriw_GP_cdnPt_V4: - return Hexagon::STriw_GP_cdnPt_nv_V4; - - case Hexagon::STriw_GP_cdnNotPt_V4: - return Hexagon::STriw_GP_cdnNotPt_nv_V4; - } -} - -// Return .new predicate version for an instruction -static int GetDotNewPredOp(const int opc) { - switch (opc) { - default: llvm_unreachable("Unknown .new type"); - - // Conditional stores - // Store byte conditionally - case Hexagon::STrib_cPt : - return Hexagon::STrib_cdnPt_V4; - - case Hexagon::STrib_cNotPt : - return Hexagon::STrib_cdnNotPt_V4; - - case Hexagon::STrib_indexed_cPt : - return Hexagon::STrib_indexed_cdnPt_V4; - - case Hexagon::STrib_indexed_cNotPt : - return Hexagon::STrib_indexed_cdnNotPt_V4; - - case Hexagon::STrib_imm_cPt_V4 : - return Hexagon::STrib_imm_cdnPt_V4; - - case Hexagon::STrib_imm_cNotPt_V4 : - return Hexagon::STrib_imm_cdnNotPt_V4; - - case Hexagon::POST_STbri_cPt : - return Hexagon::POST_STbri_cdnPt_V4; - - case Hexagon::POST_STbri_cNotPt : - return Hexagon::POST_STbri_cdnNotPt_V4; - - case Hexagon::STrib_indexed_shl_cPt_V4 : - return Hexagon::STrib_indexed_shl_cdnPt_V4; - - case Hexagon::STrib_indexed_shl_cNotPt_V4 : - return Hexagon::STrib_indexed_shl_cdnNotPt_V4; - - case Hexagon::STb_GP_cPt_V4 : - return Hexagon::STb_GP_cdnPt_V4; - - case Hexagon::STb_GP_cNotPt_V4 : - return Hexagon::STb_GP_cdnNotPt_V4; - - case Hexagon::STrib_GP_cPt_V4 : - return Hexagon::STrib_GP_cdnPt_V4; - - case Hexagon::STrib_GP_cNotPt_V4 : - return Hexagon::STrib_GP_cdnNotPt_V4; - - // Store doubleword conditionally - case Hexagon::STrid_cPt : - return Hexagon::STrid_cdnPt_V4; - - case Hexagon::STrid_cNotPt : - return Hexagon::STrid_cdnNotPt_V4; - - case Hexagon::STrid_indexed_cPt : - return Hexagon::STrid_indexed_cdnPt_V4; - - case Hexagon::STrid_indexed_cNotPt : - return Hexagon::STrid_indexed_cdnNotPt_V4; - - case Hexagon::STrid_indexed_shl_cPt_V4 : - return Hexagon::STrid_indexed_shl_cdnPt_V4; - - case Hexagon::STrid_indexed_shl_cNotPt_V4 : - return Hexagon::STrid_indexed_shl_cdnNotPt_V4; - - case Hexagon::POST_STdri_cPt : - return Hexagon::POST_STdri_cdnPt_V4; - - case Hexagon::POST_STdri_cNotPt : - return Hexagon::POST_STdri_cdnNotPt_V4; - - case Hexagon::STd_GP_cPt_V4 : - return Hexagon::STd_GP_cdnPt_V4; - - case Hexagon::STd_GP_cNotPt_V4 : - return Hexagon::STd_GP_cdnNotPt_V4; - - case Hexagon::STrid_GP_cPt_V4 : - return Hexagon::STrid_GP_cdnPt_V4; - - case Hexagon::STrid_GP_cNotPt_V4 : - return Hexagon::STrid_GP_cdnNotPt_V4; - - // Store halfword conditionally - case Hexagon::STrih_cPt : - return Hexagon::STrih_cdnPt_V4; - - case Hexagon::STrih_cNotPt : - return Hexagon::STrih_cdnNotPt_V4; - - case Hexagon::STrih_indexed_cPt : - return Hexagon::STrih_indexed_cdnPt_V4; - - case Hexagon::STrih_indexed_cNotPt : - return Hexagon::STrih_indexed_cdnNotPt_V4; - - case Hexagon::STrih_imm_cPt_V4 : - return Hexagon::STrih_imm_cdnPt_V4; - - case Hexagon::STrih_imm_cNotPt_V4 : - return Hexagon::STrih_imm_cdnNotPt_V4; - - case Hexagon::STrih_indexed_shl_cPt_V4 : - return Hexagon::STrih_indexed_shl_cdnPt_V4; - - case Hexagon::STrih_indexed_shl_cNotPt_V4 : - return Hexagon::STrih_indexed_shl_cdnNotPt_V4; - - case Hexagon::POST_SThri_cPt : - return Hexagon::POST_SThri_cdnPt_V4; - - case Hexagon::POST_SThri_cNotPt : - return Hexagon::POST_SThri_cdnNotPt_V4; - - case Hexagon::STh_GP_cPt_V4 : - return Hexagon::STh_GP_cdnPt_V4; - - case Hexagon::STh_GP_cNotPt_V4 : - return Hexagon::STh_GP_cdnNotPt_V4; - - case Hexagon::STrih_GP_cPt_V4 : - return Hexagon::STrih_GP_cdnPt_V4; - - case Hexagon::STrih_GP_cNotPt_V4 : - return Hexagon::STrih_GP_cdnNotPt_V4; - - // Store word conditionally - case Hexagon::STriw_cPt : - return Hexagon::STriw_cdnPt_V4; - - case Hexagon::STriw_cNotPt : - return Hexagon::STriw_cdnNotPt_V4; - - case Hexagon::STriw_indexed_cPt : - return Hexagon::STriw_indexed_cdnPt_V4; - - case Hexagon::STriw_indexed_cNotPt : - return Hexagon::STriw_indexed_cdnNotPt_V4; - - case Hexagon::STriw_imm_cPt_V4 : - return Hexagon::STriw_imm_cdnPt_V4; - - case Hexagon::STriw_imm_cNotPt_V4 : - return Hexagon::STriw_imm_cdnNotPt_V4; - - case Hexagon::STriw_indexed_shl_cPt_V4 : - return Hexagon::STriw_indexed_shl_cdnPt_V4; - - case Hexagon::STriw_indexed_shl_cNotPt_V4 : - return Hexagon::STriw_indexed_shl_cdnNotPt_V4; - - case Hexagon::POST_STwri_cPt : - return Hexagon::POST_STwri_cdnPt_V4; - - case Hexagon::POST_STwri_cNotPt : - return Hexagon::POST_STwri_cdnNotPt_V4; - - case Hexagon::STw_GP_cPt_V4 : - return Hexagon::STw_GP_cdnPt_V4; - - case Hexagon::STw_GP_cNotPt_V4 : - return Hexagon::STw_GP_cdnNotPt_V4; - - case Hexagon::STriw_GP_cPt_V4 : - return Hexagon::STriw_GP_cdnPt_V4; - - case Hexagon::STriw_GP_cNotPt_V4 : - return Hexagon::STriw_GP_cdnNotPt_V4; - - // Condtional Jumps - case Hexagon::JMP_c: - return Hexagon::JMP_cdnPt; - - case Hexagon::JMP_cNot: - return Hexagon::JMP_cdnNotPt; - - case Hexagon::JMPR_cPt: - return Hexagon::JMPR_cdnPt_V3; - - case Hexagon::JMPR_cNotPt: - return Hexagon::JMPR_cdnNotPt_V3; - - // Conditional Transfers - case Hexagon::TFR_cPt: - return Hexagon::TFR_cdnPt; - - case Hexagon::TFR_cNotPt: - return Hexagon::TFR_cdnNotPt; - - case Hexagon::TFRI_cPt: - return Hexagon::TFRI_cdnPt; - - case Hexagon::TFRI_cNotPt: - return Hexagon::TFRI_cdnNotPt; - - // Load double word - case Hexagon::LDrid_cPt : - return Hexagon::LDrid_cdnPt; - - case Hexagon::LDrid_cNotPt : - return Hexagon::LDrid_cdnNotPt; - - case Hexagon::LDrid_indexed_cPt : - return Hexagon::LDrid_indexed_cdnPt; - - case Hexagon::LDrid_indexed_cNotPt : - return Hexagon::LDrid_indexed_cdnNotPt; - - case Hexagon::POST_LDrid_cPt : - return Hexagon::POST_LDrid_cdnPt_V4; - - case Hexagon::POST_LDrid_cNotPt : - return Hexagon::POST_LDrid_cdnNotPt_V4; - - // Load word - case Hexagon::LDriw_cPt : - return Hexagon::LDriw_cdnPt; - - case Hexagon::LDriw_cNotPt : - return Hexagon::LDriw_cdnNotPt; - - case Hexagon::LDriw_indexed_cPt : - return Hexagon::LDriw_indexed_cdnPt; - - case Hexagon::LDriw_indexed_cNotPt : - return Hexagon::LDriw_indexed_cdnNotPt; - - case Hexagon::POST_LDriw_cPt : - return Hexagon::POST_LDriw_cdnPt_V4; - - case Hexagon::POST_LDriw_cNotPt : - return Hexagon::POST_LDriw_cdnNotPt_V4; - - // Load halfword - case Hexagon::LDrih_cPt : - return Hexagon::LDrih_cdnPt; - - case Hexagon::LDrih_cNotPt : - return Hexagon::LDrih_cdnNotPt; - - case Hexagon::LDrih_indexed_cPt : - return Hexagon::LDrih_indexed_cdnPt; - - case Hexagon::LDrih_indexed_cNotPt : - return Hexagon::LDrih_indexed_cdnNotPt; - - case Hexagon::POST_LDrih_cPt : - return Hexagon::POST_LDrih_cdnPt_V4; - - case Hexagon::POST_LDrih_cNotPt : - return Hexagon::POST_LDrih_cdnNotPt_V4; - - // Load byte - case Hexagon::LDrib_cPt : - return Hexagon::LDrib_cdnPt; - - case Hexagon::LDrib_cNotPt : - return Hexagon::LDrib_cdnNotPt; - - case Hexagon::LDrib_indexed_cPt : - return Hexagon::LDrib_indexed_cdnPt; - - case Hexagon::LDrib_indexed_cNotPt : - return Hexagon::LDrib_indexed_cdnNotPt; - - case Hexagon::POST_LDrib_cPt : - return Hexagon::POST_LDrib_cdnPt_V4; - - case Hexagon::POST_LDrib_cNotPt : - return Hexagon::POST_LDrib_cdnNotPt_V4; - - // Load unsigned halfword - case Hexagon::LDriuh_cPt : - return Hexagon::LDriuh_cdnPt; - - case Hexagon::LDriuh_cNotPt : - return Hexagon::LDriuh_cdnNotPt; - - case Hexagon::LDriuh_indexed_cPt : - return Hexagon::LDriuh_indexed_cdnPt; - - case Hexagon::LDriuh_indexed_cNotPt : - return Hexagon::LDriuh_indexed_cdnNotPt; - - case Hexagon::POST_LDriuh_cPt : - return Hexagon::POST_LDriuh_cdnPt_V4; - - case Hexagon::POST_LDriuh_cNotPt : - return Hexagon::POST_LDriuh_cdnNotPt_V4; - - // Load unsigned byte - case Hexagon::LDriub_cPt : - return Hexagon::LDriub_cdnPt; - - case Hexagon::LDriub_cNotPt : - return Hexagon::LDriub_cdnNotPt; - - case Hexagon::LDriub_indexed_cPt : - return Hexagon::LDriub_indexed_cdnPt; - - case Hexagon::LDriub_indexed_cNotPt : - return Hexagon::LDriub_indexed_cdnNotPt; - - case Hexagon::POST_LDriub_cPt : - return Hexagon::POST_LDriub_cdnPt_V4; - - case Hexagon::POST_LDriub_cNotPt : - return Hexagon::POST_LDriub_cdnNotPt_V4; - - // V4 indexed+scaled load - - case Hexagon::LDrid_indexed_cPt_V4 : - return Hexagon::LDrid_indexed_cdnPt_V4; - - case Hexagon::LDrid_indexed_cNotPt_V4 : - return Hexagon::LDrid_indexed_cdnNotPt_V4; - - case Hexagon::LDrid_indexed_shl_cPt_V4 : - return Hexagon::LDrid_indexed_shl_cdnPt_V4; - - case Hexagon::LDrid_indexed_shl_cNotPt_V4 : - return Hexagon::LDrid_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDrib_indexed_cPt_V4 : - return Hexagon::LDrib_indexed_cdnPt_V4; - - case Hexagon::LDrib_indexed_cNotPt_V4 : - return Hexagon::LDrib_indexed_cdnNotPt_V4; - - case Hexagon::LDrib_indexed_shl_cPt_V4 : - return Hexagon::LDrib_indexed_shl_cdnPt_V4; - - case Hexagon::LDrib_indexed_shl_cNotPt_V4 : - return Hexagon::LDrib_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDriub_indexed_cPt_V4 : - return Hexagon::LDriub_indexed_cdnPt_V4; - - case Hexagon::LDriub_indexed_cNotPt_V4 : - return Hexagon::LDriub_indexed_cdnNotPt_V4; - - case Hexagon::LDriub_indexed_shl_cPt_V4 : - return Hexagon::LDriub_indexed_shl_cdnPt_V4; - - case Hexagon::LDriub_indexed_shl_cNotPt_V4 : - return Hexagon::LDriub_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDrih_indexed_cPt_V4 : - return Hexagon::LDrih_indexed_cdnPt_V4; - - case Hexagon::LDrih_indexed_cNotPt_V4 : - return Hexagon::LDrih_indexed_cdnNotPt_V4; - - case Hexagon::LDrih_indexed_shl_cPt_V4 : - return Hexagon::LDrih_indexed_shl_cdnPt_V4; - - case Hexagon::LDrih_indexed_shl_cNotPt_V4 : - return Hexagon::LDrih_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDriuh_indexed_cPt_V4 : - return Hexagon::LDriuh_indexed_cdnPt_V4; - - case Hexagon::LDriuh_indexed_cNotPt_V4 : - return Hexagon::LDriuh_indexed_cdnNotPt_V4; - - case Hexagon::LDriuh_indexed_shl_cPt_V4 : - return Hexagon::LDriuh_indexed_shl_cdnPt_V4; - - case Hexagon::LDriuh_indexed_shl_cNotPt_V4 : - return Hexagon::LDriuh_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDriw_indexed_cPt_V4 : - return Hexagon::LDriw_indexed_cdnPt_V4; - - case Hexagon::LDriw_indexed_cNotPt_V4 : - return Hexagon::LDriw_indexed_cdnNotPt_V4; - - case Hexagon::LDriw_indexed_shl_cPt_V4 : - return Hexagon::LDriw_indexed_shl_cdnPt_V4; - - case Hexagon::LDriw_indexed_shl_cNotPt_V4 : - return Hexagon::LDriw_indexed_shl_cdnNotPt_V4; - - // V4 global address load - - case Hexagon::LDd_GP_cPt_V4: - return Hexagon::LDd_GP_cdnPt_V4; - - case Hexagon::LDd_GP_cNotPt_V4: - return Hexagon::LDd_GP_cdnNotPt_V4; - - case Hexagon::LDb_GP_cPt_V4: - return Hexagon::LDb_GP_cdnPt_V4; - - case Hexagon::LDb_GP_cNotPt_V4: - return Hexagon::LDb_GP_cdnNotPt_V4; - - case Hexagon::LDub_GP_cPt_V4: - return Hexagon::LDub_GP_cdnPt_V4; - - case Hexagon::LDub_GP_cNotPt_V4: - return Hexagon::LDub_GP_cdnNotPt_V4; - - case Hexagon::LDh_GP_cPt_V4: - return Hexagon::LDh_GP_cdnPt_V4; - - case Hexagon::LDh_GP_cNotPt_V4: - return Hexagon::LDh_GP_cdnNotPt_V4; - - case Hexagon::LDuh_GP_cPt_V4: - return Hexagon::LDuh_GP_cdnPt_V4; - - case Hexagon::LDuh_GP_cNotPt_V4: - return Hexagon::LDuh_GP_cdnNotPt_V4; - - case Hexagon::LDw_GP_cPt_V4: - return Hexagon::LDw_GP_cdnPt_V4; - - case Hexagon::LDw_GP_cNotPt_V4: - return Hexagon::LDw_GP_cdnNotPt_V4; - - case Hexagon::LDrid_GP_cPt_V4: - return Hexagon::LDrid_GP_cdnPt_V4; - - case Hexagon::LDrid_GP_cNotPt_V4: - return Hexagon::LDrid_GP_cdnNotPt_V4; - - case Hexagon::LDrib_GP_cPt_V4: - return Hexagon::LDrib_GP_cdnPt_V4; - - case Hexagon::LDrib_GP_cNotPt_V4: - return Hexagon::LDrib_GP_cdnNotPt_V4; - - case Hexagon::LDriub_GP_cPt_V4: - return Hexagon::LDriub_GP_cdnPt_V4; - - case Hexagon::LDriub_GP_cNotPt_V4: - return Hexagon::LDriub_GP_cdnNotPt_V4; - - case Hexagon::LDrih_GP_cPt_V4: - return Hexagon::LDrih_GP_cdnPt_V4; - - case Hexagon::LDrih_GP_cNotPt_V4: - return Hexagon::LDrih_GP_cdnNotPt_V4; - - case Hexagon::LDriuh_GP_cPt_V4: - return Hexagon::LDriuh_GP_cdnPt_V4; - - case Hexagon::LDriuh_GP_cNotPt_V4: - return Hexagon::LDriuh_GP_cdnNotPt_V4; - - case Hexagon::LDriw_GP_cPt_V4: - return Hexagon::LDriw_GP_cdnPt_V4; - - case Hexagon::LDriw_GP_cNotPt_V4: - return Hexagon::LDriw_GP_cdnNotPt_V4; - - // Conditional store new-value byte - case Hexagon::STrib_cPt_nv_V4 : - return Hexagon::STrib_cdnPt_nv_V4; - case Hexagon::STrib_cNotPt_nv_V4 : - return Hexagon::STrib_cdnNotPt_nv_V4; - - case Hexagon::STrib_indexed_cPt_nv_V4 : - return Hexagon::STrib_indexed_cdnPt_nv_V4; - case Hexagon::STrib_indexed_cNotPt_nv_V4 : - return Hexagon::STrib_indexed_cdnNotPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cPt_nv_V4 : - return Hexagon::STrib_indexed_shl_cdnPt_nv_V4; - case Hexagon::STrib_indexed_shl_cNotPt_nv_V4 : - return Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_STbri_cPt_nv_V4 : - return Hexagon::POST_STbri_cdnPt_nv_V4; - case Hexagon::POST_STbri_cNotPt_nv_V4 : - return Hexagon::POST_STbri_cdnNotPt_nv_V4; - - case Hexagon::STb_GP_cPt_nv_V4 : - return Hexagon::STb_GP_cdnPt_nv_V4; - - case Hexagon::STb_GP_cNotPt_nv_V4 : - return Hexagon::STb_GP_cdnNotPt_nv_V4; - - case Hexagon::STrib_GP_cPt_nv_V4 : - return Hexagon::STrib_GP_cdnPt_nv_V4; - - case Hexagon::STrib_GP_cNotPt_nv_V4 : - return Hexagon::STrib_GP_cdnNotPt_nv_V4; - - // Conditional store new-value halfword - case Hexagon::STrih_cPt_nv_V4 : - return Hexagon::STrih_cdnPt_nv_V4; - case Hexagon::STrih_cNotPt_nv_V4 : - return Hexagon::STrih_cdnNotPt_nv_V4; - - case Hexagon::STrih_indexed_cPt_nv_V4 : - return Hexagon::STrih_indexed_cdnPt_nv_V4; - case Hexagon::STrih_indexed_cNotPt_nv_V4 : - return Hexagon::STrih_indexed_cdnNotPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cPt_nv_V4 : - return Hexagon::STrih_indexed_shl_cdnPt_nv_V4; - case Hexagon::STrih_indexed_shl_cNotPt_nv_V4 : - return Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_SThri_cPt_nv_V4 : - return Hexagon::POST_SThri_cdnPt_nv_V4; - case Hexagon::POST_SThri_cNotPt_nv_V4 : - return Hexagon::POST_SThri_cdnNotPt_nv_V4; - - case Hexagon::STh_GP_cPt_nv_V4 : - return Hexagon::STh_GP_cdnPt_nv_V4; - - case Hexagon::STh_GP_cNotPt_nv_V4 : - return Hexagon::STh_GP_cdnNotPt_nv_V4; - - case Hexagon::STrih_GP_cPt_nv_V4 : - return Hexagon::STrih_GP_cdnPt_nv_V4; - - case Hexagon::STrih_GP_cNotPt_nv_V4 : - return Hexagon::STrih_GP_cdnNotPt_nv_V4; - - // Conditional store new-value word - case Hexagon::STriw_cPt_nv_V4 : - return Hexagon::STriw_cdnPt_nv_V4; - case Hexagon::STriw_cNotPt_nv_V4 : - return Hexagon::STriw_cdnNotPt_nv_V4; - - case Hexagon::STriw_indexed_cPt_nv_V4 : - return Hexagon::STriw_indexed_cdnPt_nv_V4; - case Hexagon::STriw_indexed_cNotPt_nv_V4 : - return Hexagon::STriw_indexed_cdnNotPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cPt_nv_V4 : - return Hexagon::STriw_indexed_shl_cdnPt_nv_V4; - case Hexagon::STriw_indexed_shl_cNotPt_nv_V4 : - return Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_STwri_cPt_nv_V4 : - return Hexagon::POST_STwri_cdnPt_nv_V4; - case Hexagon::POST_STwri_cNotPt_nv_V4: - return Hexagon::POST_STwri_cdnNotPt_nv_V4; - - case Hexagon::STw_GP_cPt_nv_V4 : - return Hexagon::STw_GP_cdnPt_nv_V4; - - case Hexagon::STw_GP_cNotPt_nv_V4 : - return Hexagon::STw_GP_cdnNotPt_nv_V4; - - case Hexagon::STriw_GP_cPt_nv_V4 : - return Hexagon::STriw_GP_cdnPt_nv_V4; - - case Hexagon::STriw_GP_cNotPt_nv_V4 : - return Hexagon::STriw_GP_cdnNotPt_nv_V4; - - // Conditional add - case Hexagon::ADD_ri_cPt : - return Hexagon::ADD_ri_cdnPt; - case Hexagon::ADD_ri_cNotPt : - return Hexagon::ADD_ri_cdnNotPt; - - case Hexagon::ADD_rr_cPt : - return Hexagon::ADD_rr_cdnPt; - case Hexagon::ADD_rr_cNotPt : - return Hexagon::ADD_rr_cdnNotPt; - - // Conditional logical Operations - case Hexagon::XOR_rr_cPt : - return Hexagon::XOR_rr_cdnPt; - case Hexagon::XOR_rr_cNotPt : - return Hexagon::XOR_rr_cdnNotPt; - - case Hexagon::AND_rr_cPt : - return Hexagon::AND_rr_cdnPt; - case Hexagon::AND_rr_cNotPt : - return Hexagon::AND_rr_cdnNotPt; - - case Hexagon::OR_rr_cPt : - return Hexagon::OR_rr_cdnPt; - case Hexagon::OR_rr_cNotPt : - return Hexagon::OR_rr_cdnNotPt; - - // Conditional Subtract - case Hexagon::SUB_rr_cPt : - return Hexagon::SUB_rr_cdnPt; - case Hexagon::SUB_rr_cNotPt : - return Hexagon::SUB_rr_cdnNotPt; - - // Conditional combine - case Hexagon::COMBINE_rr_cPt : - return Hexagon::COMBINE_rr_cdnPt; - case Hexagon::COMBINE_rr_cNotPt : - return Hexagon::COMBINE_rr_cdnNotPt; - - case Hexagon::ASLH_cPt_V4 : - return Hexagon::ASLH_cdnPt_V4; - case Hexagon::ASLH_cNotPt_V4 : - return Hexagon::ASLH_cdnNotPt_V4; - - case Hexagon::ASRH_cPt_V4 : - return Hexagon::ASRH_cdnPt_V4; - case Hexagon::ASRH_cNotPt_V4 : - return Hexagon::ASRH_cdnNotPt_V4; - - case Hexagon::SXTB_cPt_V4 : - return Hexagon::SXTB_cdnPt_V4; - case Hexagon::SXTB_cNotPt_V4 : - return Hexagon::SXTB_cdnNotPt_V4; - - case Hexagon::SXTH_cPt_V4 : - return Hexagon::SXTH_cdnPt_V4; - case Hexagon::SXTH_cNotPt_V4 : - return Hexagon::SXTH_cdnNotPt_V4; - - case Hexagon::ZXTB_cPt_V4 : - return Hexagon::ZXTB_cdnPt_V4; - case Hexagon::ZXTB_cNotPt_V4 : - return Hexagon::ZXTB_cdnNotPt_V4; - - case Hexagon::ZXTH_cPt_V4 : - return Hexagon::ZXTH_cdnPt_V4; - case Hexagon::ZXTH_cNotPt_V4 : - return Hexagon::ZXTH_cdnNotPt_V4; - } -} - -// Returns true if an instruction can be promoted to .new predicate -// or new-value store. -bool HexagonPacketizerList::isNewifiable(MachineInstr* MI) { - if ( isCondInst(MI) || IsNewifyStore(MI)) - return true; - else - return false; -} - -bool HexagonPacketizerList::isCondInst (MachineInstr* MI) { - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - const MCInstrDesc& TID = MI->getDesc(); - // bug 5670: until that is fixed, - // this portion is disabled. - if ( TID.isConditionalBranch() // && !IsRegisterJump(MI)) || - || QII->isConditionalTransfer(MI) - || QII->isConditionalALU32(MI) - || QII->isConditionalLoad(MI) - || QII->isConditionalStore(MI)) { - return true; - } - return false; -} - - -// Promote an instructiont to its .new form. -// At this time, we have already made a call to CanPromoteToDotNew -// and made sure that it can *indeed* be promoted. -bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI, - SDep::Kind DepType, MachineBasicBlock::iterator &MII, - const TargetRegisterClass* RC) { - - assert (DepType == SDep::Data); - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - - int NewOpcode; - if (RC == Hexagon::PredRegsRegisterClass) - NewOpcode = GetDotNewPredOp(MI->getOpcode()); - else - NewOpcode = GetDotNewOp(MI->getOpcode()); - MI->setDesc(QII->get(NewOpcode)); - - return true; -} - -// Returns the most basic instruction for the .new predicated instructions and -// new-value stores. -// For example, all of the following instructions will be converted back to the -// same instruction: -// 1) if (p0.new) memw(R0+#0) = R1.new ---> -// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1 -// 3) if (p0.new) memw(R0+#0) = R1 ---> -// -// To understand the translation of instruction 1 to its original form, consider -// a packet with 3 instructions. -// { p0 = cmp.eq(R0,R1) -// if (p0.new) R2 = add(R3, R4) -// R5 = add (R3, R1) -// } -// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet -// -// This instruction can be part of the previous packet only if both p0 and R2 -// are promoted to .new values. This promotion happens in steps, first -// predicate register is promoted to .new and in the next iteration R2 is -// promoted. Therefore, in case of dependence check failure (due to R5) during -// next iteration, it should be converted back to its most basic form. - -static int GetDotOldOp(const int opc) { - switch (opc) { - default: llvm_unreachable("Unknown .old type"); - - case Hexagon::TFR_cdnPt: - return Hexagon::TFR_cPt; - - case Hexagon::TFR_cdnNotPt: - return Hexagon::TFR_cNotPt; - - case Hexagon::TFRI_cdnPt: - return Hexagon::TFRI_cPt; - - case Hexagon::TFRI_cdnNotPt: - return Hexagon::TFRI_cNotPt; - - case Hexagon::JMP_cdnPt: - return Hexagon::JMP_c; - - case Hexagon::JMP_cdnNotPt: - return Hexagon::JMP_cNot; - - case Hexagon::JMPR_cdnPt_V3: - return Hexagon::JMPR_cPt; - - case Hexagon::JMPR_cdnNotPt_V3: - return Hexagon::JMPR_cNotPt; - - // Load double word - - case Hexagon::LDrid_cdnPt : - return Hexagon::LDrid_cPt; - - case Hexagon::LDrid_cdnNotPt : - return Hexagon::LDrid_cNotPt; - - case Hexagon::LDrid_indexed_cdnPt : - return Hexagon::LDrid_indexed_cPt; - - case Hexagon::LDrid_indexed_cdnNotPt : - return Hexagon::LDrid_indexed_cNotPt; - - case Hexagon::POST_LDrid_cdnPt_V4 : - return Hexagon::POST_LDrid_cPt; - - case Hexagon::POST_LDrid_cdnNotPt_V4 : - return Hexagon::POST_LDrid_cNotPt; - - // Load word - - case Hexagon::LDriw_cdnPt : - return Hexagon::LDriw_cPt; - - case Hexagon::LDriw_cdnNotPt : - return Hexagon::LDriw_cNotPt; - - case Hexagon::LDriw_indexed_cdnPt : - return Hexagon::LDriw_indexed_cPt; - - case Hexagon::LDriw_indexed_cdnNotPt : - return Hexagon::LDriw_indexed_cNotPt; - - case Hexagon::POST_LDriw_cdnPt_V4 : - return Hexagon::POST_LDriw_cPt; - - case Hexagon::POST_LDriw_cdnNotPt_V4 : - return Hexagon::POST_LDriw_cNotPt; - - // Load half - - case Hexagon::LDrih_cdnPt : - return Hexagon::LDrih_cPt; - - case Hexagon::LDrih_cdnNotPt : - return Hexagon::LDrih_cNotPt; - - case Hexagon::LDrih_indexed_cdnPt : - return Hexagon::LDrih_indexed_cPt; - - case Hexagon::LDrih_indexed_cdnNotPt : - return Hexagon::LDrih_indexed_cNotPt; - - case Hexagon::POST_LDrih_cdnPt_V4 : - return Hexagon::POST_LDrih_cPt; - - case Hexagon::POST_LDrih_cdnNotPt_V4 : - return Hexagon::POST_LDrih_cNotPt; - - // Load byte - - case Hexagon::LDrib_cdnPt : - return Hexagon::LDrib_cPt; - - case Hexagon::LDrib_cdnNotPt : - return Hexagon::LDrib_cNotPt; - - case Hexagon::LDrib_indexed_cdnPt : - return Hexagon::LDrib_indexed_cPt; - - case Hexagon::LDrib_indexed_cdnNotPt : - return Hexagon::LDrib_indexed_cNotPt; - - case Hexagon::POST_LDrib_cdnPt_V4 : - return Hexagon::POST_LDrib_cPt; - - case Hexagon::POST_LDrib_cdnNotPt_V4 : - return Hexagon::POST_LDrib_cNotPt; - - // Load unsigned half - - case Hexagon::LDriuh_cdnPt : - return Hexagon::LDriuh_cPt; - - case Hexagon::LDriuh_cdnNotPt : - return Hexagon::LDriuh_cNotPt; - - case Hexagon::LDriuh_indexed_cdnPt : - return Hexagon::LDriuh_indexed_cPt; - - case Hexagon::LDriuh_indexed_cdnNotPt : - return Hexagon::LDriuh_indexed_cNotPt; - - case Hexagon::POST_LDriuh_cdnPt_V4 : - return Hexagon::POST_LDriuh_cPt; - - case Hexagon::POST_LDriuh_cdnNotPt_V4 : - return Hexagon::POST_LDriuh_cNotPt; - - // Load unsigned byte - case Hexagon::LDriub_cdnPt : - return Hexagon::LDriub_cPt; - - case Hexagon::LDriub_cdnNotPt : - return Hexagon::LDriub_cNotPt; - - case Hexagon::LDriub_indexed_cdnPt : - return Hexagon::LDriub_indexed_cPt; - - case Hexagon::LDriub_indexed_cdnNotPt : - return Hexagon::LDriub_indexed_cNotPt; - - case Hexagon::POST_LDriub_cdnPt_V4 : - return Hexagon::POST_LDriub_cPt; - - case Hexagon::POST_LDriub_cdnNotPt_V4 : - return Hexagon::POST_LDriub_cNotPt; - - // V4 indexed+scaled Load - - case Hexagon::LDrid_indexed_cdnPt_V4 : - return Hexagon::LDrid_indexed_cPt_V4; - - case Hexagon::LDrid_indexed_cdnNotPt_V4 : - return Hexagon::LDrid_indexed_cNotPt_V4; - - case Hexagon::LDrid_indexed_shl_cdnPt_V4 : - return Hexagon::LDrid_indexed_shl_cPt_V4; - - case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDrid_indexed_shl_cNotPt_V4; - - case Hexagon::LDrib_indexed_cdnPt_V4 : - return Hexagon::LDrib_indexed_cPt_V4; - - case Hexagon::LDrib_indexed_cdnNotPt_V4 : - return Hexagon::LDrib_indexed_cNotPt_V4; - - case Hexagon::LDrib_indexed_shl_cdnPt_V4 : - return Hexagon::LDrib_indexed_shl_cPt_V4; - - case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDrib_indexed_shl_cNotPt_V4; - - case Hexagon::LDriub_indexed_cdnPt_V4 : - return Hexagon::LDriub_indexed_cPt_V4; - - case Hexagon::LDriub_indexed_cdnNotPt_V4 : - return Hexagon::LDriub_indexed_cNotPt_V4; - - case Hexagon::LDriub_indexed_shl_cdnPt_V4 : - return Hexagon::LDriub_indexed_shl_cPt_V4; - - case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDriub_indexed_shl_cNotPt_V4; - - case Hexagon::LDrih_indexed_cdnPt_V4 : - return Hexagon::LDrih_indexed_cPt_V4; - - case Hexagon::LDrih_indexed_cdnNotPt_V4 : - return Hexagon::LDrih_indexed_cNotPt_V4; - - case Hexagon::LDrih_indexed_shl_cdnPt_V4 : - return Hexagon::LDrih_indexed_shl_cPt_V4; - - case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDrih_indexed_shl_cNotPt_V4; - - case Hexagon::LDriuh_indexed_cdnPt_V4 : - return Hexagon::LDriuh_indexed_cPt_V4; - - case Hexagon::LDriuh_indexed_cdnNotPt_V4 : - return Hexagon::LDriuh_indexed_cNotPt_V4; - - case Hexagon::LDriuh_indexed_shl_cdnPt_V4 : - return Hexagon::LDriuh_indexed_shl_cPt_V4; - - case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDriuh_indexed_shl_cNotPt_V4; - - case Hexagon::LDriw_indexed_cdnPt_V4 : - return Hexagon::LDriw_indexed_cPt_V4; - - case Hexagon::LDriw_indexed_cdnNotPt_V4 : - return Hexagon::LDriw_indexed_cNotPt_V4; - - case Hexagon::LDriw_indexed_shl_cdnPt_V4 : - return Hexagon::LDriw_indexed_shl_cPt_V4; - - case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDriw_indexed_shl_cNotPt_V4; - - // V4 global address load - - case Hexagon::LDd_GP_cdnPt_V4: - return Hexagon::LDd_GP_cPt_V4; - - case Hexagon::LDd_GP_cdnNotPt_V4: - return Hexagon::LDd_GP_cNotPt_V4; - - case Hexagon::LDb_GP_cdnPt_V4: - return Hexagon::LDb_GP_cPt_V4; - - case Hexagon::LDb_GP_cdnNotPt_V4: - return Hexagon::LDb_GP_cNotPt_V4; - - case Hexagon::LDub_GP_cdnPt_V4: - return Hexagon::LDub_GP_cPt_V4; - - case Hexagon::LDub_GP_cdnNotPt_V4: - return Hexagon::LDub_GP_cNotPt_V4; - - case Hexagon::LDh_GP_cdnPt_V4: - return Hexagon::LDh_GP_cPt_V4; - - case Hexagon::LDh_GP_cdnNotPt_V4: - return Hexagon::LDh_GP_cNotPt_V4; - - case Hexagon::LDuh_GP_cdnPt_V4: - return Hexagon::LDuh_GP_cPt_V4; - - case Hexagon::LDuh_GP_cdnNotPt_V4: - return Hexagon::LDuh_GP_cNotPt_V4; - - case Hexagon::LDw_GP_cdnPt_V4: - return Hexagon::LDw_GP_cPt_V4; - - case Hexagon::LDw_GP_cdnNotPt_V4: - return Hexagon::LDw_GP_cNotPt_V4; - - case Hexagon::LDrid_GP_cdnPt_V4: - return Hexagon::LDrid_GP_cPt_V4; - - case Hexagon::LDrid_GP_cdnNotPt_V4: - return Hexagon::LDrid_GP_cNotPt_V4; - - case Hexagon::LDrib_GP_cdnPt_V4: - return Hexagon::LDrib_GP_cPt_V4; - - case Hexagon::LDrib_GP_cdnNotPt_V4: - return Hexagon::LDrib_GP_cNotPt_V4; - - case Hexagon::LDriub_GP_cdnPt_V4: - return Hexagon::LDriub_GP_cPt_V4; - - case Hexagon::LDriub_GP_cdnNotPt_V4: - return Hexagon::LDriub_GP_cNotPt_V4; - - case Hexagon::LDrih_GP_cdnPt_V4: - return Hexagon::LDrih_GP_cPt_V4; - - case Hexagon::LDrih_GP_cdnNotPt_V4: - return Hexagon::LDrih_GP_cNotPt_V4; - - case Hexagon::LDriuh_GP_cdnPt_V4: - return Hexagon::LDriuh_GP_cPt_V4; - - case Hexagon::LDriuh_GP_cdnNotPt_V4: - return Hexagon::LDriuh_GP_cNotPt_V4; - - case Hexagon::LDriw_GP_cdnPt_V4: - return Hexagon::LDriw_GP_cPt_V4; - - case Hexagon::LDriw_GP_cdnNotPt_V4: - return Hexagon::LDriw_GP_cNotPt_V4; - - // Conditional add - - case Hexagon::ADD_ri_cdnPt : - return Hexagon::ADD_ri_cPt; - case Hexagon::ADD_ri_cdnNotPt : - return Hexagon::ADD_ri_cNotPt; - - case Hexagon::ADD_rr_cdnPt : - return Hexagon::ADD_rr_cPt; - case Hexagon::ADD_rr_cdnNotPt: - return Hexagon::ADD_rr_cNotPt; - - // Conditional logical Operations - - case Hexagon::XOR_rr_cdnPt : - return Hexagon::XOR_rr_cPt; - case Hexagon::XOR_rr_cdnNotPt : - return Hexagon::XOR_rr_cNotPt; - - case Hexagon::AND_rr_cdnPt : - return Hexagon::AND_rr_cPt; - case Hexagon::AND_rr_cdnNotPt : - return Hexagon::AND_rr_cNotPt; - - case Hexagon::OR_rr_cdnPt : - return Hexagon::OR_rr_cPt; - case Hexagon::OR_rr_cdnNotPt : - return Hexagon::OR_rr_cNotPt; - - // Conditional Subtract - - case Hexagon::SUB_rr_cdnPt : - return Hexagon::SUB_rr_cPt; - case Hexagon::SUB_rr_cdnNotPt : - return Hexagon::SUB_rr_cNotPt; - - // Conditional combine - - case Hexagon::COMBINE_rr_cdnPt : - return Hexagon::COMBINE_rr_cPt; - case Hexagon::COMBINE_rr_cdnNotPt : - return Hexagon::COMBINE_rr_cNotPt; - -// Conditional shift operations - - case Hexagon::ASLH_cdnPt_V4 : - return Hexagon::ASLH_cPt_V4; - case Hexagon::ASLH_cdnNotPt_V4 : - return Hexagon::ASLH_cNotPt_V4; - - case Hexagon::ASRH_cdnPt_V4 : - return Hexagon::ASRH_cPt_V4; - case Hexagon::ASRH_cdnNotPt_V4 : - return Hexagon::ASRH_cNotPt_V4; - - case Hexagon::SXTB_cdnPt_V4 : - return Hexagon::SXTB_cPt_V4; - case Hexagon::SXTB_cdnNotPt_V4 : - return Hexagon::SXTB_cNotPt_V4; - - case Hexagon::SXTH_cdnPt_V4 : - return Hexagon::SXTH_cPt_V4; - case Hexagon::SXTH_cdnNotPt_V4 : - return Hexagon::SXTH_cNotPt_V4; - - case Hexagon::ZXTB_cdnPt_V4 : - return Hexagon::ZXTB_cPt_V4; - case Hexagon::ZXTB_cdnNotPt_V4 : - return Hexagon::ZXTB_cNotPt_V4; - - case Hexagon::ZXTH_cdnPt_V4 : - return Hexagon::ZXTH_cPt_V4; - case Hexagon::ZXTH_cdnNotPt_V4 : - return Hexagon::ZXTH_cNotPt_V4; - - // Store byte - - case Hexagon::STrib_imm_cdnPt_V4 : - return Hexagon::STrib_imm_cPt_V4; - - case Hexagon::STrib_imm_cdnNotPt_V4 : - return Hexagon::STrib_imm_cNotPt_V4; - - case Hexagon::STrib_cdnPt_nv_V4 : - case Hexagon::STrib_cPt_nv_V4 : - case Hexagon::STrib_cdnPt_V4 : - return Hexagon::STrib_cPt; - - case Hexagon::STrib_cdnNotPt_nv_V4 : - case Hexagon::STrib_cNotPt_nv_V4 : - case Hexagon::STrib_cdnNotPt_V4 : - return Hexagon::STrib_cNotPt; - - case Hexagon::STrib_indexed_cdnPt_V4 : - case Hexagon::STrib_indexed_cPt_nv_V4 : - case Hexagon::STrib_indexed_cdnPt_nv_V4 : - return Hexagon::STrib_indexed_cPt; - - case Hexagon::STrib_indexed_cdnNotPt_V4 : - case Hexagon::STrib_indexed_cNotPt_nv_V4 : - case Hexagon::STrib_indexed_cdnNotPt_nv_V4 : - return Hexagon::STrib_indexed_cNotPt; - - case Hexagon::STrib_indexed_shl_cdnPt_nv_V4: - case Hexagon::STrib_indexed_shl_cPt_nv_V4 : - case Hexagon::STrib_indexed_shl_cdnPt_V4 : - return Hexagon::STrib_indexed_shl_cPt_V4; - - case Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4: - case Hexagon::STrib_indexed_shl_cNotPt_nv_V4 : - case Hexagon::STrib_indexed_shl_cdnNotPt_V4 : - return Hexagon::STrib_indexed_shl_cNotPt_V4; - - case Hexagon::POST_STbri_cdnPt_nv_V4 : - case Hexagon::POST_STbri_cPt_nv_V4 : - case Hexagon::POST_STbri_cdnPt_V4 : - return Hexagon::POST_STbri_cPt; - - case Hexagon::POST_STbri_cdnNotPt_nv_V4 : - case Hexagon::POST_STbri_cNotPt_nv_V4: - case Hexagon::POST_STbri_cdnNotPt_V4 : - return Hexagon::POST_STbri_cNotPt; - - case Hexagon::STb_GP_cdnPt_nv_V4: - case Hexagon::STb_GP_cdnPt_V4: - case Hexagon::STb_GP_cPt_nv_V4: - return Hexagon::STb_GP_cPt_V4; - - case Hexagon::STb_GP_cdnNotPt_nv_V4: - case Hexagon::STb_GP_cdnNotPt_V4: - case Hexagon::STb_GP_cNotPt_nv_V4: - return Hexagon::STb_GP_cNotPt_V4; - - case Hexagon::STrib_GP_cdnPt_nv_V4: - case Hexagon::STrib_GP_cdnPt_V4: - case Hexagon::STrib_GP_cPt_nv_V4: - return Hexagon::STrib_GP_cPt_V4; - - case Hexagon::STrib_GP_cdnNotPt_nv_V4: - case Hexagon::STrib_GP_cdnNotPt_V4: - case Hexagon::STrib_GP_cNotPt_nv_V4: - return Hexagon::STrib_GP_cNotPt_V4; - - // Store new-value byte - unconditional - case Hexagon::STrib_nv_V4: - return Hexagon::STrib; - - case Hexagon::STrib_indexed_nv_V4: - return Hexagon::STrib_indexed; - - case Hexagon::STrib_indexed_shl_nv_V4: - return Hexagon::STrib_indexed_shl_V4; - - case Hexagon::STrib_shl_nv_V4: - return Hexagon::STrib_shl_V4; - - case Hexagon::STrib_GP_nv_V4: - return Hexagon::STrib_GP_V4; - - case Hexagon::STb_GP_nv_V4: - return Hexagon::STb_GP_V4; - - case Hexagon::POST_STbri_nv_V4: - return Hexagon::POST_STbri; - - // Store halfword - case Hexagon::STrih_imm_cdnPt_V4 : - return Hexagon::STrih_imm_cPt_V4; - - case Hexagon::STrih_imm_cdnNotPt_V4 : - return Hexagon::STrih_imm_cNotPt_V4; - - case Hexagon::STrih_cdnPt_nv_V4 : - case Hexagon::STrih_cPt_nv_V4 : - case Hexagon::STrih_cdnPt_V4 : - return Hexagon::STrih_cPt; - - case Hexagon::STrih_cdnNotPt_nv_V4 : - case Hexagon::STrih_cNotPt_nv_V4 : - case Hexagon::STrih_cdnNotPt_V4 : - return Hexagon::STrih_cNotPt; - - case Hexagon::STrih_indexed_cdnPt_nv_V4: - case Hexagon::STrih_indexed_cPt_nv_V4 : - case Hexagon::STrih_indexed_cdnPt_V4 : - return Hexagon::STrih_indexed_cPt; - - case Hexagon::STrih_indexed_cdnNotPt_nv_V4: - case Hexagon::STrih_indexed_cNotPt_nv_V4 : - case Hexagon::STrih_indexed_cdnNotPt_V4 : - return Hexagon::STrih_indexed_cNotPt; - - case Hexagon::STrih_indexed_shl_cdnPt_nv_V4 : - case Hexagon::STrih_indexed_shl_cPt_nv_V4 : - case Hexagon::STrih_indexed_shl_cdnPt_V4 : - return Hexagon::STrih_indexed_shl_cPt_V4; - - case Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4 : - case Hexagon::STrih_indexed_shl_cNotPt_nv_V4 : - case Hexagon::STrih_indexed_shl_cdnNotPt_V4 : - return Hexagon::STrih_indexed_shl_cNotPt_V4; - - case Hexagon::POST_SThri_cdnPt_nv_V4 : - case Hexagon::POST_SThri_cPt_nv_V4 : - case Hexagon::POST_SThri_cdnPt_V4 : - return Hexagon::POST_SThri_cPt; - - case Hexagon::POST_SThri_cdnNotPt_nv_V4 : - case Hexagon::POST_SThri_cNotPt_nv_V4 : - case Hexagon::POST_SThri_cdnNotPt_V4 : - return Hexagon::POST_SThri_cNotPt; - - case Hexagon::STh_GP_cdnPt_nv_V4: - case Hexagon::STh_GP_cdnPt_V4: - case Hexagon::STh_GP_cPt_nv_V4: - return Hexagon::STh_GP_cPt_V4; - - case Hexagon::STh_GP_cdnNotPt_nv_V4: - case Hexagon::STh_GP_cdnNotPt_V4: - case Hexagon::STh_GP_cNotPt_nv_V4: - return Hexagon::STh_GP_cNotPt_V4; - - case Hexagon::STrih_GP_cdnPt_nv_V4: - case Hexagon::STrih_GP_cdnPt_V4: - case Hexagon::STrih_GP_cPt_nv_V4: - return Hexagon::STrih_GP_cPt_V4; - - case Hexagon::STrih_GP_cdnNotPt_nv_V4: - case Hexagon::STrih_GP_cdnNotPt_V4: - case Hexagon::STrih_GP_cNotPt_nv_V4: - return Hexagon::STrih_GP_cNotPt_V4; - - // Store new-value halfword - unconditional - - case Hexagon::STrih_nv_V4: - return Hexagon::STrih; - - case Hexagon::STrih_indexed_nv_V4: - return Hexagon::STrih_indexed; - - case Hexagon::STrih_indexed_shl_nv_V4: - return Hexagon::STrih_indexed_shl_V4; - - case Hexagon::STrih_shl_nv_V4: - return Hexagon::STrih_shl_V4; - - case Hexagon::STrih_GP_nv_V4: - return Hexagon::STrih_GP_V4; - - case Hexagon::STh_GP_nv_V4: - return Hexagon::STh_GP_V4; - - case Hexagon::POST_SThri_nv_V4: - return Hexagon::POST_SThri; - - // Store word - - case Hexagon::STriw_imm_cdnPt_V4 : - return Hexagon::STriw_imm_cPt_V4; - - case Hexagon::STriw_imm_cdnNotPt_V4 : - return Hexagon::STriw_imm_cNotPt_V4; - - case Hexagon::STriw_cdnPt_nv_V4 : - case Hexagon::STriw_cPt_nv_V4 : - case Hexagon::STriw_cdnPt_V4 : - return Hexagon::STriw_cPt; - - case Hexagon::STriw_cdnNotPt_nv_V4 : - case Hexagon::STriw_cNotPt_nv_V4 : - case Hexagon::STriw_cdnNotPt_V4 : - return Hexagon::STriw_cNotPt; - - case Hexagon::STriw_indexed_cdnPt_nv_V4 : - case Hexagon::STriw_indexed_cPt_nv_V4 : - case Hexagon::STriw_indexed_cdnPt_V4 : - return Hexagon::STriw_indexed_cPt; - - case Hexagon::STriw_indexed_cdnNotPt_nv_V4 : - case Hexagon::STriw_indexed_cNotPt_nv_V4 : - case Hexagon::STriw_indexed_cdnNotPt_V4 : - return Hexagon::STriw_indexed_cNotPt; - - case Hexagon::STriw_indexed_shl_cdnPt_nv_V4 : - case Hexagon::STriw_indexed_shl_cPt_nv_V4 : - case Hexagon::STriw_indexed_shl_cdnPt_V4 : - return Hexagon::STriw_indexed_shl_cPt_V4; - - case Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4 : - case Hexagon::STriw_indexed_shl_cNotPt_nv_V4 : - case Hexagon::STriw_indexed_shl_cdnNotPt_V4 : - return Hexagon::STriw_indexed_shl_cNotPt_V4; - - case Hexagon::POST_STwri_cdnPt_nv_V4 : - case Hexagon::POST_STwri_cPt_nv_V4 : - case Hexagon::POST_STwri_cdnPt_V4 : - return Hexagon::POST_STwri_cPt; - - case Hexagon::POST_STwri_cdnNotPt_nv_V4 : - case Hexagon::POST_STwri_cNotPt_nv_V4 : - case Hexagon::POST_STwri_cdnNotPt_V4 : - return Hexagon::POST_STwri_cNotPt; - - case Hexagon::STw_GP_cdnPt_nv_V4: - case Hexagon::STw_GP_cdnPt_V4: - case Hexagon::STw_GP_cPt_nv_V4: - return Hexagon::STw_GP_cPt_V4; - - case Hexagon::STw_GP_cdnNotPt_nv_V4: - case Hexagon::STw_GP_cdnNotPt_V4: - case Hexagon::STw_GP_cNotPt_nv_V4: - return Hexagon::STw_GP_cNotPt_V4; - - case Hexagon::STriw_GP_cdnPt_nv_V4: - case Hexagon::STriw_GP_cdnPt_V4: - case Hexagon::STriw_GP_cPt_nv_V4: - return Hexagon::STriw_GP_cPt_V4; - - case Hexagon::STriw_GP_cdnNotPt_nv_V4: - case Hexagon::STriw_GP_cdnNotPt_V4: - case Hexagon::STriw_GP_cNotPt_nv_V4: - return Hexagon::STriw_GP_cNotPt_V4; - - // Store new-value word - unconditional - - case Hexagon::STriw_nv_V4: - return Hexagon::STriw; - - case Hexagon::STriw_indexed_nv_V4: - return Hexagon::STriw_indexed; - - case Hexagon::STriw_indexed_shl_nv_V4: - return Hexagon::STriw_indexed_shl_V4; - - case Hexagon::STriw_shl_nv_V4: - return Hexagon::STriw_shl_V4; - - case Hexagon::STriw_GP_nv_V4: - return Hexagon::STriw_GP_V4; - - case Hexagon::STw_GP_nv_V4: - return Hexagon::STw_GP_V4; - - case Hexagon::POST_STwri_nv_V4: - return Hexagon::POST_STwri; - - // Store doubleword - - case Hexagon::STrid_cdnPt_V4 : - return Hexagon::STrid_cPt; - - case Hexagon::STrid_cdnNotPt_V4 : - return Hexagon::STrid_cNotPt; - - case Hexagon::STrid_indexed_cdnPt_V4 : - return Hexagon::STrid_indexed_cPt; - - case Hexagon::STrid_indexed_cdnNotPt_V4 : - return Hexagon::STrid_indexed_cNotPt; - - case Hexagon::STrid_indexed_shl_cdnPt_V4 : - return Hexagon::STrid_indexed_shl_cPt_V4; - - case Hexagon::STrid_indexed_shl_cdnNotPt_V4 : - return Hexagon::STrid_indexed_shl_cNotPt_V4; - - case Hexagon::POST_STdri_cdnPt_V4 : - return Hexagon::POST_STdri_cPt; - - case Hexagon::POST_STdri_cdnNotPt_V4 : - return Hexagon::POST_STdri_cNotPt; - - case Hexagon::STd_GP_cdnPt_V4 : - return Hexagon::STd_GP_cPt_V4; - - case Hexagon::STd_GP_cdnNotPt_V4 : - return Hexagon::STd_GP_cNotPt_V4; - - case Hexagon::STrid_GP_cdnPt_V4 : - return Hexagon::STrid_GP_cPt_V4; - - case Hexagon::STrid_GP_cdnNotPt_V4 : - return Hexagon::STrid_GP_cNotPt_V4; - } -} - -bool HexagonPacketizerList::DemoteToDotOld(MachineInstr* MI) { - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - int NewOpcode = GetDotOldOp(MI->getOpcode()); - MI->setDesc(QII->get(NewOpcode)); - return true; -} - -// Returns true if an instruction is predicated on p0 and false if it's -// predicated on !p0. - -static bool GetPredicateSense(MachineInstr* MI, - const HexagonInstrInfo *QII) { - - switch (MI->getOpcode()) { - case Hexagon::TFR_cPt: - case Hexagon::TFR_cdnPt: - case Hexagon::TFRI_cPt: - case Hexagon::TFRI_cdnPt: - case Hexagon::STrib_cPt : - case Hexagon::STrib_cdnPt_V4 : - case Hexagon::STrib_indexed_cPt : - case Hexagon::STrib_indexed_cdnPt_V4 : - case Hexagon::STrib_indexed_shl_cPt_V4 : - case Hexagon::STrib_indexed_shl_cdnPt_V4 : - case Hexagon::POST_STbri_cPt : - case Hexagon::POST_STbri_cdnPt_V4 : - case Hexagon::STrih_cPt : - case Hexagon::STrih_cdnPt_V4 : - case Hexagon::STrih_indexed_cPt : - case Hexagon::STrih_indexed_cdnPt_V4 : - case Hexagon::STrih_indexed_shl_cPt_V4 : - case Hexagon::STrih_indexed_shl_cdnPt_V4 : - case Hexagon::POST_SThri_cPt : - case Hexagon::POST_SThri_cdnPt_V4 : - case Hexagon::STriw_cPt : - case Hexagon::STriw_cdnPt_V4 : - case Hexagon::STriw_indexed_cPt : - case Hexagon::STriw_indexed_cdnPt_V4 : - case Hexagon::STriw_indexed_shl_cPt_V4 : - case Hexagon::STriw_indexed_shl_cdnPt_V4 : - case Hexagon::POST_STwri_cPt : - case Hexagon::POST_STwri_cdnPt_V4 : - case Hexagon::STrib_imm_cPt_V4 : - case Hexagon::STrib_imm_cdnPt_V4 : - case Hexagon::STrid_cPt : - case Hexagon::STrid_cdnPt_V4 : - case Hexagon::STrid_indexed_cPt : - case Hexagon::STrid_indexed_cdnPt_V4 : - case Hexagon::STrid_indexed_shl_cPt_V4 : - case Hexagon::STrid_indexed_shl_cdnPt_V4 : - case Hexagon::POST_STdri_cPt : - case Hexagon::POST_STdri_cdnPt_V4 : - case Hexagon::STrih_imm_cPt_V4 : - case Hexagon::STrih_imm_cdnPt_V4 : - case Hexagon::STriw_imm_cPt_V4 : - case Hexagon::STriw_imm_cdnPt_V4 : - case Hexagon::JMP_cdnPt : - case Hexagon::LDrid_cPt : - case Hexagon::LDrid_cdnPt : - case Hexagon::LDrid_indexed_cPt : - case Hexagon::LDrid_indexed_cdnPt : - case Hexagon::POST_LDrid_cPt : - case Hexagon::POST_LDrid_cdnPt_V4 : - case Hexagon::LDriw_cPt : - case Hexagon::LDriw_cdnPt : - case Hexagon::LDriw_indexed_cPt : - case Hexagon::LDriw_indexed_cdnPt : - case Hexagon::POST_LDriw_cPt : - case Hexagon::POST_LDriw_cdnPt_V4 : - case Hexagon::LDrih_cPt : - case Hexagon::LDrih_cdnPt : - case Hexagon::LDrih_indexed_cPt : - case Hexagon::LDrih_indexed_cdnPt : - case Hexagon::POST_LDrih_cPt : - case Hexagon::POST_LDrih_cdnPt_V4 : - case Hexagon::LDrib_cPt : - case Hexagon::LDrib_cdnPt : - case Hexagon::LDrib_indexed_cPt : - case Hexagon::LDrib_indexed_cdnPt : - case Hexagon::POST_LDrib_cPt : - case Hexagon::POST_LDrib_cdnPt_V4 : - case Hexagon::LDriuh_cPt : - case Hexagon::LDriuh_cdnPt : - case Hexagon::LDriuh_indexed_cPt : - case Hexagon::LDriuh_indexed_cdnPt : - case Hexagon::POST_LDriuh_cPt : - case Hexagon::POST_LDriuh_cdnPt_V4 : - case Hexagon::LDriub_cPt : - case Hexagon::LDriub_cdnPt : - case Hexagon::LDriub_indexed_cPt : - case Hexagon::LDriub_indexed_cdnPt : - case Hexagon::POST_LDriub_cPt : - case Hexagon::POST_LDriub_cdnPt_V4 : - case Hexagon::LDrid_indexed_cPt_V4 : - case Hexagon::LDrid_indexed_cdnPt_V4 : - case Hexagon::LDrid_indexed_shl_cPt_V4 : - case Hexagon::LDrid_indexed_shl_cdnPt_V4 : - case Hexagon::LDrib_indexed_cPt_V4 : - case Hexagon::LDrib_indexed_cdnPt_V4 : - case Hexagon::LDrib_indexed_shl_cPt_V4 : - case Hexagon::LDrib_indexed_shl_cdnPt_V4 : - case Hexagon::LDriub_indexed_cPt_V4 : - case Hexagon::LDriub_indexed_cdnPt_V4 : - case Hexagon::LDriub_indexed_shl_cPt_V4 : - case Hexagon::LDriub_indexed_shl_cdnPt_V4 : - case Hexagon::LDrih_indexed_cPt_V4 : - case Hexagon::LDrih_indexed_cdnPt_V4 : - case Hexagon::LDrih_indexed_shl_cPt_V4 : - case Hexagon::LDrih_indexed_shl_cdnPt_V4 : - case Hexagon::LDriuh_indexed_cPt_V4 : - case Hexagon::LDriuh_indexed_cdnPt_V4 : - case Hexagon::LDriuh_indexed_shl_cPt_V4 : - case Hexagon::LDriuh_indexed_shl_cdnPt_V4 : - case Hexagon::LDriw_indexed_cPt_V4 : - case Hexagon::LDriw_indexed_cdnPt_V4 : - case Hexagon::LDriw_indexed_shl_cPt_V4 : - case Hexagon::LDriw_indexed_shl_cdnPt_V4 : - case Hexagon::ADD_ri_cPt : - case Hexagon::ADD_ri_cdnPt : - case Hexagon::ADD_rr_cPt : - case Hexagon::ADD_rr_cdnPt : - case Hexagon::XOR_rr_cPt : - case Hexagon::XOR_rr_cdnPt : - case Hexagon::AND_rr_cPt : - case Hexagon::AND_rr_cdnPt : - case Hexagon::OR_rr_cPt : - case Hexagon::OR_rr_cdnPt : - case Hexagon::SUB_rr_cPt : - case Hexagon::SUB_rr_cdnPt : - case Hexagon::COMBINE_rr_cPt : - case Hexagon::COMBINE_rr_cdnPt : - case Hexagon::ASLH_cPt_V4 : - case Hexagon::ASLH_cdnPt_V4 : - case Hexagon::ASRH_cPt_V4 : - case Hexagon::ASRH_cdnPt_V4 : - case Hexagon::SXTB_cPt_V4 : - case Hexagon::SXTB_cdnPt_V4 : - case Hexagon::SXTH_cPt_V4 : - case Hexagon::SXTH_cdnPt_V4 : - case Hexagon::ZXTB_cPt_V4 : - case Hexagon::ZXTB_cdnPt_V4 : - case Hexagon::ZXTH_cPt_V4 : - case Hexagon::ZXTH_cdnPt_V4 : - case Hexagon::LDrid_GP_cPt_V4 : - case Hexagon::LDrib_GP_cPt_V4 : - case Hexagon::LDriub_GP_cPt_V4 : - case Hexagon::LDrih_GP_cPt_V4 : - case Hexagon::LDriuh_GP_cPt_V4 : - case Hexagon::LDriw_GP_cPt_V4 : - case Hexagon::LDd_GP_cPt_V4 : - case Hexagon::LDb_GP_cPt_V4 : - case Hexagon::LDub_GP_cPt_V4 : - case Hexagon::LDh_GP_cPt_V4 : - case Hexagon::LDuh_GP_cPt_V4 : - case Hexagon::LDw_GP_cPt_V4 : - case Hexagon::STrid_GP_cPt_V4 : - case Hexagon::STrib_GP_cPt_V4 : - case Hexagon::STrih_GP_cPt_V4 : - case Hexagon::STriw_GP_cPt_V4 : - case Hexagon::STd_GP_cPt_V4 : - case Hexagon::STb_GP_cPt_V4 : - case Hexagon::STh_GP_cPt_V4 : - case Hexagon::STw_GP_cPt_V4 : - case Hexagon::LDrid_GP_cdnPt_V4 : - case Hexagon::LDrib_GP_cdnPt_V4 : - case Hexagon::LDriub_GP_cdnPt_V4 : - case Hexagon::LDrih_GP_cdnPt_V4 : - case Hexagon::LDriuh_GP_cdnPt_V4 : - case Hexagon::LDriw_GP_cdnPt_V4 : - case Hexagon::LDd_GP_cdnPt_V4 : - case Hexagon::LDb_GP_cdnPt_V4 : - case Hexagon::LDub_GP_cdnPt_V4 : - case Hexagon::LDh_GP_cdnPt_V4 : - case Hexagon::LDuh_GP_cdnPt_V4 : - case Hexagon::LDw_GP_cdnPt_V4 : - case Hexagon::STrid_GP_cdnPt_V4 : - case Hexagon::STrib_GP_cdnPt_V4 : - case Hexagon::STrih_GP_cdnPt_V4 : - case Hexagon::STriw_GP_cdnPt_V4 : - case Hexagon::STd_GP_cdnPt_V4 : - case Hexagon::STb_GP_cdnPt_V4 : - case Hexagon::STh_GP_cdnPt_V4 : - case Hexagon::STw_GP_cdnPt_V4 : - return true; - - case Hexagon::TFR_cNotPt: - case Hexagon::TFR_cdnNotPt: - case Hexagon::TFRI_cNotPt: - case Hexagon::TFRI_cdnNotPt: - case Hexagon::STrib_cNotPt : - case Hexagon::STrib_cdnNotPt_V4 : - case Hexagon::STrib_indexed_cNotPt : - case Hexagon::STrib_indexed_cdnNotPt_V4 : - case Hexagon::STrib_indexed_shl_cNotPt_V4 : - case Hexagon::STrib_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_STbri_cNotPt : - case Hexagon::POST_STbri_cdnNotPt_V4 : - case Hexagon::STrih_cNotPt : - case Hexagon::STrih_cdnNotPt_V4 : - case Hexagon::STrih_indexed_cNotPt : - case Hexagon::STrih_indexed_cdnNotPt_V4 : - case Hexagon::STrih_indexed_shl_cNotPt_V4 : - case Hexagon::STrih_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_SThri_cNotPt : - case Hexagon::POST_SThri_cdnNotPt_V4 : - case Hexagon::STriw_cNotPt : - case Hexagon::STriw_cdnNotPt_V4 : - case Hexagon::STriw_indexed_cNotPt : - case Hexagon::STriw_indexed_cdnNotPt_V4 : - case Hexagon::STriw_indexed_shl_cNotPt_V4 : - case Hexagon::STriw_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_STwri_cNotPt : - case Hexagon::POST_STwri_cdnNotPt_V4 : - case Hexagon::STrib_imm_cNotPt_V4 : - case Hexagon::STrib_imm_cdnNotPt_V4 : - case Hexagon::STrid_cNotPt : - case Hexagon::STrid_cdnNotPt_V4 : - case Hexagon::STrid_indexed_cdnNotPt_V4 : - case Hexagon::STrid_indexed_cNotPt : - case Hexagon::STrid_indexed_shl_cNotPt_V4 : - case Hexagon::STrid_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_STdri_cNotPt : - case Hexagon::POST_STdri_cdnNotPt_V4 : - case Hexagon::STrih_imm_cNotPt_V4 : - case Hexagon::STrih_imm_cdnNotPt_V4 : - case Hexagon::STriw_imm_cNotPt_V4 : - case Hexagon::STriw_imm_cdnNotPt_V4 : - case Hexagon::JMP_cdnNotPt : - case Hexagon::LDrid_cNotPt : - case Hexagon::LDrid_cdnNotPt : - case Hexagon::LDrid_indexed_cNotPt : - case Hexagon::LDrid_indexed_cdnNotPt : - case Hexagon::POST_LDrid_cNotPt : - case Hexagon::POST_LDrid_cdnNotPt_V4 : - case Hexagon::LDriw_cNotPt : - case Hexagon::LDriw_cdnNotPt : - case Hexagon::LDriw_indexed_cNotPt : - case Hexagon::LDriw_indexed_cdnNotPt : - case Hexagon::POST_LDriw_cNotPt : - case Hexagon::POST_LDriw_cdnNotPt_V4 : - case Hexagon::LDrih_cNotPt : - case Hexagon::LDrih_cdnNotPt : - case Hexagon::LDrih_indexed_cNotPt : - case Hexagon::LDrih_indexed_cdnNotPt : - case Hexagon::POST_LDrih_cNotPt : - case Hexagon::POST_LDrih_cdnNotPt_V4 : - case Hexagon::LDrib_cNotPt : - case Hexagon::LDrib_cdnNotPt : - case Hexagon::LDrib_indexed_cNotPt : - case Hexagon::LDrib_indexed_cdnNotPt : - case Hexagon::POST_LDrib_cNotPt : - case Hexagon::POST_LDrib_cdnNotPt_V4 : - case Hexagon::LDriuh_cNotPt : - case Hexagon::LDriuh_cdnNotPt : - case Hexagon::LDriuh_indexed_cNotPt : - case Hexagon::LDriuh_indexed_cdnNotPt : - case Hexagon::POST_LDriuh_cNotPt : - case Hexagon::POST_LDriuh_cdnNotPt_V4 : - case Hexagon::LDriub_cNotPt : - case Hexagon::LDriub_cdnNotPt : - case Hexagon::LDriub_indexed_cNotPt : - case Hexagon::LDriub_indexed_cdnNotPt : - case Hexagon::POST_LDriub_cNotPt : - case Hexagon::POST_LDriub_cdnNotPt_V4 : - case Hexagon::LDrid_indexed_cNotPt_V4 : - case Hexagon::LDrid_indexed_cdnNotPt_V4 : - case Hexagon::LDrid_indexed_shl_cNotPt_V4 : - case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDrib_indexed_cNotPt_V4 : - case Hexagon::LDrib_indexed_cdnNotPt_V4 : - case Hexagon::LDrib_indexed_shl_cNotPt_V4 : - case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriub_indexed_cNotPt_V4 : - case Hexagon::LDriub_indexed_cdnNotPt_V4 : - case Hexagon::LDriub_indexed_shl_cNotPt_V4 : - case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDrih_indexed_cNotPt_V4 : - case Hexagon::LDrih_indexed_cdnNotPt_V4 : - case Hexagon::LDrih_indexed_shl_cNotPt_V4 : - case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriuh_indexed_cNotPt_V4 : - case Hexagon::LDriuh_indexed_cdnNotPt_V4 : - case Hexagon::LDriuh_indexed_shl_cNotPt_V4 : - case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriw_indexed_cNotPt_V4 : - case Hexagon::LDriw_indexed_cdnNotPt_V4 : - case Hexagon::LDriw_indexed_shl_cNotPt_V4 : - case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 : - case Hexagon::ADD_ri_cNotPt : - case Hexagon::ADD_ri_cdnNotPt : - case Hexagon::ADD_rr_cNotPt : - case Hexagon::ADD_rr_cdnNotPt : - case Hexagon::XOR_rr_cNotPt : - case Hexagon::XOR_rr_cdnNotPt : - case Hexagon::AND_rr_cNotPt : - case Hexagon::AND_rr_cdnNotPt : - case Hexagon::OR_rr_cNotPt : - case Hexagon::OR_rr_cdnNotPt : - case Hexagon::SUB_rr_cNotPt : - case Hexagon::SUB_rr_cdnNotPt : - case Hexagon::COMBINE_rr_cNotPt : - case Hexagon::COMBINE_rr_cdnNotPt : - case Hexagon::ASLH_cNotPt_V4 : - case Hexagon::ASLH_cdnNotPt_V4 : - case Hexagon::ASRH_cNotPt_V4 : - case Hexagon::ASRH_cdnNotPt_V4 : - case Hexagon::SXTB_cNotPt_V4 : - case Hexagon::SXTB_cdnNotPt_V4 : - case Hexagon::SXTH_cNotPt_V4 : - case Hexagon::SXTH_cdnNotPt_V4 : - case Hexagon::ZXTB_cNotPt_V4 : - case Hexagon::ZXTB_cdnNotPt_V4 : - case Hexagon::ZXTH_cNotPt_V4 : - case Hexagon::ZXTH_cdnNotPt_V4 : - - case Hexagon::LDrid_GP_cNotPt_V4 : - case Hexagon::LDrib_GP_cNotPt_V4 : - case Hexagon::LDriub_GP_cNotPt_V4 : - case Hexagon::LDrih_GP_cNotPt_V4 : - case Hexagon::LDriuh_GP_cNotPt_V4 : - case Hexagon::LDriw_GP_cNotPt_V4 : - case Hexagon::LDd_GP_cNotPt_V4 : - case Hexagon::LDb_GP_cNotPt_V4 : - case Hexagon::LDub_GP_cNotPt_V4 : - case Hexagon::LDh_GP_cNotPt_V4 : - case Hexagon::LDuh_GP_cNotPt_V4 : - case Hexagon::LDw_GP_cNotPt_V4 : - case Hexagon::STrid_GP_cNotPt_V4 : - case Hexagon::STrib_GP_cNotPt_V4 : - case Hexagon::STrih_GP_cNotPt_V4 : - case Hexagon::STriw_GP_cNotPt_V4 : - case Hexagon::STd_GP_cNotPt_V4 : - case Hexagon::STb_GP_cNotPt_V4 : - case Hexagon::STh_GP_cNotPt_V4 : - case Hexagon::STw_GP_cNotPt_V4 : - case Hexagon::LDrid_GP_cdnNotPt_V4 : - case Hexagon::LDrib_GP_cdnNotPt_V4 : - case Hexagon::LDriub_GP_cdnNotPt_V4 : - case Hexagon::LDrih_GP_cdnNotPt_V4 : - case Hexagon::LDriuh_GP_cdnNotPt_V4 : - case Hexagon::LDriw_GP_cdnNotPt_V4 : - case Hexagon::LDd_GP_cdnNotPt_V4 : - case Hexagon::LDb_GP_cdnNotPt_V4 : - case Hexagon::LDub_GP_cdnNotPt_V4 : - case Hexagon::LDh_GP_cdnNotPt_V4 : - case Hexagon::LDuh_GP_cdnNotPt_V4 : - case Hexagon::LDw_GP_cdnNotPt_V4 : - case Hexagon::STrid_GP_cdnNotPt_V4 : - case Hexagon::STrib_GP_cdnNotPt_V4 : - case Hexagon::STrih_GP_cdnNotPt_V4 : - case Hexagon::STriw_GP_cdnNotPt_V4 : - case Hexagon::STd_GP_cdnNotPt_V4 : - case Hexagon::STb_GP_cdnNotPt_V4 : - case Hexagon::STh_GP_cdnNotPt_V4 : - case Hexagon::STw_GP_cdnNotPt_V4 : - return false; - - default: - assert (false && "Unknown predicate sense of the instruction"); - } - // return *some value* to avoid compiler warning - return false; -} - -bool HexagonPacketizerList::isDotNewInst(MachineInstr* MI) { - if (isNewValueInst(MI)) - return true; - - switch (MI->getOpcode()) { - case Hexagon::TFR_cdnNotPt: - case Hexagon::TFR_cdnPt: - case Hexagon::TFRI_cdnNotPt: - case Hexagon::TFRI_cdnPt: - case Hexagon::LDrid_cdnPt : - case Hexagon::LDrid_cdnNotPt : - case Hexagon::LDrid_indexed_cdnPt : - case Hexagon::LDrid_indexed_cdnNotPt : - case Hexagon::POST_LDrid_cdnPt_V4 : - case Hexagon::POST_LDrid_cdnNotPt_V4 : - case Hexagon::LDriw_cdnPt : - case Hexagon::LDriw_cdnNotPt : - case Hexagon::LDriw_indexed_cdnPt : - case Hexagon::LDriw_indexed_cdnNotPt : - case Hexagon::POST_LDriw_cdnPt_V4 : - case Hexagon::POST_LDriw_cdnNotPt_V4 : - case Hexagon::LDrih_cdnPt : - case Hexagon::LDrih_cdnNotPt : - case Hexagon::LDrih_indexed_cdnPt : - case Hexagon::LDrih_indexed_cdnNotPt : - case Hexagon::POST_LDrih_cdnPt_V4 : - case Hexagon::POST_LDrih_cdnNotPt_V4 : - case Hexagon::LDrib_cdnPt : - case Hexagon::LDrib_cdnNotPt : - case Hexagon::LDrib_indexed_cdnPt : - case Hexagon::LDrib_indexed_cdnNotPt : - case Hexagon::POST_LDrib_cdnPt_V4 : - case Hexagon::POST_LDrib_cdnNotPt_V4 : - case Hexagon::LDriuh_cdnPt : - case Hexagon::LDriuh_cdnNotPt : - case Hexagon::LDriuh_indexed_cdnPt : - case Hexagon::LDriuh_indexed_cdnNotPt : - case Hexagon::POST_LDriuh_cdnPt_V4 : - case Hexagon::POST_LDriuh_cdnNotPt_V4 : - case Hexagon::LDriub_cdnPt : - case Hexagon::LDriub_cdnNotPt : - case Hexagon::LDriub_indexed_cdnPt : - case Hexagon::LDriub_indexed_cdnNotPt : - case Hexagon::POST_LDriub_cdnPt_V4 : - case Hexagon::POST_LDriub_cdnNotPt_V4 : - - case Hexagon::LDrid_indexed_cdnPt_V4 : - case Hexagon::LDrid_indexed_cdnNotPt_V4 : - case Hexagon::LDrid_indexed_shl_cdnPt_V4 : - case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDrib_indexed_cdnPt_V4 : - case Hexagon::LDrib_indexed_cdnNotPt_V4 : - case Hexagon::LDrib_indexed_shl_cdnPt_V4 : - case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriub_indexed_cdnPt_V4 : - case Hexagon::LDriub_indexed_cdnNotPt_V4 : - case Hexagon::LDriub_indexed_shl_cdnPt_V4 : - case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDrih_indexed_cdnPt_V4 : - case Hexagon::LDrih_indexed_cdnNotPt_V4 : - case Hexagon::LDrih_indexed_shl_cdnPt_V4 : - case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriuh_indexed_cdnPt_V4 : - case Hexagon::LDriuh_indexed_cdnNotPt_V4 : - case Hexagon::LDriuh_indexed_shl_cdnPt_V4 : - case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriw_indexed_cdnPt_V4 : - case Hexagon::LDriw_indexed_cdnNotPt_V4 : - case Hexagon::LDriw_indexed_shl_cdnPt_V4 : - case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 : - -// Coditional add - case Hexagon::ADD_ri_cdnPt: - case Hexagon::ADD_ri_cdnNotPt: - case Hexagon::ADD_rr_cdnPt: - case Hexagon::ADD_rr_cdnNotPt: - - // Conditional logical operations - case Hexagon::XOR_rr_cdnPt : - case Hexagon::XOR_rr_cdnNotPt : - case Hexagon::AND_rr_cdnPt : - case Hexagon::AND_rr_cdnNotPt : - case Hexagon::OR_rr_cdnPt : - case Hexagon::OR_rr_cdnNotPt : - - // Conditonal subtract - case Hexagon::SUB_rr_cdnPt : - case Hexagon::SUB_rr_cdnNotPt : - - // Conditional combine - case Hexagon::COMBINE_rr_cdnPt : - case Hexagon::COMBINE_rr_cdnNotPt : - - // Conditional shift operations - case Hexagon::ASLH_cdnPt_V4: - case Hexagon::ASLH_cdnNotPt_V4: - case Hexagon::ASRH_cdnPt_V4: - case Hexagon::ASRH_cdnNotPt_V4: - case Hexagon::SXTB_cdnPt_V4: - case Hexagon::SXTB_cdnNotPt_V4: - case Hexagon::SXTH_cdnPt_V4: - case Hexagon::SXTH_cdnNotPt_V4: - case Hexagon::ZXTB_cdnPt_V4: - case Hexagon::ZXTB_cdnNotPt_V4: - case Hexagon::ZXTH_cdnPt_V4: - case Hexagon::ZXTH_cdnNotPt_V4: - - // Conditional stores - case Hexagon::STrib_imm_cdnPt_V4 : - case Hexagon::STrib_imm_cdnNotPt_V4 : - case Hexagon::STrib_cdnPt_V4 : - case Hexagon::STrib_cdnNotPt_V4 : - case Hexagon::STrib_indexed_cdnPt_V4 : - case Hexagon::STrib_indexed_cdnNotPt_V4 : - case Hexagon::POST_STbri_cdnPt_V4 : - case Hexagon::POST_STbri_cdnNotPt_V4 : - case Hexagon::STrib_indexed_shl_cdnPt_V4 : - case Hexagon::STrib_indexed_shl_cdnNotPt_V4 : - - // Store doubleword conditionally - case Hexagon::STrid_indexed_cdnPt_V4 : - case Hexagon::STrid_indexed_cdnNotPt_V4 : - case Hexagon::STrid_indexed_shl_cdnPt_V4 : - case Hexagon::STrid_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_STdri_cdnPt_V4 : - case Hexagon::POST_STdri_cdnNotPt_V4 : - - // Store halfword conditionally - case Hexagon::STrih_cdnPt_V4 : - case Hexagon::STrih_cdnNotPt_V4 : - case Hexagon::STrih_indexed_cdnPt_V4 : - case Hexagon::STrih_indexed_cdnNotPt_V4 : - case Hexagon::STrih_imm_cdnPt_V4 : - case Hexagon::STrih_imm_cdnNotPt_V4 : - case Hexagon::STrih_indexed_shl_cdnPt_V4 : - case Hexagon::STrih_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_SThri_cdnPt_V4 : - case Hexagon::POST_SThri_cdnNotPt_V4 : - - // Store word conditionally - case Hexagon::STriw_cdnPt_V4 : - case Hexagon::STriw_cdnNotPt_V4 : - case Hexagon::STriw_indexed_cdnPt_V4 : - case Hexagon::STriw_indexed_cdnNotPt_V4 : - case Hexagon::STriw_imm_cdnPt_V4 : - case Hexagon::STriw_imm_cdnNotPt_V4 : - case Hexagon::STriw_indexed_shl_cdnPt_V4 : - case Hexagon::STriw_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_STwri_cdnPt_V4 : - case Hexagon::POST_STwri_cdnNotPt_V4 : - - case Hexagon::LDd_GP_cdnPt_V4: - case Hexagon::LDd_GP_cdnNotPt_V4: - case Hexagon::LDb_GP_cdnPt_V4: - case Hexagon::LDb_GP_cdnNotPt_V4: - case Hexagon::LDub_GP_cdnPt_V4: - case Hexagon::LDub_GP_cdnNotPt_V4: - case Hexagon::LDh_GP_cdnPt_V4: - case Hexagon::LDh_GP_cdnNotPt_V4: - case Hexagon::LDuh_GP_cdnPt_V4: - case Hexagon::LDuh_GP_cdnNotPt_V4: - case Hexagon::LDw_GP_cdnPt_V4: - case Hexagon::LDw_GP_cdnNotPt_V4: - case Hexagon::LDrid_GP_cdnPt_V4: - case Hexagon::LDrid_GP_cdnNotPt_V4: - case Hexagon::LDrib_GP_cdnPt_V4: - case Hexagon::LDrib_GP_cdnNotPt_V4: - case Hexagon::LDriub_GP_cdnPt_V4: - case Hexagon::LDriub_GP_cdnNotPt_V4: - case Hexagon::LDrih_GP_cdnPt_V4: - case Hexagon::LDrih_GP_cdnNotPt_V4: - case Hexagon::LDriuh_GP_cdnPt_V4: - case Hexagon::LDriuh_GP_cdnNotPt_V4: - case Hexagon::LDriw_GP_cdnPt_V4: - case Hexagon::LDriw_GP_cdnNotPt_V4: - - case Hexagon::STrid_GP_cdnPt_V4: - case Hexagon::STrid_GP_cdnNotPt_V4: - case Hexagon::STrib_GP_cdnPt_V4: - case Hexagon::STrib_GP_cdnNotPt_V4: - case Hexagon::STrih_GP_cdnPt_V4: - case Hexagon::STrih_GP_cdnNotPt_V4: - case Hexagon::STriw_GP_cdnPt_V4: - case Hexagon::STriw_GP_cdnNotPt_V4: - case Hexagon::STd_GP_cdnPt_V4: - case Hexagon::STd_GP_cdnNotPt_V4: - case Hexagon::STb_GP_cdnPt_V4: - case Hexagon::STb_GP_cdnNotPt_V4: - case Hexagon::STh_GP_cdnPt_V4: - case Hexagon::STh_GP_cdnNotPt_V4: - case Hexagon::STw_GP_cdnPt_V4: - case Hexagon::STw_GP_cdnNotPt_V4: - - return true; - } - return false; -} - -static MachineOperand& GetPostIncrementOperand(MachineInstr *MI, - const HexagonInstrInfo *QII) { - assert(QII->isPostIncrement(MI) && "Not a post increment operation."); -#ifndef NDEBUG - // Post Increment means duplicates. Use dense map to find duplicates in the - // list. Caution: Densemap initializes with the minimum of 64 buckets, - // whereas there are at most 5 operands in the post increment. - DenseMap<unsigned, unsigned> DefRegsSet; - for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) - if (MI->getOperand(opNum).isReg() && - MI->getOperand(opNum).isDef()) { - DefRegsSet[MI->getOperand(opNum).getReg()] = 1; - } - - for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) - if (MI->getOperand(opNum).isReg() && - MI->getOperand(opNum).isUse()) { - if (DefRegsSet[MI->getOperand(opNum).getReg()]) { - return MI->getOperand(opNum); - } - } -#else - if (MI->getDesc().mayLoad()) { - // The 2nd operand is always the post increment operand in load. - assert(MI->getOperand(1).isReg() && - "Post increment operand has be to a register."); - return (MI->getOperand(1)); - } - if (MI->getDesc().mayStore()) { - // The 1st operand is always the post increment operand in store. - assert(MI->getOperand(0).isReg() && - "Post increment operand has be to a register."); - return (MI->getOperand(0)); - } -#endif - // we should never come here. - llvm_unreachable("mayLoad or mayStore not set for Post Increment operation"); -} - -// get the value being stored -static MachineOperand& GetStoreValueOperand(MachineInstr *MI) { - // value being stored is always the last operand. - return (MI->getOperand(MI->getNumOperands()-1)); -} - -// can be new value store? -// Following restrictions are to be respected in convert a store into -// a new value store. -// 1. If an instruction uses auto-increment, its address register cannot -// be a new-value register. Arch Spec 5.4.2.1 -// 2. If an instruction uses absolute-set addressing mode, -// its address register cannot be a new-value register. -// Arch Spec 5.4.2.1.TODO: This is not enabled as -// as absolute-set address mode patters are not implemented. -// 3. If an instruction produces a 64-bit result, its registers cannot be used -// as new-value registers. Arch Spec 5.4.2.2. -// 4. If the instruction that sets a new-value register is conditional, then -// the instruction that uses the new-value register must also be conditional, -// and both must always have their predicates evaluate identically. -// Arch Spec 5.4.2.3. -// 5. There is an implied restriction of a packet can not have another store, -// if there is a new value store in the packet. Corollary, if there is -// already a store in a packet, there can not be a new value store. -// Arch Spec: 3.4.4.2 -bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI, - MachineInstr *PacketMI, unsigned DepReg, - std::map <MachineInstr*, SUnit*> MIToSUnit) -{ - // Make sure we are looking at the store - if (!IsNewifyStore(MI)) - return false; - - // Make sure there is dependency and can be new value'ed - if (GetStoreValueOperand(MI).isReg() && - GetStoreValueOperand(MI).getReg() != DepReg) - return false; - - const HexagonRegisterInfo* QRI = (const HexagonRegisterInfo *) TM.getRegisterInfo(); - const MCInstrDesc& MCID = PacketMI->getDesc(); - // first operand is always the result - - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - const TargetRegisterClass* PacketRC = QII->getRegClass(MCID, 0, QRI); - - // if there is already an store in the packet, no can do new value store - // Arch Spec 3.4.4.2. - for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(), - VE = CurrentPacketMIs.end(); - (VI != VE); ++VI) { - SUnit* PacketSU = MIToSUnit[*VI]; - if (PacketSU->getInstr()->getDesc().mayStore() || - // if we have mayStore = 1 set on ALLOCFRAME and DEALLOCFRAME, - // then we don't need this - PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME || - PacketSU->getInstr()->getOpcode() == Hexagon::DEALLOCFRAME) - return false; - } - - if (PacketRC == Hexagon::DoubleRegsRegisterClass) { - // new value store constraint: double regs can not feed into new value store - // arch spec section: 5.4.2.2 - return false; - } - - // Make sure it's NOT the post increment register that we are going to - // new value. - if (QII->isPostIncrement(MI) && - MI->getDesc().mayStore() && - GetPostIncrementOperand(MI, QII).getReg() == DepReg) { - return false; - } - - if (QII->isPostIncrement(PacketMI) && - PacketMI->getDesc().mayLoad() && - GetPostIncrementOperand(PacketMI, QII).getReg() == DepReg) { - // if source is post_inc, or absolute-set addressing, - // it can not feed into new value store - // r3 = memw(r2++#4) - // memw(r30 + #-1404) = r2.new -> can not be new value store - // arch spec section: 5.4.2.1 - return false; - } - - // If the source that feeds the store is predicated, new value store must also be - // also predicated. - if (QII->isPredicated(PacketMI)) { - if (!QII->isPredicated(MI)) - return false; - - // Check to make sure that they both will have their predicates - // evaluate identically - unsigned predRegNumSrc; - unsigned predRegNumDst; - const TargetRegisterClass* predRegClass; - - // Get predicate register used in the source instruction - for(unsigned opNum = 0; opNum < PacketMI->getNumOperands(); opNum++) { - if ( PacketMI->getOperand(opNum).isReg()) - predRegNumSrc = PacketMI->getOperand(opNum).getReg(); - predRegClass = QRI->getMinimalPhysRegClass(predRegNumSrc); - if (predRegClass == Hexagon::PredRegsRegisterClass) { - break; - } - } - assert ((predRegClass == Hexagon::PredRegsRegisterClass ) && - ("predicate register not found in a predicated PacketMI instruction")); - - // Get predicate register used in new-value store instruction - for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) { - if ( MI->getOperand(opNum).isReg()) - predRegNumDst = MI->getOperand(opNum).getReg(); - predRegClass = QRI->getMinimalPhysRegClass(predRegNumDst); - if (predRegClass == Hexagon::PredRegsRegisterClass) { - break; - } - } - assert ((predRegClass == Hexagon::PredRegsRegisterClass ) && - ("predicate register not found in a predicated MI instruction")); - - // New-value register producer and user (store) need to satisfy these - // constraints: - // 1) Both instructions should be predicated on the same register. - // 2) If producer of the new-value register is .new predicated then store - // should also be .new predicated and if producer is not .new predicated - // then store should not be .new predicated. - // 3) Both new-value register producer and user should have same predicate - // sense, i.e, either both should be negated or both should be none negated. - - if (( predRegNumDst != predRegNumSrc) || - isDotNewInst(PacketMI) != isDotNewInst(MI) || - GetPredicateSense(MI, QII) != GetPredicateSense(PacketMI, QII)) { - return false; - } - } - - // Make sure that other than the new-value register no other store instruction - // register has been modified in the same packet. Predicate registers can be - // modified by they should not be modified between the producer and the store - // instruction as it will make them both conditional on different values. - // We already know this to be true for all the instructions before and - // including PacketMI. Howerver, we need to perform the check for the - // remaining instructions in the packet. - - std::vector<MachineInstr*>::iterator VI; - std::vector<MachineInstr*>::iterator VE; - unsigned StartCheck = 0; - - for (VI=CurrentPacketMIs.begin(), VE = CurrentPacketMIs.end(); - (VI != VE); ++VI) { - SUnit* TempSU = MIToSUnit[*VI]; - MachineInstr* TempMI = TempSU->getInstr(); - - // Following condition is true for all the instructions until PacketMI is - // reached (StartCheck is set to 0 before the for loop). - // StartCheck flag is 1 for all the instructions after PacketMI. - if (TempMI != PacketMI && !StartCheck) // start processing only after - continue; // encountering PacketMI - - StartCheck = 1; - if (TempMI == PacketMI) // We don't want to check PacketMI for dependence - continue; - - for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) { - if (MI->getOperand(opNum).isReg() && - TempSU->getInstr()->modifiesRegister(MI->getOperand(opNum).getReg(), QRI)) - return false; - } - } - - // Make sure that for non POST_INC stores: - // 1. The only use of reg is DepReg and no other registers. - // This handles V4 base+index registers. - // The following store can not be dot new. - // Eg. r0 = add(r0, #3)a - // memw(r1+r0<<#2) = r0 - if (!QII->isPostIncrement(MI) && - GetStoreValueOperand(MI).isReg() && - GetStoreValueOperand(MI).getReg() == DepReg) { - for(unsigned opNum = 0; opNum < MI->getNumOperands()-1; opNum++) { - if (MI->getOperand(opNum).isReg() && - MI->getOperand(opNum).getReg() == DepReg) { - return false; - } - } - // 2. If data definition is because of implicit definition of the register, - // do not newify the store. Eg. - // %R9<def> = ZXTH %R12, %D6<imp-use>, %R12<imp-def> - // STrih_indexed %R8, 2, %R12<kill>; mem:ST2[%scevgep343] - for(unsigned opNum = 0; opNum < PacketMI->getNumOperands(); opNum++) { - if (PacketMI->getOperand(opNum).isReg() && - PacketMI->getOperand(opNum).getReg() == DepReg && - PacketMI->getOperand(opNum).isDef() && - PacketMI->getOperand(opNum).isImplicit()) { - return false; - } - } - } - - // Can be dot new store. - return true; -} - -// can this MI to promoted to either -// new value store or new value jump -bool HexagonPacketizerList::CanPromoteToNewValue( MachineInstr *MI, - SUnit *PacketSU, unsigned DepReg, - std::map <MachineInstr*, SUnit*> MIToSUnit, - MachineBasicBlock::iterator &MII) -{ - - const HexagonRegisterInfo* QRI = (const HexagonRegisterInfo *) TM.getRegisterInfo(); - if (!QRI->Subtarget.hasV4TOps() || - !IsNewifyStore(MI)) - return false; - - MachineInstr *PacketMI = PacketSU->getInstr(); - - // Check to see the store can be new value'ed. - if (CanPromoteToNewValueStore(MI, PacketMI, DepReg, MIToSUnit)) - return true; - - // Check to see the compare/jump can be new value'ed. - // This is done as a pass on its own. Don't need to check it here. - return false; -} - -// Check to see if an instruction can be dot new -// There are three kinds. -// 1. dot new on predicate - V2/V3/V4 -// 2. dot new on stores NV/ST - V4 -// 3. dot new on jump NV/J - V4 -- This is generated in a pass. -bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI, - SUnit *PacketSU, unsigned DepReg, - std::map <MachineInstr*, SUnit*> MIToSUnit, - MachineBasicBlock::iterator &MII, - const TargetRegisterClass* RC ) -{ - // already a dot new instruction - if (isDotNewInst(MI) && !IsNewifyStore(MI)) - return false; - - if (!isNewifiable(MI)) - return false; - - // predicate .new - if (RC == Hexagon::PredRegsRegisterClass && isCondInst(MI)) - return true; - else if (RC != Hexagon::PredRegsRegisterClass && - !IsNewifyStore(MI)) // MI is not a new-value store - return false; - else { - // Create a dot new machine instruction to see if resources can be - // allocated. If not, bail out now. - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - int NewOpcode = GetDotNewOp(MI->getOpcode()); - const MCInstrDesc &desc = QII->get(NewOpcode); - DebugLoc dl; - MachineInstr *NewMI = MI->getParent()->getParent()->CreateMachineInstr(desc, dl); - bool ResourcesAvailable = ResourceTracker->canReserveResources(NewMI); - MI->getParent()->getParent()->DeleteMachineInstr(NewMI); - - if (!ResourcesAvailable) - return false; - - // new value store only - // new new value jump generated as a passes - if (!CanPromoteToNewValue(MI, PacketSU, DepReg, MIToSUnit, MII)) { - return false; - } - } - return true; -} - -// Go through the packet instructions and search for anti dependency -// between them and DepReg from MI -// Consider this case: -// Trying to add -// a) %R1<def> = TFRI_cdNotPt %P3, 2 -// to this packet: -// { -// b) %P0<def> = OR_pp %P3<kill>, %P0<kill> -// c) %P3<def> = TFR_PdRs %R23 -// d) %R1<def> = TFRI_cdnPt %P3, 4 -// } -// The P3 from a) and d) will be complements after -// a)'s P3 is converted to .new form -// Anti Dep between c) and b) is irrelevant for this case -bool HexagonPacketizerList::RestrictingDepExistInPacket (MachineInstr* MI, - unsigned DepReg, - std::map <MachineInstr*, SUnit*> MIToSUnit) { - - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - SUnit* PacketSUDep = MIToSUnit[MI]; - - for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(), - VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) { - - // We only care for dependencies to predicated instructions - if(!QII->isPredicated(*VIN)) continue; - - // Scheduling Unit for current insn in the packet - SUnit* PacketSU = MIToSUnit[*VIN]; - - // Look at dependencies between current members of the packet - // and predicate defining instruction MI. - // Make sure that dependency is on the exact register - // we care about. - if (PacketSU->isSucc(PacketSUDep)) { - for (unsigned i = 0; i < PacketSU->Succs.size(); ++i) { - if ((PacketSU->Succs[i].getSUnit() == PacketSUDep) && - (PacketSU->Succs[i].getKind() == SDep::Anti) && - (PacketSU->Succs[i].getReg() == DepReg)) { - return true; - } - } - } - } - - return false; -} - - -// Given two predicated instructions, this function detects whether -// the predicates are complements -bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1, - MachineInstr* MI2, std::map <MachineInstr*, SUnit*> MIToSUnit) { - - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - // Currently can only reason about conditional transfers - if (!QII->isConditionalTransfer(MI1) || !QII->isConditionalTransfer(MI2)) { - return false; - } - - // Scheduling unit for candidate - SUnit* SU = MIToSUnit[MI1]; - - // One corner case deals with the following scenario: - // Trying to add - // a) %R24<def> = TFR_cPt %P0, %R25 - // to this packet: - // - // { - // b) %R25<def> = TFR_cNotPt %P0, %R24 - // c) %P0<def> = CMPEQri %R26, 1 - // } - // - // On general check a) and b) are complements, but - // presence of c) will convert a) to .new form, and - // then it is not a complement - // We attempt to detect it by analyzing existing - // dependencies in the packet - - // Analyze relationships between all existing members of the packet. - // Look for Anti dependecy on the same predicate reg - // as used in the candidate - for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(), - VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) { - - // Scheduling Unit for current insn in the packet - SUnit* PacketSU = MIToSUnit[*VIN]; - - // If this instruction in the packet is succeeded by the candidate... - if (PacketSU->isSucc(SU)) { - for (unsigned i = 0; i < PacketSU->Succs.size(); ++i) { - // The corner case exist when there is true data - // dependency between candidate and one of current - // packet members, this dep is on predicate reg, and - // there already exist anti dep on the same pred in - // the packet. - if (PacketSU->Succs[i].getSUnit() == SU && - Hexagon::PredRegsRegisterClass->contains( - PacketSU->Succs[i].getReg()) && - PacketSU->Succs[i].getKind() == SDep::Data && - // Here I know that *VIN is predicate setting instruction - // with true data dep to candidate on the register - // we care about - c) in the above example. - // Now I need to see if there is an anti dependency - // from c) to any other instruction in the - // same packet on the pred reg of interest - RestrictingDepExistInPacket(*VIN,PacketSU->Succs[i].getReg(), - MIToSUnit)) { - return false; - } - } - } - } - - // If the above case does not apply, check regular - // complement condition. - // Check that the predicate register is the same and - // that the predicate sense is different - // We also need to differentiate .old vs. .new: - // !p0 is not complimentary to p0.new - return ((MI1->getOperand(1).getReg() == MI2->getOperand(1).getReg()) && - (GetPredicateSense(MI1, QII) != GetPredicateSense(MI2, QII)) && - (isDotNewInst(MI1) == isDotNewInst(MI2))); -} - -// initPacketizerState - Initialize packetizer flags -void HexagonPacketizerList::initPacketizerState() { - - Dependence = false; - PromotedToDotNew = false; - GlueToNewValueJump = false; - GlueAllocframeStore = false; - FoundSequentialDependence = false; - - return; -} - -// ignorePseudoInstruction - Ignore bundling of pseudo instructions. -bool HexagonPacketizerList::ignorePseudoInstruction(MachineInstr *MI, - MachineBasicBlock *MBB) { - if (MI->isDebugValue()) - return true; - - // We must print out inline assembly - if (MI->isInlineAsm()) - return false; - - // We check if MI has any functional units mapped to it. - // If it doesn't, we ignore the instruction. - const MCInstrDesc& TID = MI->getDesc(); - unsigned SchedClass = TID.getSchedClass(); - const InstrStage* IS = ResourceTracker->getInstrItins()->beginStage(SchedClass); - unsigned FuncUnits = IS->getUnits(); - return !FuncUnits; -} - -// isSoloInstruction: - Returns true for instructions that must be -// scheduled in their own packet. -bool HexagonPacketizerList::isSoloInstruction(MachineInstr *MI) { - - if (MI->isInlineAsm()) - return true; - - if (MI->isEHLabel()) - return true; - - // From Hexagon V4 Programmer's Reference Manual 3.4.4 Grouping constraints: - // trap, pause, barrier, icinva, isync, and syncht are solo instructions. - // They must not be grouped with other instructions in a packet. - if (IsSchedBarrier(MI)) - return true; - - return false; -} - -// isLegalToPacketizeTogether: -// SUI is the current instruction that is out side of the current packet. -// SUJ is the current instruction inside the current packet against which that -// SUI will be packetized. -bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { - MachineInstr *I = SUI->getInstr(); - MachineInstr *J = SUJ->getInstr(); - assert(I && J && "Unable to packetize null instruction!"); - - const MCInstrDesc &MCIDI = I->getDesc(); - const MCInstrDesc &MCIDJ = J->getDesc(); - - MachineBasicBlock::iterator II = I; - - const unsigned FrameSize = MF.getFrameInfo()->getStackSize(); - const HexagonRegisterInfo* QRI = (const HexagonRegisterInfo *) TM.getRegisterInfo(); - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - - // Inline asm cannot go in the packet. - if (I->getOpcode() == Hexagon::INLINEASM) - llvm_unreachable("Should not meet inline asm here!"); - - if (isSoloInstruction(I)) - llvm_unreachable("Should not meet solo instr here!"); - - // A save callee-save register function call can only be in a packet - // with instructions that don't write to the callee-save registers. - if ((QII->isSaveCalleeSavedRegsCall(I) && - DoesModifyCalleeSavedReg(J, QRI)) || - (QII->isSaveCalleeSavedRegsCall(J) && - DoesModifyCalleeSavedReg(I, QRI))) { - Dependence = true; - return false; - } - - // Two control flow instructions cannot go in the same packet. - if (IsControlFlow(I) && IsControlFlow(J)) { - Dependence = true; - return false; - } - - // A LoopN instruction cannot appear in the same packet as a jump or call. - if (IsLoopN(I) && ( IsDirectJump(J) - || MCIDJ.isCall() - || QII->isDeallocRet(J))) { - Dependence = true; - return false; - } - if (IsLoopN(J) && ( IsDirectJump(I) - || MCIDI.isCall() - || QII->isDeallocRet(I))) { - Dependence = true; - return false; - } - - // dealloc_return cannot appear in the same packet as a conditional or - // unconditional jump. - if (QII->isDeallocRet(I) && ( MCIDJ.isBranch() - || MCIDJ.isCall() - || MCIDJ.isBarrier())) { - Dependence = true; - return false; - } - - - // V4 allows dual store. But does not allow second store, if the - // first store is not in SLOT0. New value store, new value jump, - // dealloc_return and memop always take SLOT0. - // Arch spec 3.4.4.2 - if (QRI->Subtarget.hasV4TOps()) { - - if (MCIDI.mayStore() && MCIDJ.mayStore() && isNewValueInst(J)) { - Dependence = true; - return false; - } - - if ( (QII->isMemOp(J) && MCIDI.mayStore()) - || (MCIDJ.mayStore() && QII->isMemOp(I)) - || (QII->isMemOp(J) && QII->isMemOp(I))) { - Dependence = true; - return false; - } - - //if dealloc_return - if (MCIDJ.mayStore() && QII->isDeallocRet(I)){ - Dependence = true; - return false; - } - - // If an instruction feeds new value jump, glue it. - MachineBasicBlock::iterator NextMII = I; - ++NextMII; - MachineInstr *NextMI = NextMII; - - if (QII->isNewValueJump(NextMI)) { - - bool secondRegMatch = false; - bool maintainNewValueJump = false; - - if (NextMI->getOperand(1).isReg() && - I->getOperand(0).getReg() == NextMI->getOperand(1).getReg()) { - secondRegMatch = true; - maintainNewValueJump = true; - } - - if (!secondRegMatch && - I->getOperand(0).getReg() == NextMI->getOperand(0).getReg()) { - maintainNewValueJump = true; - } - - for (std::vector<MachineInstr*>::iterator - VI = CurrentPacketMIs.begin(), - VE = CurrentPacketMIs.end(); - (VI != VE && maintainNewValueJump); ++VI) { - SUnit* PacketSU = MIToSUnit[*VI]; - - // NVJ can not be part of the dual jump - Arch Spec: section 7.8 - if (PacketSU->getInstr()->getDesc().isCall()) { - Dependence = true; - break; - } - // Validate - // 1. Packet does not have a store in it. - // 2. If the first operand of the nvj is newified, and the second - // operand is also a reg, it (second reg) is not defined in - // the same packet. - // 3. If the second operand of the nvj is newified, (which means - // first operand is also a reg), first reg is not defined in - // the same packet. - if (PacketSU->getInstr()->getDesc().mayStore() || - PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME || - // Check #2. - (!secondRegMatch && NextMI->getOperand(1).isReg() && - PacketSU->getInstr()->modifiesRegister( - NextMI->getOperand(1).getReg(), QRI)) || - // Check #3. - (secondRegMatch && - PacketSU->getInstr()->modifiesRegister( - NextMI->getOperand(0).getReg(), QRI))) { - Dependence = true; - break; - } - } - if (!Dependence) - GlueToNewValueJump = true; - else - return false; - } - } - - if (SUJ->isSucc(SUI)) { - for (unsigned i = 0; - (i < SUJ->Succs.size()) && !FoundSequentialDependence; - ++i) { - - if (SUJ->Succs[i].getSUnit() != SUI) { - continue; - } - - SDep::Kind DepType = SUJ->Succs[i].getKind(); - - // For direct calls: - // Ignore register dependences for call instructions for - // packetization purposes except for those due to r31 and - // predicate registers. - // - // For indirect calls: - // Same as direct calls + check for true dependences to the register - // used in the indirect call. - // - // We completely ignore Order dependences for call instructions - // - // For returns: - // Ignore register dependences for return instructions like jumpr, - // dealloc return unless we have dependencies on the explicit uses - // of the registers used by jumpr (like r31) or dealloc return - // (like r29 or r30). - // - // TODO: Currently, jumpr is handling only return of r31. So, the - // following logic (specificaly IsCallDependent) is working fine. - // We need to enable jumpr for register other than r31 and then, - // we need to rework the last part, where it handles indirect call - // of that (IsCallDependent) function. Bug 6216 is opened for this. - // - unsigned DepReg; - const TargetRegisterClass* RC; - if (DepType == SDep::Data) { - DepReg = SUJ->Succs[i].getReg(); - RC = QRI->getMinimalPhysRegClass(DepReg); - } - if ((MCIDI.isCall() || MCIDI.isReturn()) && - (!IsRegDependence(DepType) || - !IsCallDependent(I, DepType, SUJ->Succs[i].getReg()))) { - /* do nothing */ - } - - // For instructions that can be promoted to dot-new, try to promote. - else if ((DepType == SDep::Data) && - CanPromoteToDotNew(I, SUJ, DepReg, MIToSUnit, II, RC) && - PromoteToDotNew(I, DepType, II, RC)) { - PromotedToDotNew = true; - /* do nothing */ - } - - else if ((DepType == SDep::Data) && - (QII->isNewValueJump(I))) { - /* do nothing */ - } - - // For predicated instructions, if the predicates are complements - // then there can be no dependence. - else if (QII->isPredicated(I) && - QII->isPredicated(J) && - ArePredicatesComplements(I, J, MIToSUnit)) { - /* do nothing */ - - } - else if (IsDirectJump(I) && - !MCIDJ.isBranch() && - !MCIDJ.isCall() && - (DepType == SDep::Order)) { - // Ignore Order dependences between unconditional direct branches - // and non-control-flow instructions - /* do nothing */ - } - else if (MCIDI.isConditionalBranch() && (DepType != SDep::Data) && - (DepType != SDep::Output)) { - // Ignore all dependences for jumps except for true and output - // dependences - /* do nothing */ - } - - // Ignore output dependences due to superregs. We can - // write to two different subregisters of R1:0 for instance - // in the same cycle - // - - // - // Let the - // If neither I nor J defines DepReg, then this is a - // superfluous output dependence. The dependence must be of the - // form: - // R0 = ... - // R1 = ... - // and there is an output dependence between the two instructions - // with - // DepReg = D0 - // We want to ignore these dependences. - // Ideally, the dependence constructor should annotate such - // dependences. We can then avoid this relatively expensive check. - // - else if (DepType == SDep::Output) { - // DepReg is the register that's responsible for the dependence. - unsigned DepReg = SUJ->Succs[i].getReg(); - - // Check if I and J really defines DepReg. - if (I->definesRegister(DepReg) || - J->definesRegister(DepReg)) { - FoundSequentialDependence = true; - break; - } - } - - // We ignore Order dependences for - // 1. Two loads unless they are volatile. - // 2. Two stores in V4 unless they are volatile. - else if ((DepType == SDep::Order) && - !I->hasVolatileMemoryRef() && - !J->hasVolatileMemoryRef()) { - if (QRI->Subtarget.hasV4TOps() && - // hexagonv4 allows dual store. - MCIDI.mayStore() && MCIDJ.mayStore()) { - /* do nothing */ - } - // store followed by store-- not OK on V2 - // store followed by load -- not OK on all (OK if addresses - // are not aliased) - // load followed by store -- OK on all - // load followed by load -- OK on all - else if ( !MCIDJ.mayStore()) { - /* do nothing */ - } - else { - FoundSequentialDependence = true; - break; - } - } - - // For V4, special case ALLOCFRAME. Even though there is dependency - // between ALLOCAFRAME and subsequent store, allow it to be - // packetized in a same packet. This implies that the store is using - // caller's SP. Hense, offset needs to be updated accordingly. - else if (DepType == SDep::Data - && QRI->Subtarget.hasV4TOps() - && J->getOpcode() == Hexagon::ALLOCFRAME - && (I->getOpcode() == Hexagon::STrid - || I->getOpcode() == Hexagon::STriw - || I->getOpcode() == Hexagon::STrib) - && I->getOperand(0).getReg() == QRI->getStackRegister() - && QII->isValidOffset(I->getOpcode(), - I->getOperand(1).getImm() - - (FrameSize + HEXAGON_LRFP_SIZE))) - { - GlueAllocframeStore = true; - // Since this store is to be glued with allocframe in the same - // packet, it will use SP of the previous stack frame, i.e - // caller's SP. Therefore, we need to recalculate offset according - // to this change. - I->getOperand(1).setImm(I->getOperand(1).getImm() - - (FrameSize + HEXAGON_LRFP_SIZE)); - } - - // - // Skip over anti-dependences. Two instructions that are - // anti-dependent can share a packet - // - else if (DepType != SDep::Anti) { - FoundSequentialDependence = true; - break; - } - } - - if (FoundSequentialDependence) { - Dependence = true; - return false; - } - } - - return true; -} - -// isLegalToPruneDependencies -bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) { - MachineInstr *I = SUI->getInstr(); - assert(I && SUJ->getInstr() && "Unable to packetize null instruction!"); - - const unsigned FrameSize = MF.getFrameInfo()->getStackSize(); - - if (Dependence) { - - // Check if the instruction was promoted to a dot-new. If so, demote it - // back into a dot-old. - if (PromotedToDotNew) { - DemoteToDotOld(I); - } - - // Check if the instruction (must be a store) was glued with an Allocframe - // instruction. If so, restore its offset to its original value, i.e. use - // curent SP instead of caller's SP. - if (GlueAllocframeStore) { - I->getOperand(1).setImm(I->getOperand(1).getImm() + - FrameSize + HEXAGON_LRFP_SIZE); - } - - return false; - } - return true; -} - -MachineBasicBlock::iterator HexagonPacketizerList::addToPacket(MachineInstr *MI) { - - MachineBasicBlock::iterator MII = MI; - MachineBasicBlock *MBB = MI->getParent(); - - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - - if (GlueToNewValueJump) { - - ++MII; - MachineInstr *nvjMI = MII; - assert(ResourceTracker->canReserveResources(MI)); - ResourceTracker->reserveResources(MI); - if (QII->isExtended(MI) && - !tryAllocateResourcesForConstExt(MI)) { - endPacket(MBB, MI); - ResourceTracker->reserveResources(MI); - assert(canReserveResourcesForConstExt(MI) && - "Ensure that there is a slot"); - reserveResourcesForConstExt(MI); - // Reserve resources for new value jump constant extender. - assert(canReserveResourcesForConstExt(MI) && - "Ensure that there is a slot"); - reserveResourcesForConstExt(nvjMI); - assert(ResourceTracker->canReserveResources(nvjMI) && - "Ensure that there is a slot"); - - } else if ( // Extended instruction takes two slots in the packet. - // Try reserve and allocate 4-byte in the current packet first. - (QII->isExtended(nvjMI) - && (!tryAllocateResourcesForConstExt(nvjMI) - || !ResourceTracker->canReserveResources(nvjMI))) - || // For non-extended instruction, no need to allocate extra 4 bytes. - (!QII->isExtended(nvjMI) && !ResourceTracker->canReserveResources(nvjMI))) - { - endPacket(MBB, MI); - // A new and empty packet starts. - // We are sure that the resources requirements can be satisfied. - // Therefore, do not need to call "canReserveResources" anymore. - ResourceTracker->reserveResources(MI); - if (QII->isExtended(nvjMI)) - reserveResourcesForConstExt(nvjMI); - } - // Here, we are sure that "reserveResources" would succeed. - ResourceTracker->reserveResources(nvjMI); - CurrentPacketMIs.push_back(MI); - CurrentPacketMIs.push_back(nvjMI); - } else { - if ( QII->isExtended(MI) - && ( !tryAllocateResourcesForConstExt(MI) - || !ResourceTracker->canReserveResources(MI))) - { - endPacket(MBB, MI); - // Check if the instruction was promoted to a dot-new. If so, demote it - // back into a dot-old - if (PromotedToDotNew) { - DemoteToDotOld(MI); - } - reserveResourcesForConstExt(MI); - } - // In case that "MI" is not an extended insn, - // the resource availability has already been checked. - ResourceTracker->reserveResources(MI); - CurrentPacketMIs.push_back(MI); - } - return MII; -} - -//===----------------------------------------------------------------------===// -// Public Constructor Functions -//===----------------------------------------------------------------------===// - -FunctionPass *llvm::createHexagonPacketizer() { - return new HexagonPacketizer(); -} - diff --git a/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp b/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp index 75d6bfb..47384cd 100644 --- a/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp +++ b/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp @@ -15,7 +15,6 @@ #include "Hexagon.h" #include "HexagonAsmPrinter.h" #include "HexagonInstPrinter.h" -#include "HexagonMCInst.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" @@ -38,50 +37,20 @@ StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) { - printInst((const HexagonMCInst*)(MI), O, Annot); -} - -void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O, - StringRef Annot) { const char packetPadding[] = " "; const char startPacket = '{', endPacket = '}'; // TODO: add outer HW loop when it's supported too. if (MI->getOpcode() == Hexagon::ENDLOOP0) { - // Ending a harware loop is different from ending an regular packet. - assert(MI->isEndPacket() && "Loop end must also end the packet"); - - if (MI->isStartPacket()) { - // There must be a packet to end a loop. - // FIXME: when shuffling is always run, this shouldn't be needed. - HexagonMCInst Nop; - StringRef NoAnnot; - - Nop.setOpcode (Hexagon::NOP); - Nop.setStartPacket (MI->isStartPacket()); - printInst (&Nop, O, NoAnnot); - } - - // Close the packet. - if (MI->isEndPacket()) - O << packetPadding << endPacket; + MCInst Nop; - printInstruction(MI, O); - } - else { - // Prefix the insn opening the packet. - if (MI->isStartPacket()) - O << packetPadding << startPacket << '\n'; - - printInstruction(MI, O); - - // Suffix the insn closing the packet. - if (MI->isEndPacket()) - // Suffix the packet in a new line always, since the GNU assembler has - // issues with a closing brace on the same line as CONST{32,64}. - O << '\n' << packetPadding << endPacket; + O << packetPadding << startPacket << '\n'; + Nop.setOpcode(Hexagon::NOP); + printInstruction(&Nop, O); + O << packetPadding << endPacket; } + printInstruction(MI, O); printAnnotation(O, Annot); } @@ -100,18 +69,18 @@ void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, } } -void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { +void HexagonInstPrinter::printImmOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { O << MI->getOperand(OpNo).getImm(); } void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { + raw_ostream &O) const { O << MI->getOperand(OpNo).getImm(); } -void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { +void HexagonInstPrinter::printUnsignedImmOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { O << MI->getOperand(OpNo).getImm(); } @@ -120,13 +89,13 @@ void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo, O << -MI->getOperand(OpNo).getImm(); } -void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { +void HexagonInstPrinter::printNOneImmOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { O << -1; } -void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { +void HexagonInstPrinter::printMEMriOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { const MCOperand& MO0 = MI->getOperand(OpNo); const MCOperand& MO1 = MI->getOperand(OpNo + 1); @@ -134,8 +103,8 @@ void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo, O << " + #" << MO1.getImm(); } -void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { +void HexagonInstPrinter::printFrameIndexOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { const MCOperand& MO0 = MI->getOperand(OpNo); const MCOperand& MO1 = MI->getOperand(OpNo + 1); diff --git a/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h b/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h index 3ce7dfc..dad4334 100644 --- a/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h +++ b/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h @@ -14,7 +14,6 @@ #ifndef HEXAGONINSTPRINTER_H #define HEXAGONINSTPRINTER_H -#include "HexagonMCInst.h" #include "llvm/MC/MCInstPrinter.h" namespace llvm { @@ -26,7 +25,6 @@ namespace llvm { : MCInstPrinter(MAI, MII, MRI) {} virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot); - void printInst(const HexagonMCInst *MI, raw_ostream &O, StringRef Annot); virtual StringRef getOpcodeName(unsigned Opcode) const; void printInstruction(const MCInst *MI, raw_ostream &O); StringRef getRegName(unsigned RegNo) const; diff --git a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h index 7221e90..ed55c3c 100644 --- a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h +++ b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h @@ -23,41 +23,14 @@ namespace llvm { /// instruction info tracks. /// namespace HexagonII { - // *** The code below must match HexagonInstrFormat*.td *** // - - // Insn types. - // *** Must match HexagonInstrFormat*.td *** - enum Type { - TypePSEUDO = 0, - TypeALU32 = 1, - TypeCR = 2, - TypeJR = 3, - TypeJ = 4, - TypeLD = 5, - TypeST = 6, - TypeSYSTEM = 7, - TypeXTYPE = 8, - TypeMEMOP = 9, - TypeNV = 10, - TypePREFIX = 30, // Such as extenders. - TypeMARKER = 31 // Such as end of a HW loop. - }; - + // *** The code below must match HexagonInstrFormat*.td *** // // MCInstrDesc TSFlags - // *** Must match HexagonInstrFormat*.td *** enum { - // This 5-bit field describes the insn type. - TypePos = 0, - TypeMask = 0x1f, - - // Solo instructions. - SoloPos = 5, - SoloMask = 0x1, // Predicated instructions. - PredicatedPos = 6, + PredicatedPos = 1, PredicatedMask = 0x1 }; diff --git a/contrib/llvm/lib/Target/MBlaze/MBlazeCallingConv.td b/contrib/llvm/lib/Target/MBlaze/MBlazeCallingConv.td index 4962573..00a4219 100644 --- a/contrib/llvm/lib/Target/MBlaze/MBlazeCallingConv.td +++ b/contrib/llvm/lib/Target/MBlaze/MBlazeCallingConv.td @@ -9,10 +9,6 @@ // This describes the calling conventions for MBlaze architecture. //===----------------------------------------------------------------------===// -/// CCIfSubtarget - Match if the current subtarget has a feature F. -class CCIfSubtarget<string F, CCAction A>: - CCIf<!strconcat("State.getTarget().getSubtarget<MBlazeSubtarget>().", F), A>; - //===----------------------------------------------------------------------===// // MBlaze ABI Calling Convention //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/contrib/llvm/lib/Target/MBlaze/MBlazeTargetMachine.cpp index dd7de9b..62393d0 100644 --- a/contrib/llvm/lib/Target/MBlaze/MBlazeTargetMachine.cpp +++ b/contrib/llvm/lib/Target/MBlaze/MBlazeTargetMachine.cpp @@ -68,7 +68,7 @@ TargetPassConfig *MBlazeTargetMachine::createPassConfig(PassManagerBase &PM) { // Install an instruction selector pass using // the ISelDag to gen MBlaze code. bool MBlazePassConfig::addInstSelector() { - PM.add(createMBlazeISelDag(getMBlazeTargetMachine())); + PM->add(createMBlazeISelDag(getMBlazeTargetMachine())); return false; } @@ -76,6 +76,6 @@ bool MBlazePassConfig::addInstSelector() { // machine code is emitted. return true if -print-machineinstrs should // print out the code after the passes. bool MBlazePassConfig::addPreEmitPass() { - PM.add(createMBlazeDelaySlotFillerPass(getMBlazeTargetMachine())); + PM->add(createMBlazeDelaySlotFillerPass(getMBlazeTargetMachine())); return true; } diff --git a/contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp b/contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp index 9f2eda1..3acf96b 100644 --- a/contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp +++ b/contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp @@ -60,12 +60,12 @@ TargetPassConfig *MSP430TargetMachine::createPassConfig(PassManagerBase &PM) { bool MSP430PassConfig::addInstSelector() { // Install an instruction selector. - PM.add(createMSP430ISelDag(getMSP430TargetMachine(), getOptLevel())); + PM->add(createMSP430ISelDag(getMSP430TargetMachine(), getOptLevel())); return false; } bool MSP430PassConfig::addPreEmitPass() { // Must run branch selection immediately preceding the asm printer. - PM.add(createMSP430BranchSelectionPass()); + PM->add(createMSP430BranchSelectionPass()); return false; } diff --git a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp new file mode 100644 index 0000000..78dbc06 --- /dev/null +++ b/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -0,0 +1,552 @@ +//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is part of the Mips Disassembler. +// +//===----------------------------------------------------------------------===// + +#include "Mips.h" +#include "MipsSubtarget.h" +#include "llvm/MC/EDInstInfo.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/Support/MemoryObject.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/MathExtras.h" + + +#include "MipsGenEDInfo.inc" + +using namespace llvm; + +typedef MCDisassembler::DecodeStatus DecodeStatus; + +/// MipsDisassembler - a disasembler class for Mips32. +class MipsDisassembler : public MCDisassembler { +public: + /// Constructor - Initializes the disassembler. + /// + MipsDisassembler(const MCSubtargetInfo &STI, bool bigEndian) : + MCDisassembler(STI), isBigEndian(bigEndian) { + } + + ~MipsDisassembler() { + } + + /// getInstruction - See MCDisassembler. + DecodeStatus getInstruction(MCInst &instr, + uint64_t &size, + const MemoryObject ®ion, + uint64_t address, + raw_ostream &vStream, + raw_ostream &cStream) const; + + /// getEDInfo - See MCDisassembler. + const EDInstInfo *getEDInfo() const; + +private: + bool isBigEndian; +}; + + +/// Mips64Disassembler - a disasembler class for Mips64. +class Mips64Disassembler : public MCDisassembler { +public: + /// Constructor - Initializes the disassembler. + /// + Mips64Disassembler(const MCSubtargetInfo &STI, bool bigEndian) : + MCDisassembler(STI), isBigEndian(bigEndian) { + } + + ~Mips64Disassembler() { + } + + /// getInstruction - See MCDisassembler. + DecodeStatus getInstruction(MCInst &instr, + uint64_t &size, + const MemoryObject ®ion, + uint64_t address, + raw_ostream &vStream, + raw_ostream &cStream) const; + + /// getEDInfo - See MCDisassembler. + const EDInstInfo *getEDInfo() const; + +private: + bool isBigEndian; +}; + +const EDInstInfo *MipsDisassembler::getEDInfo() const { + return instInfoMips; +} + +const EDInstInfo *Mips64Disassembler::getEDInfo() const { + return instInfoMips; +} + +// Decoder tables for Mips register +static const unsigned CPURegsTable[] = { + Mips::ZERO, Mips::AT, Mips::V0, Mips::V1, + Mips::A0, Mips::A1, Mips::A2, Mips::A3, + Mips::T0, Mips::T1, Mips::T2, Mips::T3, + Mips::T4, Mips::T5, Mips::T6, Mips::T7, + Mips::S0, Mips::S1, Mips::S2, Mips::S3, + Mips::S4, Mips::S5, Mips::S6, Mips::S7, + Mips::T8, Mips::T9, Mips::K0, Mips::K1, + Mips::GP, Mips::SP, Mips::FP, Mips::RA +}; + +static const unsigned FGR32RegsTable[] = { + Mips::F0, Mips::F1, Mips::F2, Mips::F3, + Mips::F4, Mips::F5, Mips::F6, Mips::F7, + Mips::F8, Mips::F9, Mips::F10, Mips::F11, + Mips::F12, Mips::F13, Mips::F14, Mips::F15, + Mips::F16, Mips::F17, Mips::F18, Mips::F18, + Mips::F20, Mips::F21, Mips::F22, Mips::F23, + Mips::F24, Mips::F25, Mips::F26, Mips::F27, + Mips::F28, Mips::F29, Mips::F30, Mips::F31 +}; + +static const unsigned CPU64RegsTable[] = { + Mips::ZERO_64, Mips::AT_64, Mips::V0_64, Mips::V1_64, + Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64, + Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64, + Mips::T4_64, Mips::T5_64, Mips::T6_64, Mips::T7_64, + Mips::S0_64, Mips::S1_64, Mips::S2_64, Mips::S3_64, + Mips::S4_64, Mips::S5_64, Mips::S6_64, Mips::S7_64, + Mips::T8_64, Mips::T9_64, Mips::K0_64, Mips::K1_64, + Mips::GP_64, Mips::SP_64, Mips::FP_64, Mips::RA_64 +}; + +static const unsigned FGR64RegsTable[] = { + Mips::D0_64, Mips::D1_64, Mips::D2_64, Mips::D3_64, + Mips::D4_64, Mips::D5_64, Mips::D6_64, Mips::D7_64, + Mips::D8_64, Mips::D9_64, Mips::D10_64, Mips::D11_64, + Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64, + Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64, + Mips::D20_64, Mips::D21_64, Mips::D22_64, Mips::D23_64, + Mips::D24_64, Mips::D25_64, Mips::D26_64, Mips::D27_64, + Mips::D28_64, Mips::D29_64, Mips::D30_64, Mips::D31_64 +}; + +static const unsigned AFGR64RegsTable[] = { + Mips::D0, Mips::D1, Mips::D2, Mips::D3, + Mips::D4, Mips::D5, Mips::D6, Mips::D7, + Mips::D8, Mips::D9, Mips::D10, Mips::D11, + Mips::D12, Mips::D13, Mips::D14, Mips::D15 +}; + +// Forward declare these because the autogenerated code will reference them. +// Definitions are further down. +static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeBranchTarget(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeBC1(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + + +static DecodeStatus DecodeJumpTarget(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMem(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeSimm16(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeCondCode(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeInsSize(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeExtSize(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +namespace llvm { +extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, + TheMips64elTarget; +} + +static MCDisassembler *createMipsDisassembler( + const Target &T, + const MCSubtargetInfo &STI) { + return new MipsDisassembler(STI,true); +} + +static MCDisassembler *createMipselDisassembler( + const Target &T, + const MCSubtargetInfo &STI) { + return new MipsDisassembler(STI,false); +} + +static MCDisassembler *createMips64Disassembler( + const Target &T, + const MCSubtargetInfo &STI) { + return new Mips64Disassembler(STI,true); +} + +static MCDisassembler *createMips64elDisassembler( + const Target &T, + const MCSubtargetInfo &STI) { + return new Mips64Disassembler(STI, false); +} + +extern "C" void LLVMInitializeMipsDisassembler() { + // Register the disassembler. + TargetRegistry::RegisterMCDisassembler(TheMipsTarget, + createMipsDisassembler); + TargetRegistry::RegisterMCDisassembler(TheMipselTarget, + createMipselDisassembler); + TargetRegistry::RegisterMCDisassembler(TheMips64Target, + createMips64Disassembler); + TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, + createMips64elDisassembler); +} + + +#include "MipsGenDisassemblerTables.inc" + + /// readInstruction - read four bytes from the MemoryObject + /// and return 32 bit word sorted according to the given endianess +static DecodeStatus readInstruction32(const MemoryObject ®ion, + uint64_t address, + uint64_t &size, + uint32_t &insn, + bool isBigEndian) { + uint8_t Bytes[4]; + + // We want to read exactly 4 Bytes of data. + if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) { + size = 0; + return MCDisassembler::Fail; + } + + if (isBigEndian) { + // Encoded as a big-endian 32-bit word in the stream. + insn = (Bytes[3] << 0) | + (Bytes[2] << 8) | + (Bytes[1] << 16) | + (Bytes[0] << 24); + } + else { + // Encoded as a small-endian 32-bit word in the stream. + insn = (Bytes[0] << 0) | + (Bytes[1] << 8) | + (Bytes[2] << 16) | + (Bytes[3] << 24); + } + + return MCDisassembler::Success; +} + +DecodeStatus +MipsDisassembler::getInstruction(MCInst &instr, + uint64_t &Size, + const MemoryObject &Region, + uint64_t Address, + raw_ostream &vStream, + raw_ostream &cStream) const { + uint32_t Insn; + + DecodeStatus Result = readInstruction32(Region, Address, Size, + Insn, isBigEndian); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + // Calling the auto-generated decoder function. + Result = decodeMipsInstruction32(instr, Insn, Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + + return MCDisassembler::Fail; +} + +DecodeStatus +Mips64Disassembler::getInstruction(MCInst &instr, + uint64_t &Size, + const MemoryObject &Region, + uint64_t Address, + raw_ostream &vStream, + raw_ostream &cStream) const { + uint32_t Insn; + + DecodeStatus Result = readInstruction32(Region, Address, Size, + Insn, isBigEndian); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + // Calling the auto-generated decoder function. + Result = decodeMips64Instruction32(instr, Insn, Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + // If we fail to decode in Mips64 decoder space we can try in Mips32 + Result = decodeMipsInstruction32(instr, Insn, Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + + return MCDisassembler::Fail; +} + +static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + + if (RegNo > 31) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::CreateReg(CPU64RegsTable[RegNo])); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::CreateReg(CPURegsTable[RegNo])); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[RegNo])); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::CreateReg(FGR32RegsTable[RegNo])); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + Inst.addOperand(MCOperand::CreateReg(RegNo)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeMem(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<16>(Insn & 0xffff); + int Reg = (int)fieldFromInstruction32(Insn, 16, 5); + int Base = (int)fieldFromInstruction32(Insn, 21, 5); + + if(Inst.getOpcode() == Mips::SC){ + Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg])); + } + + Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg])); + Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base])); + Inst.addOperand(MCOperand::CreateImm(Offset)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeFMem(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<16>(Insn & 0xffff); + int Reg = (int)fieldFromInstruction32(Insn, 16, 5); + int Base = (int)fieldFromInstruction32(Insn, 21, 5); + + Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[Reg])); + Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base])); + Inst.addOperand(MCOperand::CreateImm(Offset)); + + return MCDisassembler::Success; +} + + +static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + // Currently only hardware register 29 is supported. + if (RegNo != 29) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeCondCode(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int CondCode = Insn & 0xf; + Inst.addOperand(MCOperand::CreateImm(CondCode)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::CreateReg(AFGR64RegsTable[RegNo])); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + //Currently only hardware register 29 is supported + if (RegNo != 29) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeBranchTarget(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + unsigned BranchOffset = Offset & 0xffff; + BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; + Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeBC1(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned BranchOffset = Insn & 0xffff; + BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; + Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeJumpTarget(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + + unsigned JumpOffset = fieldFromInstruction32(Insn, 0, 26) << 2; + Inst.addOperand(MCOperand::CreateImm(JumpOffset)); + return MCDisassembler::Success; +} + + +static DecodeStatus DecodeSimm16(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeInsSize(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + // First we need to grab the pos(lsb) from MCInst. + int Pos = Inst.getOperand(2).getImm(); + int Size = (int) Insn - Pos + 1; + Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeExtSize(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Size = (int) Insn + 1; + Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); + return MCDisassembler::Success; +} diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index e79be33..9b4caf6 100644 --- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// // -#include "MipsBaseInfo.h" #include "MipsFixupKinds.h" #include "MCTargetDesc/MipsMCTargetDesc.h" #include "llvm/MC/MCAsmBackend.h" @@ -85,9 +84,8 @@ public: uint64_t Value) const { MCFixupKind Kind = Fixup.getKind(); Value = adjustFixupValue((unsigned)Kind, Value); - int64_t SymOffset = MipsGetSymAndOffset(Fixup).second; - if (!Value && !SymOffset) + if (!Value) return; // Doesn't change encoding. // Where do we start in the object @@ -118,7 +116,7 @@ public: } uint64_t Mask = ((uint64_t)(-1) >> (64 - getFixupKindInfo(Kind).TargetSize)); - CurVal |= (Value + SymOffset) & Mask; + CurVal |= Value & Mask; // Write out the fixed up bytes back to the code/data bits. for (unsigned i = 0; i != NumBytes; ++i) { diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 27954b1..4ed2be0 100644 --- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -194,7 +194,7 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, assert (Kind == MCExpr::SymbolRef); - Mips::Fixups FixupKind; + Mips::Fixups FixupKind = Mips::Fixups(0); switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { case MCSymbolRefExpr::VK_Mips_GPREL: diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index 3c544f6..f634f08 100644 --- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -34,6 +34,38 @@ using namespace llvm; +static std::string ParseMipsTriple(StringRef TT, StringRef CPU) { + std::string MipsArchFeature; + size_t DashPosition = 0; + StringRef TheTriple; + + // Let's see if there is a dash, like mips-unknown-linux. + DashPosition = TT.find('-'); + + if (DashPosition == StringRef::npos) { + // No dash, we check the string size. + TheTriple = TT.substr(0); + } else { + // We are only interested in substring before dash. + TheTriple = TT.substr(0,DashPosition); + } + + if (TheTriple == "mips" || TheTriple == "mipsel") { + if (CPU.empty() || CPU == "mips32") { + MipsArchFeature = "+mips32"; + } else if (CPU == "mips32r2") { + MipsArchFeature = "+mips32r2"; + } + } else { + if (CPU.empty() || CPU == "mips64") { + MipsArchFeature = "+mips64"; + } else if (CPU == "mips64r2") { + MipsArchFeature = "+mips64r2"; + } + } + return MipsArchFeature; +} + static MCInstrInfo *createMipsMCInstrInfo() { MCInstrInfo *X = new MCInstrInfo(); InitMipsMCInstrInfo(X); @@ -48,8 +80,15 @@ static MCRegisterInfo *createMipsMCRegisterInfo(StringRef TT) { static MCSubtargetInfo *createMipsMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) { + std::string ArchFS = ParseMipsTriple(TT,CPU); + if (!FS.empty()) { + if (!ArchFS.empty()) + ArchFS = ArchFS + "," + FS.str(); + else + ArchFS = FS; + } MCSubtargetInfo *X = new MCSubtargetInfo(); - InitMipsMCSubtargetInfo(X, TT, CPU, FS); + InitMipsMCSubtargetInfo(X, TT, CPU, ArchFS); return X; } diff --git a/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td b/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td index 427e8d9..0382869 100644 --- a/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -36,6 +36,7 @@ def immZExt6 : ImmLeaf<i32, [{return Imm == (Imm & 0x3f);}]>; //===----------------------------------------------------------------------===// // Shifts // 64-bit shift instructions. +let DecoderNamespace = "Mips64" in { class shift_rotate_imm64<bits<6> func, bits<5> isRotate, string instr_asm, SDNode OpNode>: shift_rotate_imm<func, isRotate, instr_asm, OpNode, immZExt6, shamt, @@ -49,16 +50,21 @@ class Div64<SDNode op, bits<6> func, string instr_asm, InstrItinClass itin>: multiclass Atomic2Ops64<PatFrag Op, string Opstr> { def #NAME# : Atomic2Ops<Op, Opstr, CPU64Regs, CPURegs>, Requires<[NotN64]>; - def _P8 : Atomic2Ops<Op, Opstr, CPU64Regs, CPU64Regs>, Requires<[IsN64]>; + def _P8 : Atomic2Ops<Op, Opstr, CPU64Regs, CPU64Regs>, Requires<[IsN64]> { + let isCodeGenOnly = 1; + } } multiclass AtomicCmpSwap64<PatFrag Op, string Width> { def #NAME# : AtomicCmpSwap<Op, Width, CPU64Regs, CPURegs>, Requires<[NotN64]>; def _P8 : AtomicCmpSwap<Op, Width, CPU64Regs, CPU64Regs>, - Requires<[IsN64]>; + Requires<[IsN64]> { + let isCodeGenOnly = 1; + } } - -let usesCustomInserter = 1, Predicates = [HasMips64] in { +} +let usesCustomInserter = 1, Predicates = [HasMips64], + DecoderNamespace = "Mips64" in { defm ATOMIC_LOAD_ADD_I64 : Atomic2Ops64<atomic_load_add_64, "load_add_64">; defm ATOMIC_LOAD_SUB_I64 : Atomic2Ops64<atomic_load_sub_64, "load_sub_64">; defm ATOMIC_LOAD_AND_I64 : Atomic2Ops64<atomic_load_and_64, "load_and_64">; @@ -72,7 +78,7 @@ let usesCustomInserter = 1, Predicates = [HasMips64] in { //===----------------------------------------------------------------------===// // Instruction definition //===----------------------------------------------------------------------===// - +let DecoderNamespace = "Mips64" in { /// Arithmetic Instructions (ALU Immediate) def DADDiu : ArithLogicI<0x19, "daddiu", add, simm16_64, immSExt16, CPU64Regs>; @@ -97,16 +103,17 @@ def NOR64 : LogicNOR<0x00, 0x27, "nor", CPU64Regs>; def DSLL : shift_rotate_imm64<0x38, 0x00, "dsll", shl>; def DSRL : shift_rotate_imm64<0x3a, 0x00, "dsrl", srl>; def DSRA : shift_rotate_imm64<0x3b, 0x00, "dsra", sra>; -def DSLLV : shift_rotate_reg<0x24, 0x00, "dsllv", shl, CPU64Regs>; -def DSRLV : shift_rotate_reg<0x26, 0x00, "dsrlv", srl, CPU64Regs>; -def DSRAV : shift_rotate_reg<0x27, 0x00, "dsrav", sra, CPU64Regs>; - +def DSLLV : shift_rotate_reg<0x14, 0x00, "dsllv", shl, CPU64Regs>; +def DSRLV : shift_rotate_reg<0x16, 0x00, "dsrlv", srl, CPU64Regs>; +def DSRAV : shift_rotate_reg<0x17, 0x00, "dsrav", sra, CPU64Regs>; +} // Rotate Instructions -let Predicates = [HasMips64r2] in { +let Predicates = [HasMips64r2], DecoderNamespace = "Mips64" in { def DROTR : shift_rotate_imm64<0x3a, 0x01, "drotr", rotr>; def DROTRV : shift_rotate_reg<0x16, 0x01, "drotrv", rotr, CPU64Regs>; } +let DecoderNamespace = "Mips64" in { /// Load and Store Instructions /// aligned defm LB64 : LoadM64<0x20, "lb", sextloadi8>; @@ -132,9 +139,13 @@ defm USD : StoreM64<0x3f, "usd", store_u, 1>; /// Load-linked, Store-conditional def LLD : LLBase<0x34, "lld", CPU64Regs, mem>, Requires<[NotN64]>; -def LLD_P8 : LLBase<0x34, "lld", CPU64Regs, mem64>, Requires<[IsN64]>; +def LLD_P8 : LLBase<0x34, "lld", CPU64Regs, mem64>, Requires<[IsN64]> { + let isCodeGenOnly = 1; +} def SCD : SCBase<0x3c, "scd", CPU64Regs, mem>, Requires<[NotN64]>; -def SCD_P8 : SCBase<0x3c, "scd", CPU64Regs, mem64>, Requires<[IsN64]>; +def SCD_P8 : SCBase<0x3c, "scd", CPU64Regs, mem64>, Requires<[IsN64]> { + let isCodeGenOnly = 1; +} /// Jump and Branch Instructions def JR64 : JumpFR<0x00, 0x08, "jr", CPU64Regs>; @@ -142,11 +153,13 @@ def BEQ64 : CBranch<0x04, "beq", seteq, CPU64Regs>; def BNE64 : CBranch<0x05, "bne", setne, CPU64Regs>; def BGEZ64 : CBranchZero<0x01, 1, "bgez", setge, CPU64Regs>; def BGTZ64 : CBranchZero<0x07, 0, "bgtz", setgt, CPU64Regs>; -def BLEZ64 : CBranchZero<0x07, 0, "blez", setle, CPU64Regs>; +def BLEZ64 : CBranchZero<0x06, 0, "blez", setle, CPU64Regs>; def BLTZ64 : CBranchZero<0x01, 0, "bltz", setlt, CPU64Regs>; - +} +let DecoderNamespace = "Mips64" in def JALR64 : JumpLinkReg<0x00, 0x09, "jalr", CPU64Regs>; +let DecoderNamespace = "Mips64" in { /// Multiply and Divide Instructions. def DMULT : Mult64<0x1c, "dmult", IIImul>; def DMULTu : Mult64<0x1d, "dmultu", IIImul>; @@ -171,11 +184,13 @@ def DSBH : SubwordSwap<0x24, 0x2, "dsbh", CPU64Regs>; def DSHD : SubwordSwap<0x24, 0x5, "dshd", CPU64Regs>; def LEA_ADDiu64 : EffectiveAddress<"daddiu\t$rt, $addr", CPU64Regs, mem_ea_64>; - -let Uses = [SP_64] in +} +let Uses = [SP_64], DecoderNamespace = "Mips64" in def DynAlloc64 : EffectiveAddress<"daddiu\t$rt, $addr", CPU64Regs, mem_ea_64>, - Requires<[IsN64]>; - + Requires<[IsN64]> { + let isCodeGenOnly = 1; +} +let DecoderNamespace = "Mips64" in { def RDHWR64 : ReadHardware<CPU64Regs, HWRegs64>; def DEXT : ExtBase<3, "dext", CPU64Regs>; @@ -183,12 +198,12 @@ def DINS : InsBase<7, "dins", CPU64Regs>; def DSLL64_32 : FR<0x3c, 0x00, (outs CPU64Regs:$rd), (ins CPURegs:$rt), "dsll\t$rd, $rt, 32", [], IIAlu>; - def SLL64_32 : FR<0x0, 0x00, (outs CPU64Regs:$rd), (ins CPURegs:$rt), "sll\t$rd, $rt, 0", [], IIAlu>; +let isCodeGenOnly = 1 in def SLL64_64 : FR<0x0, 0x00, (outs CPU64Regs:$rd), (ins CPU64Regs:$rt), "sll\t$rd, $rt, 0", [], IIAlu>; - +} //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/Target/Mips/MipsCondMov.td b/contrib/llvm/lib/Target/Mips/MipsCondMov.td index 075a3e8..da33680 100644 --- a/contrib/llvm/lib/Target/Mips/MipsCondMov.td +++ b/contrib/llvm/lib/Target/Mips/MipsCondMov.td @@ -95,45 +95,65 @@ multiclass MovnPats<RegisterClass CRC, RegisterClass DRC, Instruction MOVNInst, // Instantiation of instructions. def MOVZ_I_I : CondMovIntInt<CPURegs, CPURegs, 0x0a, "movz">; -let Predicates = [HasMips64] in { +let Predicates = [HasMips64],DecoderNamespace = "Mips64" in { def MOVZ_I_I64 : CondMovIntInt<CPURegs, CPU64Regs, 0x0a, "movz">; - def MOVZ_I64_I : CondMovIntInt<CPU64Regs, CPURegs, 0x0a, "movz">; - def MOVZ_I64_I64 : CondMovIntInt<CPU64Regs, CPU64Regs, 0x0a, "movz">; + def MOVZ_I64_I : CondMovIntInt<CPU64Regs, CPURegs, 0x0a, "movz"> { + let isCodeGenOnly = 1; + } + def MOVZ_I64_I64 : CondMovIntInt<CPU64Regs, CPU64Regs, 0x0a, "movz"> { + let isCodeGenOnly = 1; + } } def MOVN_I_I : CondMovIntInt<CPURegs, CPURegs, 0x0b, "movn">; -let Predicates = [HasMips64] in { +let Predicates = [HasMips64],DecoderNamespace = "Mips64" in { def MOVN_I_I64 : CondMovIntInt<CPURegs, CPU64Regs, 0x0b, "movn">; - def MOVN_I64_I : CondMovIntInt<CPU64Regs, CPURegs, 0x0b, "movn">; - def MOVN_I64_I64 : CondMovIntInt<CPU64Regs, CPU64Regs, 0x0b, "movn">; + def MOVN_I64_I : CondMovIntInt<CPU64Regs, CPURegs, 0x0b, "movn"> { + let isCodeGenOnly = 1; + } + def MOVN_I64_I64 : CondMovIntInt<CPU64Regs, CPU64Regs, 0x0b, "movn"> { + let isCodeGenOnly = 1; + } } def MOVZ_I_S : CondMovIntFP<CPURegs, FGR32, 16, 18, "movz.s">; def MOVZ_I64_S : CondMovIntFP<CPU64Regs, FGR32, 16, 18, "movz.s">, - Requires<[HasMips64]>; + Requires<[HasMips64]> { + let DecoderNamespace = "Mips64"; +} def MOVN_I_S : CondMovIntFP<CPURegs, FGR32, 16, 19, "movn.s">; def MOVN_I64_S : CondMovIntFP<CPU64Regs, FGR32, 16, 19, "movn.s">, - Requires<[HasMips64]>; + Requires<[HasMips64]> { + let DecoderNamespace = "Mips64"; +} let Predicates = [NotFP64bit] in { def MOVZ_I_D32 : CondMovIntFP<CPURegs, AFGR64, 17, 18, "movz.d">; def MOVN_I_D32 : CondMovIntFP<CPURegs, AFGR64, 17, 19, "movn.d">; } -let Predicates = [IsFP64bit] in { +let Predicates = [IsFP64bit],DecoderNamespace = "Mips64" in { def MOVZ_I_D64 : CondMovIntFP<CPURegs, FGR64, 17, 18, "movz.d">; - def MOVZ_I64_D64 : CondMovIntFP<CPU64Regs, FGR64, 17, 18, "movz.d">; + def MOVZ_I64_D64 : CondMovIntFP<CPU64Regs, FGR64, 17, 18, "movz.d"> { + let isCodeGenOnly = 1; + } def MOVN_I_D64 : CondMovIntFP<CPURegs, FGR64, 17, 19, "movn.d">; - def MOVN_I64_D64 : CondMovIntFP<CPU64Regs, FGR64, 17, 19, "movn.d">; + def MOVN_I64_D64 : CondMovIntFP<CPU64Regs, FGR64, 17, 19, "movn.d"> { + let isCodeGenOnly = 1; + } } def MOVT_I : CondMovFPInt<CPURegs, MipsCMovFP_T, 1, "movt">; def MOVT_I64 : CondMovFPInt<CPU64Regs, MipsCMovFP_T, 1, "movt">, - Requires<[HasMips64]>; + Requires<[HasMips64]> { + let DecoderNamespace = "Mips64"; +} def MOVF_I : CondMovFPInt<CPURegs, MipsCMovFP_F, 0, "movf">; def MOVF_I64 : CondMovFPInt<CPU64Regs, MipsCMovFP_F, 0, "movf">, - Requires<[HasMips64]>; + Requires<[HasMips64]> { + let DecoderNamespace = "Mips64"; +} def MOVT_S : CondMovFPFP<FGR32, MipsCMovFP_T, 16, 1, "movt.s">; def MOVF_S : CondMovFPFP<FGR32, MipsCMovFP_F, 16, 0, "movf.s">; @@ -142,7 +162,7 @@ let Predicates = [NotFP64bit] in { def MOVT_D32 : CondMovFPFP<AFGR64, MipsCMovFP_T, 17, 1, "movt.d">; def MOVF_D32 : CondMovFPFP<AFGR64, MipsCMovFP_F, 17, 0, "movf.d">; } -let Predicates = [IsFP64bit] in { +let Predicates = [IsFP64bit], DecoderNamespace = "Mips64" in { def MOVT_D64 : CondMovFPFP<FGR64, MipsCMovFP_T, 17, 1, "movt.d">; def MOVF_D64 : CondMovFPFP<FGR64, MipsCMovFP_F, 17, 0, "movf.d">; } diff --git a/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp b/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp index 6a23bc3..ace47ab 100644 --- a/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -34,6 +34,8 @@ #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + using namespace llvm; // If I is a shifted mask, set the size (Size) and the first bit of the diff --git a/contrib/llvm/lib/Target/Mips/MipsInstrFPU.td b/contrib/llvm/lib/Target/Mips/MipsInstrFPU.td index b655945..14d8f1e 100644 --- a/contrib/llvm/lib/Target/Mips/MipsInstrFPU.td +++ b/contrib/llvm/lib/Target/Mips/MipsInstrFPU.td @@ -47,17 +47,17 @@ def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64", SDT_MipsExtractElementF64>; // Operand for printing out a condition code. -let PrintMethod = "printFCCOperand" in +let PrintMethod = "printFCCOperand", DecoderMethod = "DecodeCondCode" in def condcode : Operand<i32>; //===----------------------------------------------------------------------===// // Feature predicates. //===----------------------------------------------------------------------===// -def IsFP64bit : Predicate<"Subtarget.isFP64bit()">; -def NotFP64bit : Predicate<"!Subtarget.isFP64bit()">; -def IsSingleFloat : Predicate<"Subtarget.isSingleFloat()">; -def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">; +def IsFP64bit : Predicate<"Subtarget.isFP64bit()">, AssemblerPredicate<"FeatureFP64Bit">; +def NotFP64bit : Predicate<"!Subtarget.isFP64bit()">, AssemblerPredicate<"!FeatureFP64Bit">; +def IsSingleFloat : Predicate<"Subtarget.isSingleFloat()">, AssemblerPredicate<"FeatureSingleFloat">; +def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">, AssemblerPredicate<"!FeatureSingleFloat">; // FP immediate patterns. def fpimm0 : PatLeaf<(fpimm), [{ @@ -83,6 +83,7 @@ def fpimm0neg : PatLeaf<(fpimm), [{ //===----------------------------------------------------------------------===// // FP load. +let DecoderMethod = "DecodeFMem" in { class FPLoad<bits<6> op, string opstr, RegisterClass RC, Operand MemOpnd>: FMem<op, (outs RC:$ft), (ins MemOpnd:$addr), !strconcat(opstr, "\t$ft, $addr"), [(set RC:$ft, (load_a addr:$addr))], @@ -93,7 +94,7 @@ class FPStore<bits<6> op, string opstr, RegisterClass RC, Operand MemOpnd>: FMem<op, (outs), (ins RC:$ft, MemOpnd:$addr), !strconcat(opstr, "\t$ft, $addr"), [(store_a RC:$ft, addr:$addr)], IIStore>; - +} // FP indexed load. class FPIdxLoad<bits<6> funct, string opstr, RegisterClass DRC, RegisterClass PRC, PatFrag FOp>: @@ -118,11 +119,13 @@ multiclass FFR1_W_M<bits<6> funct, string opstr> { def _D32 : FFR1<funct, 17, opstr, "w.d", FGR32, AFGR64>, Requires<[NotFP64bit]>; def _D64 : FFR1<funct, 17, opstr, "w.d", FGR32, FGR64>, - Requires<[IsFP64bit]>; + Requires<[IsFP64bit]> { + let DecoderNamespace = "Mips64"; + } } // Instructions that convert an FP value to 64-bit fixed point. -let Predicates = [IsFP64bit] in +let Predicates = [IsFP64bit], DecoderNamespace = "Mips64" in multiclass FFR1_L_M<bits<6> funct, string opstr> { def _S : FFR1<funct, 16, opstr, "l.s", FGR64, FGR32>; def _D64 : FFR1<funct, 17, opstr, "l.d", FGR64, FGR64>; @@ -134,7 +137,9 @@ multiclass FFR1P_M<bits<6> funct, string opstr, SDNode OpNode> { def _D32 : FFR1P<funct, 17, opstr, "d", AFGR64, AFGR64, OpNode>, Requires<[NotFP64bit]>; def _D64 : FFR1P<funct, 17, opstr, "d", FGR64, FGR64, OpNode>, - Requires<[IsFP64bit]>; + Requires<[IsFP64bit]> { + let DecoderNamespace = "Mips64"; + } } multiclass FFR2P_M<bits<6> funct, string opstr, SDNode OpNode, bit isComm = 0> { @@ -143,9 +148,11 @@ multiclass FFR2P_M<bits<6> funct, string opstr, SDNode OpNode, bit isComm = 0> { def _D32 : FFR2P<funct, 17, opstr, "d", AFGR64, OpNode>, Requires<[NotFP64bit]>; def _D64 : FFR2P<funct, 17, opstr, "d", FGR64, OpNode>, - Requires<[IsFP64bit]>; + Requires<[IsFP64bit]> { + let DecoderNamespace = "Mips64"; } } +} // FP madd/msub/nmadd/nmsub instruction classes. class FMADDSUB<bits<3> funct, bits<3> fmt, string opstr, string fmtstr, @@ -172,9 +179,11 @@ defm CEIL_L : FFR1_L_M<0xa, "ceil">; defm FLOOR_W : FFR1_W_M<0xf, "floor">; defm FLOOR_L : FFR1_L_M<0xb, "floor">; defm CVT_W : FFR1_W_M<0x24, "cvt">; -defm CVT_L : FFR1_L_M<0x25, "cvt">; +//defm CVT_L : FFR1_L_M<0x25, "cvt">; def CVT_S_W : FFR1<0x20, 20, "cvt", "s.w", FGR32, FGR32>; +def CVT_L_S : FFR1<0x25, 16, "cvt", "l.s", FGR64, FGR32>; +def CVT_L_D64: FFR1<0x25, 17, "cvt", "l.d", FGR64, FGR64>; let Predicates = [NotFP64bit] in { def CVT_S_D32 : FFR1<0x20, 17, "cvt", "s.d", FGR32, AFGR64>; @@ -182,7 +191,7 @@ let Predicates = [NotFP64bit] in { def CVT_D32_S : FFR1<0x21, 16, "cvt", "d.s", AFGR64, FGR32>; } -let Predicates = [IsFP64bit] in { +let Predicates = [IsFP64bit], DecoderNamespace = "Mips64" in { def CVT_S_D64 : FFR1<0x20, 17, "cvt", "s.d", FGR32, FGR64>; def CVT_S_L : FFR1<0x20, 21, "cvt", "s.l", FGR32, FGR64>; def CVT_D64_W : FFR1<0x21, 20, "cvt", "d.w", FGR64, FGR32>; @@ -235,14 +244,20 @@ def FMOV_S : FFR1<0x6, 16, "mov", "s", FGR32, FGR32>; def FMOV_D32 : FFR1<0x6, 17, "mov", "d", AFGR64, AFGR64>, Requires<[NotFP64bit]>; def FMOV_D64 : FFR1<0x6, 17, "mov", "d", FGR64, FGR64>, - Requires<[IsFP64bit]>; + Requires<[IsFP64bit]> { + let DecoderNamespace = "Mips64"; +} /// Floating Point Memory Instructions -let Predicates = [IsN64] in { +let Predicates = [IsN64], DecoderNamespace = "Mips64" in { def LWC1_P8 : FPLoad<0x31, "lwc1", FGR32, mem64>; def SWC1_P8 : FPStore<0x39, "swc1", FGR32, mem64>; - def LDC164_P8 : FPLoad<0x35, "ldc1", FGR64, mem64>; - def SDC164_P8 : FPStore<0x3d, "sdc1", FGR64, mem64>; + def LDC164_P8 : FPLoad<0x35, "ldc1", FGR64, mem64> { + let isCodeGenOnly =1; + } + def SDC164_P8 : FPStore<0x3d, "sdc1", FGR64, mem64> { + let isCodeGenOnly =1; + } } let Predicates = [NotN64] in { @@ -250,7 +265,7 @@ let Predicates = [NotN64] in { def SWC1 : FPStore<0x39, "swc1", FGR32, mem>; } -let Predicates = [NotN64, HasMips64] in { +let Predicates = [NotN64, HasMips64], DecoderNamespace = "Mips64" in { def LDC164 : FPLoad<0x35, "ldc1", FGR64, mem>; def SDC164 : FPStore<0x3d, "sdc1", FGR64, mem>; } @@ -273,13 +288,13 @@ let Predicates = [HasMips32r2, NotMips64] in { def SDXC1 : FPIdxStore<0x9, "sdxc1", AFGR64, CPURegs, store_a>; } -let Predicates = [HasMips64, NotN64] in { +let Predicates = [HasMips64, NotN64], DecoderNamespace="Mips64" in { def LDXC164 : FPIdxLoad<0x1, "ldxc1", FGR64, CPURegs, load_a>; def SDXC164 : FPIdxStore<0x9, "sdxc1", FGR64, CPURegs, store_a>; } // n64 -let Predicates = [IsN64] in { +let Predicates = [IsN64], isCodeGenOnly=1 in { def LWXC1_P8 : FPIdxLoad<0x0, "lwxc1", FGR32, CPU64Regs, load_a>; def LUXC1_P8 : FPIdxLoad<0x5, "luxc1", FGR32, CPU64Regs, load_u>; def LDXC164_P8 : FPIdxLoad<0x1, "ldxc1", FGR64, CPU64Regs, load_a>; @@ -314,12 +329,12 @@ let Predicates = [HasMips32r2, NotFP64bit, NoNaNsFPMath] in { def NMSUB_D32 : FNMADDSUB<0x7, 1, "nmsub", "d", fsub, AFGR64>; } -let Predicates = [HasMips32r2, IsFP64bit] in { +let Predicates = [HasMips32r2, IsFP64bit], isCodeGenOnly=1 in { def MADD_D64 : FMADDSUB<0x4, 1, "madd", "d", fadd, FGR64>; def MSUB_D64 : FMADDSUB<0x5, 1, "msub", "d", fsub, FGR64>; } -let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath] in { +let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath], isCodeGenOnly=1 in { def NMADD_D64 : FNMADDSUB<0x6, 1, "nmadd", "d", fadd, FGR64>; def NMSUB_D64 : FNMADDSUB<0x7, 1, "nmsub", "d", fsub, FGR64>; } @@ -342,9 +357,10 @@ let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in let Inst{16} = tf; } +let DecoderMethod = "DecodeBC1" in { def BC1F : FBRANCH<0, 0, MIPS_BRANCH_F, "bc1f">; def BC1T : FBRANCH<0, 1, MIPS_BRANCH_T, "bc1t">; - +} //===----------------------------------------------------------------------===// // Floating Point Flag Conditions //===----------------------------------------------------------------------===// @@ -376,7 +392,9 @@ class FCMP<bits<5> fmt, RegisterClass RC, string typestr> : let Defs=[FCR31] in { def FCMP_S32 : FCMP<0x10, FGR32, "s">; def FCMP_D32 : FCMP<0x11, AFGR64, "d">, Requires<[NotFP64bit]>; - def FCMP_D64 : FCMP<0x11, FGR64, "d">, Requires<[IsFP64bit]>; + def FCMP_D64 : FCMP<0x11, FGR64, "d">, Requires<[IsFP64bit]> { + let DecoderNamespace = "Mips64"; + } } //===----------------------------------------------------------------------===// @@ -438,13 +456,13 @@ let Predicates = [IsFP64bit] in { // Patterns for unaligned floating point loads and stores. let Predicates = [HasMips32r2Or64, NotN64] in { - def : Pat<(f32 (load_u CPURegs:$addr)), (LUXC1 CPURegs:$addr, ZERO)>; + def : Pat<(f32 (load_u CPURegs:$addr)), (LUXC1 CPURegs:$addr, ZERO)>; def : Pat<(store_u FGR32:$src, CPURegs:$addr), (SUXC1 FGR32:$src, CPURegs:$addr, ZERO)>; } let Predicates = [IsN64] in { - def : Pat<(f32 (load_u CPU64Regs:$addr)), (LUXC1_P8 CPU64Regs:$addr, ZERO_64)>; + def : Pat<(f32 (load_u CPU64Regs:$addr)), (LUXC1_P8 CPU64Regs:$addr, ZERO_64)>; def : Pat<(store_u FGR32:$src, CPU64Regs:$addr), (SUXC1_P8 FGR32:$src, CPU64Regs:$addr, ZERO_64)>; } diff --git a/contrib/llvm/lib/Target/Mips/MipsInstrFormats.td b/contrib/llvm/lib/Target/Mips/MipsInstrFormats.td index 4555303..841eba0 100644 --- a/contrib/llvm/lib/Target/Mips/MipsInstrFormats.td +++ b/contrib/llvm/lib/Target/Mips/MipsInstrFormats.td @@ -45,6 +45,8 @@ class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern, let Namespace = "Mips"; + let Size = 4; + bits<6> Opcode = 0; // Top 6 bits are the 'opcode' field @@ -64,6 +66,10 @@ class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern, // TSFlags layout should be kept in sync with MipsInstrInfo.h. let TSFlags{3-0} = FormBits; + + let DecoderNamespace = "Mips"; + + field bits<32> SoftFail = 0; } // Mips Pseudo Instructions Format diff --git a/contrib/llvm/lib/Target/Mips/MipsInstrInfo.td b/contrib/llvm/lib/Target/Mips/MipsInstrInfo.td index be74f8e..873d2bd 100644 --- a/contrib/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/contrib/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -121,21 +121,36 @@ def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>; //===----------------------------------------------------------------------===// // Mips Instruction Predicate Definitions. //===----------------------------------------------------------------------===// -def HasSEInReg : Predicate<"Subtarget.hasSEInReg()">; -def HasBitCount : Predicate<"Subtarget.hasBitCount()">; -def HasSwap : Predicate<"Subtarget.hasSwap()">; -def HasCondMov : Predicate<"Subtarget.hasCondMov()">; -def HasMips32 : Predicate<"Subtarget.hasMips32()">; -def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">; -def HasMips64 : Predicate<"Subtarget.hasMips64()">; -def HasMips32r2Or64 : Predicate<"Subtarget.hasMips32r2Or64()">; -def NotMips64 : Predicate<"!Subtarget.hasMips64()">; -def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">; -def IsN64 : Predicate<"Subtarget.isABI_N64()">; -def NotN64 : Predicate<"!Subtarget.isABI_N64()">; -def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">; -def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">; -def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">; +def HasSEInReg : Predicate<"Subtarget.hasSEInReg()">, + AssemblerPredicate<"FeatureSEInReg">; +def HasBitCount : Predicate<"Subtarget.hasBitCount()">, + AssemblerPredicate<"FeatureBitCount">; +def HasSwap : Predicate<"Subtarget.hasSwap()">, + AssemblerPredicate<"FeatureSwap">; +def HasCondMov : Predicate<"Subtarget.hasCondMov()">, + AssemblerPredicate<"FeatureCondMov">; +def HasMips32 : Predicate<"Subtarget.hasMips32()">, + AssemblerPredicate<"FeatureMips32">; +def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">, + AssemblerPredicate<"FeatureMips32r2">; +def HasMips64 : Predicate<"Subtarget.hasMips64()">, + AssemblerPredicate<"FeatureMips64">; +def HasMips32r2Or64 : Predicate<"Subtarget.hasMips32r2Or64()">, + AssemblerPredicate<"FeatureMips32r2,FeatureMips64">; +def NotMips64 : Predicate<"!Subtarget.hasMips64()">, + AssemblerPredicate<"!FeatureMips64">; +def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">, + AssemblerPredicate<"FeatureMips64r2">; +def IsN64 : Predicate<"Subtarget.isABI_N64()">, + AssemblerPredicate<"FeatureN64">; +def NotN64 : Predicate<"!Subtarget.isABI_N64()">, + AssemblerPredicate<"!FeatureN64">; +def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">, + AssemblerPredicate<"FeatureMips32">; +def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">, + AssemblerPredicate<"FeatureMips32">; +def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">, + AssemblerPredicate<"FeatureMips32">; //===----------------------------------------------------------------------===// // Mips Operand, Complex Patterns and Transformations Definitions. @@ -148,12 +163,15 @@ def jmptarget : Operand<OtherVT> { def brtarget : Operand<OtherVT> { let EncoderMethod = "getBranchTargetOpValue"; let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTarget"; } def calltarget : Operand<iPTR> { let EncoderMethod = "getJumpTargetOpValue"; } def calltarget64: Operand<i64>; -def simm16 : Operand<i32>; +def simm16 : Operand<i32> { + let DecoderMethod= "DecodeSimm16"; +} def simm16_64 : Operand<i64>; def shamt : Operand<i32>; @@ -189,11 +207,13 @@ def mem_ea_64 : Operand<i64> { // size operand of ext instruction def size_ext : Operand<i32> { let EncoderMethod = "getSizeExtEncoding"; + let DecoderMethod = "DecodeExtSize"; } // size operand of ins instruction def size_ins : Operand<i32> { let EncoderMethod = "getSizeInsEncoding"; + let DecoderMethod = "DecodeInsSize"; } // Transformation Function - get the lower 16 bits. @@ -295,6 +315,7 @@ class ArithLogicR<bits<6> op, bits<6> func, string instr_asm, SDNode OpNode, [(set RC:$rd, (OpNode RC:$rs, RC:$rt))], itin> { let shamt = 0; let isCommutable = isComm; + let isReMaterializable = 1; } class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm, @@ -310,7 +331,9 @@ class ArithLogicI<bits<6> op, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type, RegisterClass RC> : FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16), !strconcat(instr_asm, "\t$rt, $rs, $imm16"), - [(set RC:$rt, (OpNode RC:$rs, imm_type:$imm16))], IIAlu>; + [(set RC:$rt, (OpNode RC:$rs, imm_type:$imm16))], IIAlu> { + let isReMaterializable = 1; +} class ArithOverflowI<bits<6> op, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type, RegisterClass RC> : @@ -366,6 +389,7 @@ class LoadUpper<bits<6> op, string instr_asm, RegisterClass RC, Operand Imm>: !strconcat(instr_asm, "\t$rt, $imm16"), [], IIAlu> { let rs = 0; let neverHasSideEffects = 1; + let isReMaterializable = 1; } class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, @@ -373,6 +397,7 @@ class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, bits<21> addr; let Inst{25-21} = addr{20-16}; let Inst{15-0} = addr{15-0}; + let DecoderMethod = "DecodeMem"; } // Memory Load/Store @@ -407,7 +432,10 @@ multiclass LoadM32<bits<6> op, string instr_asm, PatFrag OpNode, def #NAME# : LoadM<op, instr_asm, OpNode, CPURegs, mem, Pseudo>, Requires<[NotN64]>; def _P8 : LoadM<op, instr_asm, OpNode, CPURegs, mem64, Pseudo>, - Requires<[IsN64]>; + Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; + let isCodeGenOnly = 1; + } } // 64-bit load. @@ -416,7 +444,10 @@ multiclass LoadM64<bits<6> op, string instr_asm, PatFrag OpNode, def #NAME# : LoadM<op, instr_asm, OpNode, CPU64Regs, mem, Pseudo>, Requires<[NotN64]>; def _P8 : LoadM<op, instr_asm, OpNode, CPU64Regs, mem64, Pseudo>, - Requires<[IsN64]>; + Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; + let isCodeGenOnly = 1; + } } // 32-bit load. @@ -424,7 +455,10 @@ multiclass LoadUnAlign32<bits<6> op> { def #NAME# : LoadUnAlign<op, CPURegs, mem>, Requires<[NotN64]>; def _P8 : LoadUnAlign<op, CPURegs, mem64>, - Requires<[IsN64]>; + Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; + let isCodeGenOnly = 1; + } } // 32-bit store. multiclass StoreM32<bits<6> op, string instr_asm, PatFrag OpNode, @@ -432,7 +466,10 @@ multiclass StoreM32<bits<6> op, string instr_asm, PatFrag OpNode, def #NAME# : StoreM<op, instr_asm, OpNode, CPURegs, mem, Pseudo>, Requires<[NotN64]>; def _P8 : StoreM<op, instr_asm, OpNode, CPURegs, mem64, Pseudo>, - Requires<[IsN64]>; + Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; + let isCodeGenOnly = 1; + } } // 64-bit store. @@ -441,7 +478,10 @@ multiclass StoreM64<bits<6> op, string instr_asm, PatFrag OpNode, def #NAME# : StoreM<op, instr_asm, OpNode, CPU64Regs, mem, Pseudo>, Requires<[NotN64]>; def _P8 : StoreM<op, instr_asm, OpNode, CPU64Regs, mem64, Pseudo>, - Requires<[IsN64]>; + Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; + let isCodeGenOnly = 1; + } } // 32-bit store. @@ -449,7 +489,10 @@ multiclass StoreUnAlign32<bits<6> op> { def #NAME# : StoreUnAlign<op, CPURegs, mem>, Requires<[NotN64]>; def _P8 : StoreUnAlign<op, CPURegs, mem64>, - Requires<[IsN64]>; + Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; + let isCodeGenOnly = 1; + } } // Conditional Branch @@ -499,6 +542,7 @@ class JumpFJ<bits<6> op, string instr_asm>: let isBarrier=1; let hasDelaySlot = 1; let Predicates = [RelocStatic]; + let DecoderMethod = "DecodeJumpTarget"; } // Unconditional branch @@ -529,7 +573,9 @@ let isCall=1, hasDelaySlot=1 in { class JumpLink<bits<6> op, string instr_asm>: FJ<op, (outs), (ins calltarget:$target, variable_ops), !strconcat(instr_asm, "\t$target"), [(MipsJmpLink imm:$target)], - IIBranch>; + IIBranch> { + let DecoderMethod = "DecodeJumpTarget"; + } class JumpLinkReg<bits<6> op, bits<6> func, string instr_asm, RegisterClass RC>: @@ -685,7 +731,9 @@ class Atomic2Ops<PatFrag Op, string Opstr, RegisterClass DRC, multiclass Atomic2Ops32<PatFrag Op, string Opstr> { def #NAME# : Atomic2Ops<Op, Opstr, CPURegs, CPURegs>, Requires<[NotN64]>; - def _P8 : Atomic2Ops<Op, Opstr, CPURegs, CPU64Regs>, Requires<[IsN64]>; + def _P8 : Atomic2Ops<Op, Opstr, CPURegs, CPU64Regs>, Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; + } } // Atomic Compare & Swap. @@ -697,7 +745,9 @@ class AtomicCmpSwap<PatFrag Op, string Width, RegisterClass DRC, multiclass AtomicCmpSwap32<PatFrag Op, string Width> { def #NAME# : AtomicCmpSwap<Op, Width, CPURegs, CPURegs>, Requires<[NotN64]>; - def _P8 : AtomicCmpSwap<Op, Width, CPURegs, CPU64Regs>, Requires<[IsN64]>; + def _P8 : AtomicCmpSwap<Op, Width, CPURegs, CPU64Regs>, Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; + } } class LLBase<bits<6> Opc, string opstring, RegisterClass RC, Operand Mem> : @@ -868,9 +918,14 @@ def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype", /// Load-linked, Store-conditional def LL : LLBase<0x30, "ll", CPURegs, mem>, Requires<[NotN64]>; -def LL_P8 : LLBase<0x30, "ll", CPURegs, mem64>, Requires<[IsN64]>; +def LL_P8 : LLBase<0x30, "ll", CPURegs, mem64>, Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; +} + def SC : SCBase<0x38, "sc", CPURegs, mem>, Requires<[NotN64]>; -def SC_P8 : SCBase<0x38, "sc", CPURegs, mem64>, Requires<[IsN64]>; +def SC_P8 : SCBase<0x38, "sc", CPURegs, mem64>, Requires<[IsN64]> { + let DecoderNamespace = "Mips64"; +} /// Jump and Branch Instructions def J : JumpFJ<0x02, "j">; @@ -888,7 +943,7 @@ def JALR : JumpLinkReg<0x00, 0x09, "jalr", CPURegs>; def BGEZAL : BranchLink<"bgezal", 0x11, CPURegs>; def BLTZAL : BranchLink<"bltzal", 0x10, CPURegs>; -let isReturn=1, isTerminator=1, hasDelaySlot=1, +let isReturn=1, isTerminator=1, hasDelaySlot=1, isCodeGenOnly=1, isBarrier=1, hasCtrlDep=1, rd=0, rt=0, shamt=0 in def RET : FR <0x00, 0x08, (outs), (ins CPURegs:$target), "jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>; @@ -923,13 +978,17 @@ let addr=0 in // instructions. The same not happens for stack address copies, so an // add op with mem ComplexPattern is used and the stack address copy // can be matched. It's similar to Sparc LEA_ADDRi -def LEA_ADDiu : EffectiveAddress<"addiu\t$rt, $addr", CPURegs, mem_ea>; +def LEA_ADDiu : EffectiveAddress<"addiu\t$rt, $addr", CPURegs, mem_ea> { + let isCodeGenOnly = 1; +} // DynAlloc node points to dynamically allocated stack space. // $sp is added to the list of implicitly used registers to prevent dead code // elimination from removing instructions that modify $sp. let Uses = [SP] in -def DynAlloc : EffectiveAddress<"addiu\t$rt, $addr", CPURegs, mem_ea>; +def DynAlloc : EffectiveAddress<"addiu\t$rt, $addr", CPURegs, mem_ea> { + let isCodeGenOnly = 1; +} // MADD*/MSUB* def MADD : MArithR<0, "madd", MipsMAdd, 1>; diff --git a/contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp index ad02231..858723b 100644 --- a/contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp +++ b/contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp @@ -117,18 +117,16 @@ TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { // Install an instruction selector pass using // the ISelDag to gen Mips code. -bool MipsPassConfig::addInstSelector() -{ - PM.add(createMipsISelDag(getMipsTargetMachine())); +bool MipsPassConfig::addInstSelector() { + PM->add(createMipsISelDag(getMipsTargetMachine())); return false; } // Implemented by targets that want to run passes immediately before // machine code is emitted. return true if -print-machineinstrs should // print out the code after the passes. -bool MipsPassConfig::addPreEmitPass() -{ - PM.add(createMipsDelaySlotFillerPass(getMipsTargetMachine())); +bool MipsPassConfig::addPreEmitPass() { + PM->add(createMipsDelaySlotFillerPass(getMipsTargetMachine())); return true; } @@ -136,12 +134,12 @@ bool MipsPassConfig::addPreRegAlloc() { // Do not restore $gp if target is Mips64. // In N32/64, $gp is a callee-saved register. if (!getMipsSubtarget().hasMips64()) - PM.add(createMipsEmitGPRestorePass(getMipsTargetMachine())); + PM->add(createMipsEmitGPRestorePass(getMipsTargetMachine())); return true; } bool MipsPassConfig::addPreSched2() { - PM.add(createMipsExpandPseudoPass(getMipsTargetMachine())); + PM->add(createMipsExpandPseudoPass(getMipsTargetMachine())); return true; } diff --git a/contrib/llvm/lib/Target/PTX/PTXTargetMachine.cpp b/contrib/llvm/lib/Target/PTX/PTXTargetMachine.cpp index c55a658..97b8de1 100644 --- a/contrib/llvm/lib/Target/PTX/PTXTargetMachine.cpp +++ b/contrib/llvm/lib/Target/PTX/PTXTargetMachine.cpp @@ -130,7 +130,7 @@ TargetPassConfig *PTXTargetMachine::createPassConfig(PassManagerBase &PM) { } bool PTXPassConfig::addInstSelector() { - PM.add(createPTXISelDag(getPTXTargetMachine(), getOptLevel())); + PM->add(createPTXISelDag(getPTXTargetMachine(), getOptLevel())); return false; } @@ -145,7 +145,7 @@ void PTXPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) { bool PTXPassConfig::addPostRegAlloc() { // PTXMFInfoExtract must after register allocation! - //PM.add(createPTXMFInfoExtract(getPTXTargetMachine())); + //PM->add(createPTXMFInfoExtract(getPTXTargetMachine())); return false; } @@ -159,7 +159,7 @@ void PTXPassConfig::addMachineLateOptimization() { } bool PTXPassConfig::addPreEmitPass() { - PM.add(createPTXMFInfoExtract(getPTXTargetMachine(), getOptLevel())); - PM.add(createPTXFPRoundingModePass(getPTXTargetMachine(), getOptLevel())); + PM->add(createPTXMFInfoExtract(getPTXTargetMachine(), getOptLevel())); + PM->add(createPTXFPRoundingModePass(getPTXTargetMachine(), getOptLevel())); return true; } diff --git a/contrib/llvm/lib/Target/PowerPC/PPCCallingConv.td b/contrib/llvm/lib/Target/PowerPC/PPCCallingConv.td index 9883c2e..b2b5364 100644 --- a/contrib/llvm/lib/Target/PowerPC/PPCCallingConv.td +++ b/contrib/llvm/lib/Target/PowerPC/PPCCallingConv.td @@ -12,10 +12,6 @@ // //===----------------------------------------------------------------------===// -/// CCIfSubtarget - Match if the current subtarget has a feature F. -class CCIfSubtarget<string F, CCAction A> - : CCIf<!strconcat("State.getTarget().getSubtarget<PPCSubtarget>().", F), A>; - //===----------------------------------------------------------------------===// // Return Value Calling Convention //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp b/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp index d113976..50f3db8 100644 --- a/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -98,13 +98,13 @@ TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) { bool PPCPassConfig::addInstSelector() { // Install an instruction selector. - PM.add(createPPCISelDag(getPPCTargetMachine())); + PM->add(createPPCISelDag(getPPCTargetMachine())); return false; } bool PPCPassConfig::addPreEmitPass() { // Must run branch selection immediately preceding the asm printer. - PM.add(createPPCBranchSelectionPass()); + PM->add(createPPCBranchSelectionPass()); return false; } diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp index 6f31356..cc25307 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp @@ -59,7 +59,7 @@ TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM) { } bool SparcPassConfig::addInstSelector() { - PM.add(createSparcISelDag(getSparcTargetMachine())); + PM->add(createSparcISelDag(getSparcTargetMachine())); return false; } @@ -67,8 +67,8 @@ bool SparcPassConfig::addInstSelector() { /// passes immediately before machine code is emitted. This should return /// true if -print-machineinstrs should print out the code after the passes. bool SparcPassConfig::addPreEmitPass(){ - PM.add(createSparcFPMoverPass(getSparcTargetMachine())); - PM.add(createSparcDelaySlotFillerPass(getSparcTargetMachine())); + PM->add(createSparcFPMoverPass(getSparcTargetMachine())); + PM->add(createSparcDelaySlotFillerPass(getSparcTargetMachine())); return true; } diff --git a/contrib/llvm/lib/Target/TargetLibraryInfo.cpp b/contrib/llvm/lib/Target/TargetLibraryInfo.cpp index 269958f..ec95ad4 100644 --- a/contrib/llvm/lib/Target/TargetLibraryInfo.cpp +++ b/contrib/llvm/lib/Target/TargetLibraryInfo.cpp @@ -56,7 +56,7 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "exp2f", "expm1", "expm1l", - "expl1f", + "expm1f", "fabs", "fabsl", "fabsf", @@ -95,6 +95,9 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "rint", "rintf", "rintl", + "round", + "roundf", + "roundl", "sin", "sinl", "sinf", @@ -155,6 +158,81 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T) { TLI.setUnavailable(LibFunc::siprintf); TLI.setUnavailable(LibFunc::fiprintf); } + + if (T.getOS() == Triple::Win32) { + // Win32 does not support long double + TLI.setUnavailable(LibFunc::acosl); + TLI.setUnavailable(LibFunc::asinl); + TLI.setUnavailable(LibFunc::atanl); + TLI.setUnavailable(LibFunc::atan2l); + TLI.setUnavailable(LibFunc::ceill); + TLI.setUnavailable(LibFunc::copysignl); + TLI.setUnavailable(LibFunc::cosl); + TLI.setUnavailable(LibFunc::coshl); + TLI.setUnavailable(LibFunc::expl); + TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf + TLI.setUnavailable(LibFunc::fabsl); + TLI.setUnavailable(LibFunc::floorl); + TLI.setUnavailable(LibFunc::fmodl); + TLI.setUnavailable(LibFunc::logl); + TLI.setUnavailable(LibFunc::powl); + TLI.setUnavailable(LibFunc::sinl); + TLI.setUnavailable(LibFunc::sinhl); + TLI.setUnavailable(LibFunc::sqrtl); + TLI.setUnavailable(LibFunc::tanl); + TLI.setUnavailable(LibFunc::tanhl); + + // Win32 only has C89 math + TLI.setUnavailable(LibFunc::exp2); + TLI.setUnavailable(LibFunc::exp2f); + TLI.setUnavailable(LibFunc::exp2l); + TLI.setUnavailable(LibFunc::expm1); + TLI.setUnavailable(LibFunc::expm1f); + TLI.setUnavailable(LibFunc::expm1l); + TLI.setUnavailable(LibFunc::log2); + TLI.setUnavailable(LibFunc::log2f); + TLI.setUnavailable(LibFunc::log2l); + TLI.setUnavailable(LibFunc::log1p); + TLI.setUnavailable(LibFunc::log1pf); + TLI.setUnavailable(LibFunc::log1pl); + TLI.setUnavailable(LibFunc::nearbyint); + TLI.setUnavailable(LibFunc::nearbyintf); + TLI.setUnavailable(LibFunc::nearbyintl); + TLI.setUnavailable(LibFunc::rint); + TLI.setUnavailable(LibFunc::rintf); + TLI.setUnavailable(LibFunc::rintl); + TLI.setUnavailable(LibFunc::round); + TLI.setUnavailable(LibFunc::roundf); + TLI.setUnavailable(LibFunc::roundl); + TLI.setUnavailable(LibFunc::trunc); + TLI.setUnavailable(LibFunc::truncf); + TLI.setUnavailable(LibFunc::truncl); + + // Win32 provides some C99 math with mangled names + TLI.setAvailableWithName(LibFunc::copysign, "_copysign"); + + if (T.getArch() == Triple::x86) { + // Win32 on x86 implements single-precision math functions as macros + TLI.setUnavailable(LibFunc::acosf); + TLI.setUnavailable(LibFunc::asinf); + TLI.setUnavailable(LibFunc::atanf); + TLI.setUnavailable(LibFunc::atan2f); + TLI.setUnavailable(LibFunc::ceilf); + TLI.setUnavailable(LibFunc::copysignf); + TLI.setUnavailable(LibFunc::cosf); + TLI.setUnavailable(LibFunc::coshf); + TLI.setUnavailable(LibFunc::expf); + TLI.setUnavailable(LibFunc::floorf); + TLI.setUnavailable(LibFunc::fmodf); + TLI.setUnavailable(LibFunc::logf); + TLI.setUnavailable(LibFunc::powf); + TLI.setUnavailable(LibFunc::sinf); + TLI.setUnavailable(LibFunc::sinhf); + TLI.setUnavailable(LibFunc::sqrtf); + TLI.setUnavailable(LibFunc::tanf); + TLI.setUnavailable(LibFunc::tanhf); + } + } } diff --git a/contrib/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp b/contrib/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp index 32c722a..a802333 100644 --- a/contrib/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp +++ b/contrib/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp @@ -169,6 +169,9 @@ void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<int> &ShuffleMask) { void DecodeVPERM2X128Mask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) { + if (Imm & 0x88) + return; // Not a shuffle + unsigned HalfSize = VT.getVectorNumElements()/2; unsigned FstHalfBegin = (Imm & 0x3) * HalfSize; unsigned SndHalfBegin = ((Imm >> 4) & 0x3) * HalfSize; diff --git a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp index 9b83aad..04299f3 100644 --- a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2935,6 +2935,7 @@ static SDValue getTargetShuffleNode(unsigned Opc, DebugLoc dl, EVT VT, case X86ISD::PSHUFHW: case X86ISD::PSHUFLW: case X86ISD::VPERMILP: + case X86ISD::VPERMI: return DAG.getNode(Opc, dl, VT, V1, DAG.getConstant(TargetMask, MVT::i8)); } } @@ -3976,6 +3977,27 @@ unsigned X86::getInsertVINSERTF128Immediate(SDNode *N) { return Index / NumElemsPerChunk; } +/// getShuffleCLImmediate - Return the appropriate immediate to shuffle +/// the specified VECTOR_SHUFFLE mask with VPERMQ and VPERMPD instructions. +/// Handles 256-bit. +static unsigned getShuffleCLImmediate(ShuffleVectorSDNode *N) { + EVT VT = N->getValueType(0); + + unsigned NumElts = VT.getVectorNumElements(); + + assert((VT.is256BitVector() && NumElts == 4) && + "Unsupported vector type for VPERMQ/VPERMPD"); + + unsigned Mask = 0; + for (unsigned i = 0; i != NumElts; ++i) { + int Elt = N->getMaskElt(i); + if (Elt < 0) + continue; + Mask |= Elt << (i*2); + } + + return Mask; +} /// isZeroNode - Returns true if Elt is a constant zero or a floating point /// constant +0.0. bool X86::isZeroNode(SDValue Elt) { @@ -4408,6 +4430,7 @@ static bool getTargetShuffleMask(SDNode *N, EVT VT, case X86ISD::VPERM2X128: ImmN = N->getOperand(N->getNumOperands()-1); DecodeVPERM2X128Mask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask); + if (Mask.empty()) return false; break; case X86ISD::MOVDDUP: case X86ISD::MOVLHPD: @@ -6628,6 +6651,23 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const { if (BlendOp.getNode()) return BlendOp; + if (V2IsUndef && HasAVX2 && (VT == MVT::v8i32 || VT == MVT::v8f32)) { + SmallVector<SDValue, 8> permclMask; + for (unsigned i = 0; i != 8; ++i) { + permclMask.push_back(DAG.getConstant((M[i]>=0) ? M[i] : 0, MVT::i32)); + } + SDValue Mask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v8i32, + &permclMask[0], 8); + // Bitcast is for VPERMPS since mask is v8i32 but node takes v8f32 + return DAG.getNode(X86ISD::VPERMV, dl, VT, + DAG.getNode(ISD::BITCAST, dl, VT, Mask), V1); + } + + if (V2IsUndef && HasAVX2 && (VT == MVT::v4i64 || VT == MVT::v4f64)) + return getTargetShuffleNode(X86ISD::VPERMI, dl, VT, V1, + getShuffleCLImmediate(SVOp), DAG); + + //===--------------------------------------------------------------------===// // Since no target specific shuffle was selected for this generic one, // lower it into other known shuffles. FIXME: this isn't true yet, but @@ -9552,12 +9592,12 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const case Intrinsic::x86_avx2_vperm2i128: return DAG.getNode(X86ISD::VPERM2X128, dl, Op.getValueType(), Op.getOperand(1), Op.getOperand(2), Op.getOperand(3)); - case Intrinsic::x86_avx_vpermil_ps: - case Intrinsic::x86_avx_vpermil_pd: - case Intrinsic::x86_avx_vpermil_ps_256: - case Intrinsic::x86_avx_vpermil_pd_256: - return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), - Op.getOperand(1), Op.getOperand(2)); + case Intrinsic::x86_avx2_permd: + case Intrinsic::x86_avx2_permps: + // Operands intentionally swapped. Mask is last operand to intrinsic, + // but second operand for node/intruction. + return DAG.getNode(X86ISD::VPERMV, dl, Op.getValueType(), + Op.getOperand(2), Op.getOperand(1)); // ptest and testp intrinsics. The intrinsic these come from are designed to // return an integer value, not just an instruction so lower it to the ptest @@ -11141,6 +11181,8 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::VBROADCAST: return "X86ISD::VBROADCAST"; case X86ISD::VPERMILP: return "X86ISD::VPERMILP"; case X86ISD::VPERM2X128: return "X86ISD::VPERM2X128"; + case X86ISD::VPERMV: return "X86ISD::VPERMV"; + case X86ISD::VPERMI: return "X86ISD::VPERMI"; case X86ISD::PMULUDQ: return "X86ISD::PMULUDQ"; case X86ISD::VASTART_SAVE_XMM_REGS: return "X86ISD::VASTART_SAVE_XMM_REGS"; case X86ISD::VAARG_64: return "X86ISD::VAARG_64"; @@ -11298,14 +11340,15 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr, unsigned notOpc, unsigned EAXreg, const TargetRegisterClass *RC, - bool invSrc) const { + bool Invert) const { // For the atomic bitwise operator, we generate // thisMBB: // newMBB: // ld t1 = [bitinstr.addr] // op t2 = t1, [bitinstr.val] + // not t3 = t2 (if Invert) // mov EAX = t1 - // lcs dest = [bitinstr.addr], t2 [EAX is implicit] + // lcs dest = [bitinstr.addr], t3 [EAX is implicit] // bz newMBB // fallthrough -->nextMBB const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); @@ -11353,13 +11396,6 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr, for (int i=0; i <= lastAddrIndx; ++i) (*MIB).addOperand(*argOpers[i]); - unsigned tt = F->getRegInfo().createVirtualRegister(RC); - if (invSrc) { - MIB = BuildMI(newMBB, dl, TII->get(notOpc), tt).addReg(t1); - } - else - tt = t1; - unsigned t2 = F->getRegInfo().createVirtualRegister(RC); assert((argOpers[valArgIndx]->isReg() || argOpers[valArgIndx]->isImm()) && @@ -11368,16 +11404,23 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr, MIB = BuildMI(newMBB, dl, TII->get(regOpc), t2); else MIB = BuildMI(newMBB, dl, TII->get(immOpc), t2); - MIB.addReg(tt); + MIB.addReg(t1); (*MIB).addOperand(*argOpers[valArgIndx]); + unsigned t3 = F->getRegInfo().createVirtualRegister(RC); + if (Invert) { + MIB = BuildMI(newMBB, dl, TII->get(notOpc), t3).addReg(t2); + } + else + t3 = t2; + MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), EAXreg); MIB.addReg(t1); MIB = BuildMI(newMBB, dl, TII->get(CXchgOpc)); for (int i=0; i <= lastAddrIndx; ++i) (*MIB).addOperand(*argOpers[i]); - MIB.addReg(t2); + MIB.addReg(t3); assert(bInstr->hasOneMemOperand() && "Unexpected number of memoperand"); (*MIB).setMemRefs(bInstr->memoperands_begin(), bInstr->memoperands_end()); @@ -11400,7 +11443,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr, unsigned regOpcH, unsigned immOpcL, unsigned immOpcH, - bool invSrc) const { + bool Invert) const { // For the atomic bitwise operator, we generate // thisMBB (instructions are in pairs, except cmpxchg8b) // ld t1,t2 = [bitinstr.addr] @@ -11408,6 +11451,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr, // out1, out2 = phi (thisMBB, t1/t2) (newMBB, t3/t4) // op t5, t6 <- out1, out2, [bitinstr.val] // (for SWAP, substitute: mov t5, t6 <- [bitinstr.val]) + // neg t7, t8 < t5, t6 (if Invert) // mov ECX, EBX <- t5, t6 // mov EAX, EDX <- t1, t2 // cmpxchg8b [bitinstr.addr] [EAX, EDX, EBX, ECX implicit] @@ -11491,16 +11535,9 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr, .addReg(t2).addMBB(thisMBB).addReg(t4).addMBB(newMBB); // The subsequent operations should be using the destination registers of - //the PHI instructions. - if (invSrc) { - t1 = F->getRegInfo().createVirtualRegister(RC); - t2 = F->getRegInfo().createVirtualRegister(RC); - MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t1).addReg(dest1Oper.getReg()); - MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t2).addReg(dest2Oper.getReg()); - } else { - t1 = dest1Oper.getReg(); - t2 = dest2Oper.getReg(); - } + // the PHI instructions. + t1 = dest1Oper.getReg(); + t2 = dest2Oper.getReg(); int valArgIndx = lastAddrIndx + 1; assert((argOpers[valArgIndx]->isReg() || @@ -11527,15 +11564,26 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr, MIB.addReg(t2); (*MIB).addOperand(*argOpers[valArgIndx + 1]); + unsigned t7, t8; + if (Invert) { + t7 = F->getRegInfo().createVirtualRegister(RC); + t8 = F->getRegInfo().createVirtualRegister(RC); + MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t7).addReg(t5); + MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t8).addReg(t6); + } else { + t7 = t5; + t8 = t6; + } + MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EAX); MIB.addReg(t1); MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EDX); MIB.addReg(t2); MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EBX); - MIB.addReg(t5); + MIB.addReg(t7); MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::ECX); - MIB.addReg(t6); + MIB.addReg(t8); MIB = BuildMI(newMBB, dl, TII->get(X86::LCMPXCHG8B)); for (int i=0; i <= lastAddrIndx; ++i) diff --git a/contrib/llvm/lib/Target/X86/X86ISelLowering.h b/contrib/llvm/lib/Target/X86/X86ISelLowering.h index 4e00733..09116e8 100644 --- a/contrib/llvm/lib/Target/X86/X86ISelLowering.h +++ b/contrib/llvm/lib/Target/X86/X86ISelLowering.h @@ -285,6 +285,8 @@ namespace llvm { UNPCKL, UNPCKH, VPERMILP, + VPERMV, + VPERMI, VPERM2X128, VBROADCAST, @@ -855,7 +857,7 @@ namespace llvm { unsigned notOpc, unsigned EAXreg, const TargetRegisterClass *RC, - bool invSrc = false) const; + bool Invert = false) const; MachineBasicBlock *EmitAtomicBit6432WithCustomInserter( MachineInstr *BInstr, @@ -864,7 +866,7 @@ namespace llvm { unsigned regOpcH, unsigned immOpcL, unsigned immOpcH, - bool invSrc = false) const; + bool Invert = false) const; /// Utility function to emit atomic min and max. It takes the min/max /// instruction to expand, the associated basic block, and the associated diff --git a/contrib/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td b/contrib/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td index 041a64f..35801e4 100644 --- a/contrib/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td +++ b/contrib/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td @@ -155,6 +155,8 @@ def X86Unpckl : SDNode<"X86ISD::UNPCKL", SDTShuff2Op>; def X86Unpckh : SDNode<"X86ISD::UNPCKH", SDTShuff2Op>; def X86VPermilp : SDNode<"X86ISD::VPERMILP", SDTShuff2OpI>; +def X86VPermv : SDNode<"X86ISD::VPERMV", SDTShuff2Op>; +def X86VPermi : SDNode<"X86ISD::VPERMI", SDTShuff2OpI>; def X86VPerm2x128 : SDNode<"X86ISD::VPERM2X128", SDTShuff3OpI>; diff --git a/contrib/llvm/lib/Target/X86/X86InstrInfo.cpp b/contrib/llvm/lib/Target/X86/X86InstrInfo.cpp index 307c96b..b12c1db 100644 --- a/contrib/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/contrib/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -1049,9 +1049,9 @@ X86InstrInfo::X86InstrInfo(X86TargetMachine &tm) { X86::VPCMPGTWYrr, X86::VPCMPGTWYrm, TB_ALIGN_32 }, { X86::VPERM2I128rr, X86::VPERM2I128rm, TB_ALIGN_32 }, { X86::VPERMDYrr, X86::VPERMDYrm, TB_ALIGN_32 }, - { X86::VPERMPDYrr, X86::VPERMPDYrm, TB_ALIGN_32 }, + { X86::VPERMPDYri, X86::VPERMPDYmi, TB_ALIGN_32 }, { X86::VPERMPSYrr, X86::VPERMPSYrm, TB_ALIGN_32 }, - { X86::VPERMQYrr, X86::VPERMQYrm, TB_ALIGN_32 }, + { X86::VPERMQYri, X86::VPERMQYmi, TB_ALIGN_32 }, { X86::VPHADDDYrr, X86::VPHADDDYrm, TB_ALIGN_32 }, { X86::VPHADDSWrr256, X86::VPHADDSWrm256, TB_ALIGN_32 }, { X86::VPHADDWYrr, X86::VPHADDWYrm, TB_ALIGN_32 }, diff --git a/contrib/llvm/lib/Target/X86/X86InstrSSE.td b/contrib/llvm/lib/Target/X86/X86InstrSSE.td index 408ab167..65e3c1e 100644 --- a/contrib/llvm/lib/Target/X86/X86InstrSSE.td +++ b/contrib/llvm/lib/Target/X86/X86InstrSSE.td @@ -6742,6 +6742,16 @@ let Predicates = [HasAVX] in { def : Pat<(v4f64 (X86Blendpd (v4f64 VR256:$src1), (v4f64 VR256:$src2), (imm:$mask))), (VBLENDPDYrri VR256:$src2, VR256:$src1, imm:$mask)>; + + def : Pat<(v8i16 (X86Blendpw (v8i16 VR128:$src1), (v8i16 VR128:$src2), + (imm:$mask))), + (VPBLENDWrri VR128:$src2, VR128:$src1, imm:$mask)>; + def : Pat<(v4f32 (X86Blendps (v4f32 VR128:$src1), (v4f32 VR128:$src2), + (imm:$mask))), + (VBLENDPSrri VR128:$src2, VR128:$src1, imm:$mask)>; + def : Pat<(v2f64 (X86Blendpd (v2f64 VR128:$src1), (v2f64 VR128:$src2), + (imm:$mask))), + (VBLENDPDrri VR128:$src2, VR128:$src1, imm:$mask)>; } let Predicates = [HasAVX2] in { @@ -6802,13 +6812,13 @@ let Predicates = [HasSSE41] in { def : Pat<(v8i16 (X86Blendpw (v8i16 VR128:$src1), (v8i16 VR128:$src2), (imm:$mask))), - (VPBLENDWrri VR128:$src2, VR128:$src1, imm:$mask)>; + (PBLENDWrri VR128:$src2, VR128:$src1, imm:$mask)>; def : Pat<(v4f32 (X86Blendps (v4f32 VR128:$src1), (v4f32 VR128:$src2), (imm:$mask))), - (VBLENDPSrri VR128:$src2, VR128:$src1, imm:$mask)>; + (BLENDPSrri VR128:$src2, VR128:$src1, imm:$mask)>; def : Pat<(v2f64 (X86Blendpd (v2f64 VR128:$src1), (v2f64 VR128:$src2), (imm:$mask))), - (VBLENDPDrri VR128:$src2, VR128:$src1, imm:$mask)>; + (BLENDPDrri VR128:$src2, VR128:$src1, imm:$mask)>; } @@ -7725,45 +7735,47 @@ def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))), // multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag, - Intrinsic Int> { + ValueType OpVT> { def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src1, VR256:$src2), !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), - [(set VR256:$dst, (Int VR256:$src1, VR256:$src2))]>, VEX_4V; + [(set VR256:$dst, + (OpVT (X86VPermv VR256:$src1, VR256:$src2)))]>, VEX_4V; def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2), !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), - [(set VR256:$dst, (Int VR256:$src1, - (bitconvert (mem_frag addr:$src2))))]>, + [(set VR256:$dst, + (OpVT (X86VPermv VR256:$src1, + (bitconvert (mem_frag addr:$src2)))))]>, VEX_4V; } -defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, int_x86_avx2_permd>; +defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, v8i32>; let ExeDomain = SSEPackedSingle in -defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, int_x86_avx2_permps>; +defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, v8f32>; multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag, - Intrinsic Int> { - def Yrr : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst), + ValueType OpVT> { + def Yri : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src1, i8imm:$src2), !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), - [(set VR256:$dst, (Int VR256:$src1, imm:$src2))]>, VEX; - def Yrm : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst), + [(set VR256:$dst, + (OpVT (X86VPermi VR256:$src1, (i8 imm:$src2))))]>, VEX; + def Ymi : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src1, i8imm:$src2), !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), - [(set VR256:$dst, (Int (mem_frag addr:$src1), imm:$src2))]>, - VEX; + [(set VR256:$dst, + (OpVT (X86VPermi (mem_frag addr:$src1), + (i8 imm:$src2))))]>, VEX; } -defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, int_x86_avx2_permq>, - VEX_W; +defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, v4i64>, VEX_W; let ExeDomain = SSEPackedDouble in -defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, int_x86_avx2_permpd>, - VEX_W; +defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, v4f64>, VEX_W; //===----------------------------------------------------------------------===// // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks diff --git a/contrib/llvm/lib/Target/X86/X86Subtarget.cpp b/contrib/llvm/lib/Target/X86/X86Subtarget.cpp index 452dd7e..ed1a409 100644 --- a/contrib/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/contrib/llvm/lib/Target/X86/X86Subtarget.cpp @@ -424,7 +424,9 @@ bool X86Subtarget::enablePostRAScheduler( CodeGenOpt::Level OptLevel, TargetSubtargetInfo::AntiDepBreakMode& Mode, RegClassVector& CriticalPathRCs) const { - Mode = TargetSubtargetInfo::ANTIDEP_CRITICAL; + //TODO: change back to ANTIDEP_CRITICAL when the + // X86 subtarget properly sets up post RA liveness. + Mode = TargetSubtargetInfo::ANTIDEP_NONE; CriticalPathRCs.clear(); return PostRAScheduler && OptLevel >= CodeGenOpt::Default; } diff --git a/contrib/llvm/lib/Target/X86/X86TargetMachine.cpp b/contrib/llvm/lib/Target/X86/X86TargetMachine.cpp index f4b7a62..89c3884 100644 --- a/contrib/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/contrib/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -145,34 +145,34 @@ TargetPassConfig *X86TargetMachine::createPassConfig(PassManagerBase &PM) { bool X86PassConfig::addInstSelector() { // Install an instruction selector. - PM.add(createX86ISelDag(getX86TargetMachine(), getOptLevel())); + PM->add(createX86ISelDag(getX86TargetMachine(), getOptLevel())); // For 32-bit, prepend instructions to set the "global base reg" for PIC. if (!getX86Subtarget().is64Bit()) - PM.add(createGlobalBaseRegPass()); + PM->add(createGlobalBaseRegPass()); return false; } bool X86PassConfig::addPreRegAlloc() { - PM.add(createX86MaxStackAlignmentHeuristicPass()); + PM->add(createX86MaxStackAlignmentHeuristicPass()); return false; // -print-machineinstr shouldn't print after this. } bool X86PassConfig::addPostRegAlloc() { - PM.add(createX86FloatingPointStackifierPass()); + PM->add(createX86FloatingPointStackifierPass()); return true; // -print-machineinstr should print after this. } bool X86PassConfig::addPreEmitPass() { bool ShouldPrint = false; if (getOptLevel() != CodeGenOpt::None && getX86Subtarget().hasSSE2()) { - PM.add(createExecutionDependencyFixPass(&X86::VR128RegClass)); + PM->add(createExecutionDependencyFixPass(&X86::VR128RegClass)); ShouldPrint = true; } if (getX86Subtarget().hasAVX() && UseVZeroUpper) { - PM.add(createX86IssueVZeroUpperPass()); + PM->add(createX86IssueVZeroUpperPass()); ShouldPrint = true; } diff --git a/contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp b/contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp index f65297e..5afd5a1 100644 --- a/contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp +++ b/contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp @@ -55,7 +55,7 @@ TargetPassConfig *XCoreTargetMachine::createPassConfig(PassManagerBase &PM) { } bool XCorePassConfig::addInstSelector() { - PM.add(createXCoreISelDag(getXCoreTargetMachine(), getOptLevel())); + PM->add(createXCoreISelDag(getXCoreTargetMachine(), getOptLevel())); return false; } diff --git a/contrib/llvm/lib/Transforms/IPO/Internalize.cpp b/contrib/llvm/lib/Transforms/IPO/Internalize.cpp index cd29e7a..fb5869e 100644 --- a/contrib/llvm/lib/Transforms/IPO/Internalize.cpp +++ b/contrib/llvm/lib/Transforms/IPO/Internalize.cpp @@ -123,6 +123,8 @@ bool InternalizePass::runOnModule(Module &M) { bool Changed = false; // Never internalize functions which code-gen might insert. + // FIXME: We should probably add this (and the __stack_chk_guard) via some + // type of call-back in CodeGen. ExternalNames.insert("__stack_chk_fail"); // Mark all functions not in the api as internal. diff --git a/contrib/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/contrib/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index a1b0a45..43b4ab5 100644 --- a/contrib/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/contrib/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -35,6 +35,11 @@ using namespace llvm; static cl::opt<bool> RunVectorization("vectorize", cl::desc("Run vectorization passes")); +static cl::opt<bool> +UseGVNAfterVectorization("use-gvn-after-vectorization", + cl::init(false), cl::Hidden, + cl::desc("Run GVN instead of Early CSE after vectorization passes")); + PassManagerBuilder::PassManagerBuilder() { OptLevel = 2; SizeLevel = 0; @@ -182,8 +187,10 @@ void PassManagerBuilder::populateModulePassManager(PassManagerBase &MPM) { if (Vectorize) { MPM.add(createBBVectorizePass()); MPM.add(createInstructionCombiningPass()); - if (OptLevel > 1) - MPM.add(createGVNPass()); // Remove redundancies + if (OptLevel > 1 && UseGVNAfterVectorization) + MPM.add(createGVNPass()); // Remove redundancies + else + MPM.add(createEarlyCSEPass()); // Catch trivial redundancies } MPM.add(createAggressiveDCEPass()); // Delete dead instructions diff --git a/contrib/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/contrib/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index d57ec22..b085b00 100644 --- a/contrib/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/contrib/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -77,6 +77,12 @@ #include <algorithm> using namespace llvm; +/// MaxIVUsers is an arbitrary threshold that provides an early opportunitiy for +/// bail out. This threshold is far beyond the number of users that LSR can +/// conceivably solve, so it should not affect generated code, but catches the +/// worst cases before LSR burns too much compile time and stack space. +static const unsigned MaxIVUsers = 200; + // Temporary flag to cleanup congruent phis after LSR phi expansion. // It's currently disabled until we can determine whether it's truly useful or // not. The flag should be removed after the v3.0 release. @@ -4102,7 +4108,7 @@ LSRInstance::HoistInsertPosition(BasicBlock::iterator IP, // Attempt to find an insert position in the middle of the block, // instead of at the end, so that it can be used for other expansions. if (IDom == Inst->getParent() && - (!BetterPos || DT.dominates(BetterPos, Inst))) + (!BetterPos || !DT.dominates(Inst, BetterPos))) BetterPos = llvm::next(BasicBlock::iterator(Inst)); } if (!AllDominate) @@ -4519,6 +4525,17 @@ LSRInstance::LSRInstance(const TargetLowering *tli, Loop *l, Pass *P) // If there's no interesting work to be done, bail early. if (IU.empty()) return; + // If there's too much analysis to be done, bail early. We won't be able to + // model the problem anyway. + unsigned NumUsers = 0; + for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) { + if (++NumUsers > MaxIVUsers) { + DEBUG(dbgs() << "LSR skipping loop, too many IV Users in " << *L + << "\n"); + return; + } + } + #ifndef NDEBUG // All dominating loops must have preheaders, or SCEVExpander may not be able // to materialize an AddRecExpr whose Start is an outer AddRecExpr. diff --git a/contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp index ee23268..930980f 100644 --- a/contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -624,11 +624,10 @@ bool LoopUnswitch::IsTrivialUnswitchCondition(Value *Cond, Constant **Val, /// LoopCond == Val to simplify the loop. If we decide that this is profitable, /// unswitch the loop, reprocess the pieces, then return true. bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val) { - Function *F = loopHeader->getParent(); - Constant *CondVal = 0; BasicBlock *ExitBlock = 0; + if (IsTrivialUnswitchCondition(LoopCond, &CondVal, &ExitBlock)) { // If the condition is trivial, always unswitch. There is no code growth // for this case. @@ -688,8 +687,8 @@ void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val, // If either edge is critical, split it. This helps preserve LoopSimplify // form for enclosing loops. - SplitCriticalEdge(BI, 0, this); - SplitCriticalEdge(BI, 1, this); + SplitCriticalEdge(BI, 0, this, false, false, true); + SplitCriticalEdge(BI, 1, this, false, false, true); } /// UnswitchTrivialCondition - Given a loop that has a trivial unswitchable diff --git a/contrib/llvm/lib/Transforms/Scalar/ObjCARC.cpp b/contrib/llvm/lib/Transforms/Scalar/ObjCARC.cpp index 40b0b20..7e3e69b 100644 --- a/contrib/llvm/lib/Transforms/Scalar/ObjCARC.cpp +++ b/contrib/llvm/lib/Transforms/Scalar/ObjCARC.cpp @@ -162,6 +162,7 @@ namespace { IC_MoveWeak, ///< objc_moveWeak (derived) IC_CopyWeak, ///< objc_copyWeak (derived) IC_DestroyWeak, ///< objc_destroyWeak (derived) + IC_StoreStrong, ///< objc_storeStrong (derived) IC_CallOrUser, ///< could call objc_release and/or "use" pointers IC_Call, ///< could call objc_release IC_User, ///< could "use" a pointer @@ -262,6 +263,7 @@ static InstructionClass GetFunctionClass(const Function *F) { return StringSwitch<InstructionClass>(F->getName()) .Case("objc_storeWeak", IC_StoreWeak) .Case("objc_initWeak", IC_InitWeak) + .Case("objc_storeStrong", IC_StoreStrong) .Default(IC_CallOrUser); // Second argument is i8**. if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1)) @@ -618,22 +620,35 @@ static bool DoesObjCBlockEscape(const Value *BlockPtr) { const User *UUser = *UI; // Special - Use by a call (callee or argument) is not considered // to be an escape. - if (isa<CallInst>(UUser) || isa<InvokeInst>(UUser)) - continue; - // Use by an instruction which copies the value is an escape if the - // result is an escape. - if (isa<BitCastInst>(UUser) || isa<GetElementPtrInst>(UUser) || - isa<PHINode>(UUser) || isa<SelectInst>(UUser)) { - Worklist.push_back(UUser); + switch (GetBasicInstructionClass(UUser)) { + case IC_StoreWeak: + case IC_InitWeak: + case IC_StoreStrong: + case IC_Autorelease: + case IC_AutoreleaseRV: + // These special functions make copies of their pointer arguments. + return true; + case IC_User: + case IC_None: + // Use by an instruction which copies the value is an escape if the + // result is an escape. + if (isa<BitCastInst>(UUser) || isa<GetElementPtrInst>(UUser) || + isa<PHINode>(UUser) || isa<SelectInst>(UUser)) { + Worklist.push_back(UUser); + continue; + } + // Use by a load is not an escape. + if (isa<LoadInst>(UUser)) + continue; + // Use by a store is not an escape if the use is the address. + if (const StoreInst *SI = dyn_cast<StoreInst>(UUser)) + if (V != SI->getValueOperand()) + continue; + break; + default: + // Regular calls and other stuff are not considered escapes. continue; } - // Use by a load is not an escape. - if (isa<LoadInst>(UUser)) - continue; - // Use by a store is not an escape if the use is the address. - if (const StoreInst *SI = dyn_cast<StoreInst>(UUser)) - if (V != SI->getValueOperand()) - continue; // Otherwise, conservatively assume an escape. return true; } @@ -883,7 +898,7 @@ bool ObjCARCExpand::runOnFunction(Function &F) { // These calls return their argument verbatim, as a low-level // optimization. However, this makes high-level optimizations // harder. Undo any uses of this optimization that the front-end - // emitted here. We'll redo them in a later pass. + // emitted here. We'll redo them in the contract pass. Changed = true; Inst->replaceAllUsesWith(cast<CallInst>(Inst)->getArgOperand(0)); break; @@ -997,7 +1012,11 @@ bool ObjCARCAPElim::runOnModule(Module &M) { return false; // Find the llvm.global_ctors variable, as the first step in - // identifying the global constructors. + // identifying the global constructors. In theory, unnecessary autorelease + // pools could occur anywhere, but in practice it's pretty rare. Global + // ctors are a place where autorelease pools get inserted automatically, + // so it's pretty common for them to be unnecessary, and it's pretty + // profitable to eliminate them. GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); if (!GV) return false; @@ -2263,6 +2282,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) { case IC_DestroyWeak: { CallInst *CI = cast<CallInst>(Inst); if (isNullOrUndef(CI->getArgOperand(0))) { + Changed = true; Type *Ty = CI->getArgOperand(0)->getType(); new StoreInst(UndefValue::get(cast<PointerType>(Ty)->getElementType()), Constant::getNullValue(Ty), @@ -2278,6 +2298,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) { CallInst *CI = cast<CallInst>(Inst); if (isNullOrUndef(CI->getArgOperand(0)) || isNullOrUndef(CI->getArgOperand(1))) { + Changed = true; Type *Ty = CI->getArgOperand(0)->getType(); new StoreInst(UndefValue::get(cast<PointerType>(Ty)->getElementType()), Constant::getNullValue(Ty), @@ -3165,6 +3186,8 @@ void ObjCARCOpt::MoveCalls(Value *Arg, } } +/// PerformCodePlacement - Identify pairings between the retains and releases, +/// and delete and/or move them. bool ObjCARCOpt::PerformCodePlacement(DenseMap<const BasicBlock *, BBState> &BBStates, @@ -3178,6 +3201,7 @@ ObjCARCOpt::PerformCodePlacement(DenseMap<const BasicBlock *, BBState> SmallVector<Instruction *, 4> NewReleases; SmallVector<Instruction *, 8> DeadInsts; + // Visit each retain. for (MapVector<Value *, RRInfo>::const_iterator I = Retains.begin(), E = Retains.end(); I != E; ++I) { Value *V = I->first; @@ -3651,6 +3675,7 @@ bool ObjCARCOpt::doInitialization(Module &M) { if (!EnableARCOpts) return false; + // If nothing in the Module uses ARC, don't do anything. Run = ModuleHasARC(M); if (!Run) return false; @@ -3985,6 +4010,7 @@ void ObjCARCContract::ContractRelease(Instruction *Release, } bool ObjCARCContract::doInitialization(Module &M) { + // If nothing in the Module uses ARC, don't do anything. Run = ModuleHasARC(M); if (!Run) return false; @@ -4060,6 +4086,7 @@ bool ObjCARCContract::runOnFunction(Function &F) { --BBI; while (isNoopInstruction(BBI)) --BBI; if (&*BBI == GetObjCArg(Inst)) { + Changed = true; InlineAsm *IA = InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()), /*isVarArg=*/false), @@ -4109,6 +4136,13 @@ bool ObjCARCContract::runOnFunction(Function &F) { Use &U = UI.getUse(); unsigned OperandNo = UI.getOperandNo(); ++UI; // Increment UI now, because we may unlink its element. + + // If the call's return value dominates a use of the call's argument + // value, rewrite the use to use the return value. We check for + // reachability here because an unreachable call is considered to + // trivially dominate itself, which would lead us to rewriting its + // argument in terms of its return value, which would lead to + // infinite loops in GetObjCArg. if (DT->isReachableFromEntry(U) && DT->dominates(Inst, U)) { Changed = true; @@ -4123,6 +4157,9 @@ bool ObjCARCContract::runOnFunction(Function &F) { if (Replacement->getType() != UseTy) Replacement = new BitCastInst(Replacement, UseTy, "", &BB->back()); + // While we're here, rewrite all edges for this PHI, rather + // than just one use at a time, to minimize the number of + // bitcasts we emit. for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) if (PHI->getIncomingBlock(i) == BB) { diff --git a/contrib/llvm/lib/Transforms/Scalar/Reassociate.cpp b/contrib/llvm/lib/Transforms/Scalar/Reassociate.cpp index cb408a1..5de00d1 100644 --- a/contrib/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/contrib/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -559,7 +559,8 @@ static unsigned FindInOperandList(SmallVectorImpl<ValueEntry> &Ops, unsigned i, /// EmitAddTreeOfValues - Emit a tree of add instructions, summing Ops together /// and returning the result. Insert the tree before I. -static Value *EmitAddTreeOfValues(Instruction *I, SmallVectorImpl<Value*> &Ops){ +static Value *EmitAddTreeOfValues(Instruction *I, + SmallVectorImpl<WeakVH> &Ops){ if (Ops.size() == 1) return Ops.back(); Value *V1 = Ops.back(); @@ -833,7 +834,7 @@ Value *Reassociate::OptimizeAdd(Instruction *I, // from an expression will drop a use of maxocc, and this can cause // RemoveFactorFromExpression on successive values to behave differently. Instruction *DummyInst = BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal); - SmallVector<Value*, 4> NewMulOps; + SmallVector<WeakVH, 4> NewMulOps; for (unsigned i = 0; i != Ops.size(); ++i) { // Only try to remove factors from expressions we're allowed to. BinaryOperator *BOp = dyn_cast<BinaryOperator>(Ops[i].Op); diff --git a/contrib/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/contrib/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 9c49ec1..f7b6941 100644 --- a/contrib/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/contrib/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -1583,21 +1583,16 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["llvm.exp2.f64"] = &Exp2; Optimizations["llvm.exp2.f32"] = &Exp2; -#ifdef HAVE_FLOORF - Optimizations["floor"] = &UnaryDoubleFP; -#endif -#ifdef HAVE_CEILF - Optimizations["ceil"] = &UnaryDoubleFP; -#endif -#ifdef HAVE_ROUNDF - Optimizations["round"] = &UnaryDoubleFP; -#endif -#ifdef HAVE_RINTF - Optimizations["rint"] = &UnaryDoubleFP; -#endif -#ifdef HAVE_NEARBYINTF - Optimizations["nearbyint"] = &UnaryDoubleFP; -#endif + if (TLI->has(LibFunc::floor) && TLI->has(LibFunc::floorf)) + Optimizations["floor"] = &UnaryDoubleFP; + if (TLI->has(LibFunc::ceil) && TLI->has(LibFunc::ceilf)) + Optimizations["ceil"] = &UnaryDoubleFP; + if (TLI->has(LibFunc::round) && TLI->has(LibFunc::roundf)) + Optimizations["round"] = &UnaryDoubleFP; + if (TLI->has(LibFunc::rint) && TLI->has(LibFunc::rintf)) + Optimizations["rint"] = &UnaryDoubleFP; + if (TLI->has(LibFunc::nearbyint) && TLI->has(LibFunc::nearbyintf)) + Optimizations["nearbyint"] = &UnaryDoubleFP; // Integer Optimizations Optimizations["ffs"] = &FFS; diff --git a/contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp b/contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp index f752d79..2a8e9b8 100644 --- a/contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp +++ b/contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -117,33 +117,38 @@ bool llvm::isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum, return false; } -/// CreatePHIsForSplitLoopExit - When a loop exit edge is split, LCSSA form +/// createPHIsForSplitLoopExit - When a loop exit edge is split, LCSSA form /// may require new PHIs in the new exit block. This function inserts the -/// new PHIs, as needed. Preds is a list of preds inside the loop, SplitBB +/// new PHIs, as needed. Preds is a list of preds inside the loop, SplitBB /// is the new loop exit block, and DestBB is the old loop exit, now the /// successor of SplitBB. -static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds, +static void createPHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds, BasicBlock *SplitBB, BasicBlock *DestBB) { // SplitBB shouldn't have anything non-trivial in it yet. - assert(SplitBB->getFirstNonPHI() == SplitBB->getTerminator() && - "SplitBB has non-PHI nodes!"); + assert((SplitBB->getFirstNonPHI() == SplitBB->getTerminator() || + SplitBB->isLandingPad()) && "SplitBB has non-PHI nodes!"); - // For each PHI in the destination block... + // For each PHI in the destination block. for (BasicBlock::iterator I = DestBB->begin(); PHINode *PN = dyn_cast<PHINode>(I); ++I) { unsigned Idx = PN->getBasicBlockIndex(SplitBB); Value *V = PN->getIncomingValue(Idx); + // If the input is a PHI which already satisfies LCSSA, don't create // a new one. if (const PHINode *VP = dyn_cast<PHINode>(V)) if (VP->getParent() == SplitBB) continue; + // Otherwise a new PHI is needed. Create one and populate it. - PHINode *NewPN = PHINode::Create(PN->getType(), Preds.size(), "split", - SplitBB->getTerminator()); + PHINode *NewPN = + PHINode::Create(PN->getType(), Preds.size(), "split", + SplitBB->isLandingPad() ? + SplitBB->begin() : SplitBB->getTerminator()); for (unsigned i = 0, e = Preds.size(); i != e; ++i) NewPN->addIncoming(V, Preds[i]); + // Update the original PHI. PN->setIncomingValue(Idx, NewPN); } @@ -168,7 +173,8 @@ static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds, /// BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P, bool MergeIdenticalEdges, - bool DontDeleteUselessPhis) { + bool DontDeleteUselessPhis, + bool SplitLandingPads) { if (!isCriticalEdge(TI, SuccNum, MergeIdenticalEdges)) return 0; assert(!isa<IndirectBrInst>(TI) && @@ -338,7 +344,7 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, if (P->mustPreserveAnalysisID(LCSSAID)) { SmallVector<BasicBlock *, 1> OrigPred; OrigPred.push_back(TIBB); - CreatePHIsForSplitLoopExit(OrigPred, NewBB, DestBB); + createPHIsForSplitLoopExit(OrigPred, NewBB, DestBB); } // For each unique exit block... @@ -371,10 +377,19 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, // getUniqueExitBlocks above because that depends on LoopSimplify // form, which we're in the process of restoring! if (!Preds.empty() && HasPredOutsideOfLoop) { - BasicBlock *NewExitBB = - SplitBlockPredecessors(Exit, Preds, "split", P); - if (P->mustPreserveAnalysisID(LCSSAID)) - CreatePHIsForSplitLoopExit(Preds, NewExitBB, Exit); + if (!Exit->isLandingPad()) { + BasicBlock *NewExitBB = + SplitBlockPredecessors(Exit, Preds, "split", P); + if (P->mustPreserveAnalysisID(LCSSAID)) + createPHIsForSplitLoopExit(Preds, NewExitBB, Exit); + } else if (SplitLandingPads) { + SmallVector<BasicBlock*, 8> NewBBs; + SplitLandingPadPredecessors(Exit, Preds, + ".split1", ".split2", + P, NewBBs); + if (P->mustPreserveAnalysisID(LCSSAID)) + createPHIsForSplitLoopExit(Preds, NewBBs[0], Exit); + } } } } diff --git a/contrib/llvm/lib/Transforms/Vectorize/BBVectorize.cpp b/contrib/llvm/lib/Transforms/Vectorize/BBVectorize.cpp index 286b54f..9d62306 100644 --- a/contrib/llvm/lib/Transforms/Vectorize/BBVectorize.cpp +++ b/contrib/llvm/lib/Transforms/Vectorize/BBVectorize.cpp @@ -84,6 +84,10 @@ NoFloats("bb-vectorize-no-floats", cl::init(false), cl::Hidden, cl::desc("Don't try to vectorize floating-point values")); static cl::opt<bool> +NoPointers("bb-vectorize-no-pointers", cl::init(false), cl::Hidden, + cl::desc("Don't try to vectorize pointer values")); + +static cl::opt<bool> NoCasts("bb-vectorize-no-casts", cl::init(false), cl::Hidden, cl::desc("Don't try to vectorize casting (conversion) operations")); @@ -96,6 +100,14 @@ NoFMA("bb-vectorize-no-fma", cl::init(false), cl::Hidden, cl::desc("Don't try to vectorize the fused-multiply-add intrinsic")); static cl::opt<bool> +NoSelect("bb-vectorize-no-select", cl::init(false), cl::Hidden, + cl::desc("Don't try to vectorize select instructions")); + +static cl::opt<bool> +NoGEP("bb-vectorize-no-gep", cl::init(false), cl::Hidden, + cl::desc("Don't try to vectorize getelementptr instructions")); + +static cl::opt<bool> NoMemOps("bb-vectorize-no-mem-ops", cl::init(false), cl::Hidden, cl::desc("Don't try to vectorize loads and stores")); @@ -546,11 +558,21 @@ namespace { return false; Type *SrcTy = C->getSrcTy(); - if (!SrcTy->isSingleValueType() || SrcTy->isPointerTy()) + if (!SrcTy->isSingleValueType()) return false; Type *DestTy = C->getDestTy(); - if (!DestTy->isSingleValueType() || DestTy->isPointerTy()) + if (!DestTy->isSingleValueType()) + return false; + } else if (isa<SelectInst>(I)) { + if (!Config.VectorizeSelect) + return false; + } else if (GetElementPtrInst *G = dyn_cast<GetElementPtrInst>(I)) { + if (!Config.VectorizeGEP) + return false; + + // Currently, vector GEPs exist only with one index. + if (G->getNumIndices() != 1) return false; } else if (!(I->isBinaryOp() || isa<ShuffleVectorInst>(I) || isa<ExtractElementInst>(I) || isa<InsertElementInst>(I))) { @@ -590,6 +612,11 @@ namespace { && (T1->isFPOrFPVectorTy() || T2->isFPOrFPVectorTy())) return false; + if ((!Config.VectorizePointers || TD == 0) && + (T1->getScalarType()->isPointerTy() || + T2->getScalarType()->isPointerTy())) + return false; + if (T1->getPrimitiveSizeInBits() > Config.VectorBits/2 || T2->getPrimitiveSizeInBits() > Config.VectorBits/2) return false; @@ -828,16 +855,33 @@ namespace { std::vector<Value *> &PairableInsts, std::multimap<ValuePair, ValuePair> &ConnectedPairs, ValuePair P) { + StoreInst *SI, *SJ; + // For each possible pairing for this variable, look at the uses of // the first value... for (Value::use_iterator I = P.first->use_begin(), E = P.first->use_end(); I != E; ++I) { + if (isa<LoadInst>(*I)) { + // A pair cannot be connected to a load because the load only takes one + // operand (the address) and it is a scalar even after vectorization. + continue; + } else if ((SI = dyn_cast<StoreInst>(*I)) && + P.first == SI->getPointerOperand()) { + // Similarly, a pair cannot be connected to a store through its + // pointer operand. + continue; + } + VPIteratorPair IPairRange = CandidatePairs.equal_range(*I); // For each use of the first variable, look for uses of the second // variable... for (Value::use_iterator J = P.second->use_begin(), E2 = P.second->use_end(); J != E2; ++J) { + if ((SJ = dyn_cast<StoreInst>(*J)) && + P.second == SJ->getPointerOperand()) + continue; + VPIteratorPair JPairRange = CandidatePairs.equal_range(*J); // Look for <I, J>: @@ -853,6 +897,10 @@ namespace { // Look for cases where just the first value in the pair is used by // both members of another pair (splatting). for (Value::use_iterator J = P.first->use_begin(); J != E; ++J) { + if ((SJ = dyn_cast<StoreInst>(*J)) && + P.first == SJ->getPointerOperand()) + continue; + if (isSecondInIteratorPair<Value*>(*J, IPairRange)) ConnectedPairs.insert(VPPair(P, ValuePair(*I, *J))); } @@ -863,9 +911,19 @@ namespace { // both members of another pair (splatting). for (Value::use_iterator I = P.second->use_begin(), E = P.second->use_end(); I != E; ++I) { + if (isa<LoadInst>(*I)) + continue; + else if ((SI = dyn_cast<StoreInst>(*I)) && + P.second == SI->getPointerOperand()) + continue; + VPIteratorPair IPairRange = CandidatePairs.equal_range(*I); for (Value::use_iterator J = P.second->use_begin(); J != E; ++J) { + if ((SJ = dyn_cast<StoreInst>(*J)) && + P.second == SJ->getPointerOperand()) + continue; + if (isSecondInIteratorPair<Value*>(*J, IPairRange)) ConnectedPairs.insert(VPPair(P, ValuePair(*I, *J))); } @@ -1891,9 +1949,12 @@ VectorizeConfig::VectorizeConfig() { VectorBits = ::VectorBits; VectorizeInts = !::NoInts; VectorizeFloats = !::NoFloats; + VectorizePointers = !::NoPointers; VectorizeCasts = !::NoCasts; VectorizeMath = !::NoMath; VectorizeFMA = !::NoFMA; + VectorizeSelect = !::NoSelect; + VectorizeGEP = !::NoGEP; VectorizeMemOps = !::NoMemOps; AlignedOnly = ::AlignedOnly; ReqChainDepth= ::ReqChainDepth; diff --git a/contrib/llvm/lib/VMCore/AutoUpgrade.cpp b/contrib/llvm/lib/VMCore/AutoUpgrade.cpp index ea3d4ba..2e16372 100644 --- a/contrib/llvm/lib/VMCore/AutoUpgrade.cpp +++ b/contrib/llvm/lib/VMCore/AutoUpgrade.cpp @@ -18,9 +18,6 @@ #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/IntrinsicInst.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" #include "llvm/Support/ErrorHandling.h" @@ -59,7 +56,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { if (Name.startswith("x86.sse2.pcmpeq.") || Name.startswith("x86.sse2.pcmpgt.") || Name.startswith("x86.avx2.pcmpeq.") || - Name.startswith("x86.avx2.pcmpgt.")) { + Name.startswith("x86.avx2.pcmpgt.") || + Name.startswith("x86.avx.vpermil.")) { NewFn = 0; return true; } @@ -121,7 +119,42 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { // need to sign extend since icmp returns vector of i1 Rep = Builder.CreateSExt(Rep, CI->getType(), ""); } else { - llvm_unreachable("Unknown function for CallInst upgrade."); + bool PD128 = false, PD256 = false, PS128 = false, PS256 = false; + if (Name.startswith("llvm.x86.avx.vpermil.pd.256")) + PD256 = true; + else if (Name.startswith("llvm.x86.avx.vpermil.pd")) + PD128 = true; + else if (Name.startswith("llvm.x86.avx.vpermil.ps.256")) + PS256 = true; + else if (Name.startswith("llvm.x86.avx.vpermil.ps")) + PS128 = true; + + if (PD256 || PD128 || PS256 || PS128) { + Value *Op0 = CI->getArgOperand(0); + unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue(); + SmallVector<Constant*, 8> Idxs; + + if (PD128) + for (unsigned i = 0; i != 2; ++i) + Idxs.push_back(Builder.getInt32((Imm >> i) & 0x1)); + else if (PD256) + for (unsigned l = 0; l != 4; l+=2) + for (unsigned i = 0; i != 2; ++i) + Idxs.push_back(Builder.getInt32(((Imm >> (l+i)) & 0x1) + l)); + else if (PS128) + for (unsigned i = 0; i != 4; ++i) + Idxs.push_back(Builder.getInt32((Imm >> (2 * i)) & 0x3)); + else if (PS256) + for (unsigned l = 0; l != 8; l+=4) + for (unsigned i = 0; i != 4; ++i) + Idxs.push_back(Builder.getInt32(((Imm >> (2 * i)) & 0x3) + l)); + else + llvm_unreachable("Unexpected function"); + + Rep = Builder.CreateShuffleVector(Op0, Op0, ConstantVector::get(Idxs)); + } else { + llvm_unreachable("Unknown function for CallInst upgrade."); + } } CI->replaceAllUsesWith(Rep); diff --git a/contrib/llvm/lib/VMCore/Instructions.cpp b/contrib/llvm/lib/VMCore/Instructions.cpp index 8db6ac9..6c5db32 100644 --- a/contrib/llvm/lib/VMCore/Instructions.cpp +++ b/contrib/llvm/lib/VMCore/Instructions.cpp @@ -2003,6 +2003,23 @@ bool BinaryOperator::isExact() const { } //===----------------------------------------------------------------------===// +// FPMathOperator Class +//===----------------------------------------------------------------------===// + +/// getFPAccuracy - Get the maximum error permitted by this operation in ULPs. +/// An accuracy of 0.0 means that the operation should be performed with the +/// default precision. +float FPMathOperator::getFPAccuracy() const { + const MDNode *MD = + cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath); + if (!MD) + return 0.0; + ConstantFP *Accuracy = cast<ConstantFP>(MD->getOperand(0)); + return Accuracy->getValueAPF().convertToFloat(); +} + + +//===----------------------------------------------------------------------===// // CastInst Class //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/VMCore/LLVMContext.cpp b/contrib/llvm/lib/VMCore/LLVMContext.cpp index 68c5621..f07f0b3 100644 --- a/contrib/llvm/lib/VMCore/LLVMContext.cpp +++ b/contrib/llvm/lib/VMCore/LLVMContext.cpp @@ -44,9 +44,9 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { unsigned ProfID = getMDKindID("prof"); assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID; - // Create the 'fpaccuracy' metadata kind. - unsigned FPAccuracyID = getMDKindID("fpaccuracy"); - assert(FPAccuracyID == MD_fpaccuracy && "fpaccuracy kind id drifted"); + // Create the 'fpmath' metadata kind. + unsigned FPAccuracyID = getMDKindID("fpmath"); + assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted"); (void)FPAccuracyID; // Create the 'range' metadata kind. diff --git a/contrib/llvm/lib/VMCore/Module.cpp b/contrib/llvm/lib/VMCore/Module.cpp index e8bc6db..3c67191 100644 --- a/contrib/llvm/lib/VMCore/Module.cpp +++ b/contrib/llvm/lib/VMCore/Module.cpp @@ -434,7 +434,7 @@ bool Module::MaterializeAllPermanently(std::string *ErrInfo) { // -// dropAllReferences() - This function causes all the subelementss to "let go" +// dropAllReferences() - This function causes all the subelements to "let go" // of all references that they are maintaining. This allows one to 'delete' a // whole module at a time, even though there may be circular references... first // all references are dropped, and all use counts go to zero. Then everything diff --git a/contrib/llvm/lib/VMCore/Verifier.cpp b/contrib/llvm/lib/VMCore/Verifier.cpp index 96492e4..47baef3 100644 --- a/contrib/llvm/lib/VMCore/Verifier.cpp +++ b/contrib/llvm/lib/VMCore/Verifier.cpp @@ -1653,16 +1653,18 @@ void Verifier::visitInstruction(Instruction &I) { } } - if (MDNode *MD = I.getMetadata(LLVMContext::MD_fpaccuracy)) { + if (MDNode *MD = I.getMetadata(LLVMContext::MD_fpmath)) { Assert1(I.getType()->isFPOrFPVectorTy(), - "fpaccuracy requires a floating point result!", &I); - Assert1(MD->getNumOperands() == 1, "fpaccuracy takes one operand!", &I); - ConstantFP *Op = dyn_cast_or_null<ConstantFP>(MD->getOperand(0)); - Assert1(Op, "fpaccuracy ULPs not a floating point number!", &I); - APFloat ULPs = Op->getValueAPF(); - Assert1(ULPs.isNormal() || ULPs.isZero(), - "fpaccuracy ULPs not a normal number!", &I); - Assert1(!ULPs.isNegative(), "fpaccuracy ULPs is negative!", &I); + "fpmath requires a floating point result!", &I); + Assert1(MD->getNumOperands() == 1, "fpmath takes one operand!", &I); + Value *Op0 = MD->getOperand(0); + if (ConstantFP *CFP0 = dyn_cast_or_null<ConstantFP>(Op0)) { + APFloat Accuracy = CFP0->getValueAPF(); + Assert1(Accuracy.isNormal() && !Accuracy.isNegative(), + "fpmath accuracy not a positive number!", &I); + } else { + Assert1(false, "invalid fpmath accuracy!", &I); + } } MDNode *MD = I.getMetadata(LLVMContext::MD_range); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Decl.h b/contrib/llvm/tools/clang/include/clang/AST/Decl.h index 11696db..ac7ab0f 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Decl.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Decl.h @@ -64,6 +64,9 @@ public: /// \brief Return the TypeLoc wrapper for the type source info. TypeLoc getTypeLoc() const; // implemented in TypeLoc.h + + /// \brief Override the type stored in this TypeSourceInfo. Use with caution! + void overrideType(QualType T) { Ty = T; } }; /// TranslationUnitDecl - The top declaration context. @@ -242,11 +245,7 @@ public: bool visibilityExplicit() const { return explicit_; } void setLinkage(Linkage L) { linkage_ = L; } - void setVisibility(Visibility V) { visibility_ = V; } void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } - void setVisibility(LinkageInfo Other) { - setVisibility(Other.visibility(), Other.visibilityExplicit()); - } void mergeLinkage(Linkage L) { setLinkage(minLinkage(linkage(), L)); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h index 4c675aed..22328912 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h @@ -861,7 +861,6 @@ public: void dumpXML(raw_ostream &OS) const; private: - const Attr *getAttrsImpl() const; void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx); void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, ASTContext &Ctx); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h b/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h index 66d190f..b8abe97 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h @@ -67,6 +67,8 @@ public: DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext(); + if (hasExternalVisibleStorage()) + getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary); if (StoredDeclsMap *Map = Primary->buildLookup()) return all_lookups_iterator(Map->begin(), Map->end()); return all_lookups_iterator(); @@ -74,6 +76,8 @@ DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { DeclContext::all_lookups_iterator DeclContext::lookups_end() const { DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext(); + if (hasExternalVisibleStorage()) + getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary); if (StoredDeclsMap *Map = Primary->buildLookup()) return all_lookups_iterator(Map->end(), Map->end()); return all_lookups_iterator(); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Expr.h b/contrib/llvm/tools/clang/include/clang/AST/Expr.h index 558bd00..b0b9b0f 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Expr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Expr.h @@ -581,16 +581,6 @@ public: /// member expression. static QualType findBoundMemberType(const Expr *expr); - /// \brief Result type of CanThrow(). - enum CanThrowResult { - CT_Cannot, - CT_Dependent, - CT_Can - }; - /// \brief Test if this expression, if evaluated, might throw, according to - /// the rules of C++ [expr.unary.noexcept]. - CanThrowResult CanThrow(ASTContext &C) const; - /// IgnoreImpCasts - Skip past any implicit casts which might /// surround this expression. Only skips ImplicitCastExprs. Expr *IgnoreImpCasts() LLVM_READONLY; @@ -3608,6 +3598,10 @@ public: return LBraceLoc.isValid() && RBraceLoc.isValid(); } + // Is this an initializer for an array of characters, initialized by a string + // literal or an @encode? + bool isStringLiteralInit() const; + SourceLocation getLBraceLoc() const { return LBraceLoc; } void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; } SourceLocation getRBraceLoc() const { return RBraceLoc; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h index 18a1432..e2a60d5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h @@ -126,6 +126,12 @@ public: virtual DeclContextLookupResult FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); + /// \brief Ensures that the table of all visible declarations inside this + /// context is up to date. + /// + /// The default implementation of this functino is a no-op. + virtual void completeVisibleDeclsMap(const DeclContext *DC); + /// \brief Finds all declarations lexically contained within the given /// DeclContext, after applying an optional filter predicate. /// diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h index a4ad525..f1b5171 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1870,6 +1870,7 @@ DEF_TRAVERSE_STMT(GotoStmt, { }) DEF_TRAVERSE_STMT(IfStmt, { }) DEF_TRAVERSE_STMT(IndirectGotoStmt, { }) DEF_TRAVERSE_STMT(LabelStmt, { }) +DEF_TRAVERSE_STMT(AttributedStmt, { }) DEF_TRAVERSE_STMT(NullStmt, { }) DEF_TRAVERSE_STMT(ObjCAtCatchStmt, { }) DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { }) diff --git a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h index 84bdfb8..1b0f576 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h @@ -20,6 +20,7 @@ #include "clang/AST/StmtIterator.h" #include "clang/AST/DeclGroup.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" @@ -794,6 +795,47 @@ public: }; +/// \brief Represents an attribute applied to a statement. +/// +/// Represents an attribute applied to a statement. For example: +/// [[omp::for(...)]] for (...) { ... } +/// +class AttributedStmt : public Stmt { + Stmt *SubStmt; + SourceLocation AttrLoc; + AttrVec Attrs; + // TODO: It can be done as Attr *Attrs[1]; and variable size array as in + // StringLiteral + + friend class ASTStmtReader; + +public: + AttributedStmt(SourceLocation loc, const AttrVec &attrs, Stmt *substmt) + : Stmt(AttributedStmtClass), SubStmt(substmt), AttrLoc(loc), Attrs(attrs) { + } + + // \brief Build an empty attributed statement. + explicit AttributedStmt(EmptyShell Empty) + : Stmt(AttributedStmtClass, Empty) { + } + + SourceLocation getAttrLoc() const { return AttrLoc; } + const AttrVec &getAttrs() const { return Attrs; } + Stmt *getSubStmt() { return SubStmt; } + const Stmt *getSubStmt() const { return SubStmt; } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(AttrLoc, SubStmt->getLocEnd()); + } + child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == AttributedStmtClass; + } + static bool classof(const AttributedStmt *) { return true; } +}; + + /// IfStmt - This represents an if/then/else. /// class IfStmt : public Stmt { diff --git a/contrib/llvm/tools/clang/include/clang/AST/Type.h b/contrib/llvm/tools/clang/include/clang/AST/Type.h index 7bd367c..7b615c1 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Type.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Type.h @@ -79,6 +79,7 @@ namespace clang { class CXXRecordDecl; class EnumDecl; class FieldDecl; + class FunctionDecl; class ObjCInterfaceDecl; class ObjCProtocolDecl; class ObjCMethodDecl; @@ -2700,7 +2701,9 @@ public: ExtProtoInfo() : Variadic(false), HasTrailingReturn(false), TypeQuals(0), ExceptionSpecType(EST_None), RefQualifier(RQ_None), - NumExceptions(0), Exceptions(0), NoexceptExpr(0), ConsumedArguments(0) {} + NumExceptions(0), Exceptions(0), NoexceptExpr(0), + ExceptionSpecDecl(0), ExceptionSpecTemplate(0), + ConsumedArguments(0) {} FunctionType::ExtInfo ExtInfo; bool Variadic : 1; @@ -2711,6 +2714,8 @@ public: unsigned NumExceptions; const QualType *Exceptions; Expr *NoexceptExpr; + FunctionDecl *ExceptionSpecDecl; + FunctionDecl *ExceptionSpecTemplate; const bool *ConsumedArguments; }; @@ -2756,6 +2761,11 @@ private: // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing // to the expression in the noexcept() specifier. + // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may + // be a pair of FunctionDecl* pointing to the function which should be used to + // instantiate this function type's exception specification, and the function + // from which it should be instantiated. + // ConsumedArgs - A variable size array, following Exceptions // and of length NumArgs, holding flags indicating which arguments // are consumed. This only appears if HasAnyConsumedArgs is true. @@ -2795,6 +2805,9 @@ public: EPI.Exceptions = exception_begin(); } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { EPI.NoexceptExpr = getNoexceptExpr(); + } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { + EPI.ExceptionSpecDecl = getExceptionSpecDecl(); + EPI.ExceptionSpecTemplate = getExceptionSpecTemplate(); } if (hasAnyConsumedArgs()) EPI.ConsumedArguments = getConsumedArgsBuffer(); @@ -2838,9 +2851,26 @@ public: // NoexceptExpr sits where the arguments end. return *reinterpret_cast<Expr *const *>(arg_type_end()); } + /// \brief If this function type has an uninstantiated exception + /// specification, this is the function whose exception specification + /// is represented by this type. + FunctionDecl *getExceptionSpecDecl() const { + if (getExceptionSpecType() != EST_Uninstantiated) + return 0; + return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0]; + } + /// \brief If this function type has an uninstantiated exception + /// specification, this is the function whose exception specification + /// should be instantiated to find the exception specification for + /// this type. + FunctionDecl *getExceptionSpecTemplate() const { + if (getExceptionSpecType() != EST_Uninstantiated) + return 0; + return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[1]; + } bool isNothrow(ASTContext &Ctx) const { ExceptionSpecificationType EST = getExceptionSpecType(); - assert(EST != EST_Delayed); + assert(EST != EST_Delayed && EST != EST_Uninstantiated); if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) return true; if (EST != EST_ComputedNoexcept) diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h index 2aa9a3d..392dad9 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h @@ -205,11 +205,11 @@ public: typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; private: uint64_t NumVTableComponents; - VTableComponent *VTableComponents; + llvm::OwningArrayPtr<VTableComponent> VTableComponents; /// VTableThunks - Contains thunks needed by vtables. uint64_t NumVTableThunks; - VTableThunkTy *VTableThunks; + llvm::OwningArrayPtr<VTableThunkTy> VTableThunks; /// Address points - Address points for all vtables. AddressPointsMapTy AddressPoints; @@ -227,11 +227,11 @@ public: } vtable_component_iterator vtable_component_begin() const { - return VTableComponents; + return VTableComponents.get(); } vtable_component_iterator vtable_component_end() const { - return VTableComponents+NumVTableComponents; + return VTableComponents.get()+NumVTableComponents; } uint64_t getNumVTableThunks() const { @@ -239,11 +239,11 @@ public: } vtable_thunk_iterator vtable_thunk_begin() const { - return VTableThunks; + return VTableThunks.get(); } vtable_thunk_iterator vtable_thunk_end() const { - return VTableThunks+NumVTableThunks; + return VTableThunks.get()+NumVTableThunks; } uint64_t getAddressPoint(BaseSubobject Base) const { diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h index b2200c6..aa7a33c 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h @@ -129,7 +129,7 @@ public: static bool classof(const ProgramPoint*) { return true; } bool operator==(const ProgramPoint & RHS) const { - return Data1 == Data1 && + return Data1 == RHS.Data1 && Data2 == RHS.Data2 && L == RHS.L && Tag == RHS.Tag; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def index f44aed6..4aea980 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def @@ -412,6 +412,9 @@ BUILTIN(__builtin_ia32_cvtps2pd256, "V4dV4f", "") BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "") BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "") BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "") +BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "") +BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "") +BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "") BUILTIN(__builtin_ia32_vinsertf128_pd256, "V4dV4dV2dIc", "") BUILTIN(__builtin_ia32_vinsertf128_ps256, "V8fV8fV4fIc", "") BUILTIN(__builtin_ia32_vinsertf128_si256, "V8iV8iV4iIc", "") @@ -560,9 +563,8 @@ BUILTIN(__builtin_ia32_pbroadcastw128, "V8sV8s", "") BUILTIN(__builtin_ia32_pbroadcastd128, "V4iV4i", "") BUILTIN(__builtin_ia32_pbroadcastq128, "V2LLiV2LLi", "") BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_permdf256, "V4dV4dIc", "") BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8f", "") -BUILTIN(__builtin_ia32_permdi256, "V4LLiV4LLiIc", "") +BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "") BUILTIN(__builtin_ia32_extract128i256, "V2LLiV4LLiIc", "") BUILTIN(__builtin_ia32_insert128i256, "V4LLiV4LLiV2LLiIc", "") BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "") diff --git a/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h b/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h index ec6b973..7fb5874 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h @@ -151,9 +151,9 @@ ConversionResult ConvertUTF16toUTF32 ( ConversionResult ConvertUTF32toUTF16 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); +#endif Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); -#endif Boolean isLegalUTF8String(const UTF8 *source, const UTF8 *sourceEnd); diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DelayedCleanupPool.h b/contrib/llvm/tools/clang/include/clang/Basic/DelayedCleanupPool.h deleted file mode 100644 index 8575bc2..0000000 --- a/contrib/llvm/tools/clang/include/clang/Basic/DelayedCleanupPool.h +++ /dev/null @@ -1,110 +0,0 @@ -//=== DelayedCleanupPool.h - Delayed Clean-up Pool Implementation *- C++ -*===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a facility to delay calling cleanup methods until specific -// points. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H -#define LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" - -namespace clang { - -/// \brief Gathers pairs of pointer-to-object/pointer-to-cleanup-function -/// allowing the cleanup functions to get called (with the pointer as parameter) -/// at specific points. -/// -/// The use case is to simplify clean-up of certain resources that, while their -/// lifetime is well-known and restricted, cleaning them up manually is easy to -/// miss and cause a leak. -/// -/// The same pointer can be added multiple times; its clean-up function will -/// only be called once. -class DelayedCleanupPool { -public: - typedef void (*CleanupFn)(void *ptr); - - /// \brief Adds a pointer and its associated cleanup function to be called - /// at a later point. - /// - /// \returns false if the pointer is already added, true otherwise. - bool delayCleanup(void *ptr, CleanupFn fn) { - assert(ptr && "Expected valid pointer to object"); - assert(fn && "Expected valid pointer to function"); - - CleanupFn &mapFn = Ptrs[ptr]; - assert((!mapFn || mapFn == fn) && - "Adding a pointer with different cleanup function!"); - - if (!mapFn) { - mapFn = fn; - Cleanups.push_back(std::make_pair(ptr, fn)); - return true; - } - - return false; - } - - template <typename T> - bool delayDelete(T *ptr) { - return delayCleanup(ptr, cleanupWithDelete<T>); - } - - template <typename T, void (T::*Fn)()> - bool delayMemberFunc(T *ptr) { - return delayCleanup(ptr, cleanupWithMemberFunc<T, Fn>); - } - - void doCleanup() { - for (SmallVector<std::pair<void *, CleanupFn>, 8>::reverse_iterator - I = Cleanups.rbegin(), E = Cleanups.rend(); I != E; ++I) - I->second(I->first); - Cleanups.clear(); - Ptrs.clear(); - } - - ~DelayedCleanupPool() { - doCleanup(); - } - -private: - llvm::DenseMap<void *, CleanupFn> Ptrs; - SmallVector<std::pair<void *, CleanupFn>, 8> Cleanups; - - template <typename T> - static void cleanupWithDelete(void *ptr) { - delete static_cast<T *>(ptr); - } - - template <typename T, void (T::*Fn)()> - static void cleanupWithMemberFunc(void *ptr) { - (static_cast<T *>(ptr)->*Fn)(); - } -}; - -/// \brief RAII object for triggering a cleanup of a DelayedCleanupPool. -class DelayedCleanupPoint { - DelayedCleanupPool &Pool; - -public: - DelayedCleanupPoint(DelayedCleanupPool &pool) : Pool(pool) { } - - ~DelayedCleanupPoint() { - Pool.doCleanup(); - } -}; - -} // end namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td index c183da7..957f05b 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -410,6 +410,8 @@ def ext_ellipsis_exception_spec : Extension< "exception specification of '...' is a Microsoft extension">; def err_dynamic_and_noexcept_specification : Error< "cannot have both throw() and noexcept() clause on the same function">; +def err_except_spec_unparsed : Error< + "unexpected end of exception specification">; def warn_cxx98_compat_noexcept_decl : Warning< "noexcept specifications are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index e553740..0614ade 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -231,9 +231,13 @@ def err_using_decl_can_not_refer_to_namespace : Error< "using declaration can not refer to namespace">; def err_using_decl_constructor : Error< "using declaration can not refer to a constructor">; -def warn_cxx98_compat_using_decl_constructor : Warning< - "inherited constructors are incompatible with C++98">, - InGroup<CXX98Compat>, DefaultIgnore; +def err_using_decl_constructor_unsupported : Error< + "inheriting constructors are not supported">; +// FIXME: Replace the above error with this warning if support for +// inheriting constructors is implemented. +//def warn_cxx98_compat_using_decl_constructor : Warning< +// "inheriting constructors are incompatible with C++98">, +// InGroup<CXX98Compat>, DefaultIgnore; def err_using_decl_destructor : Error< "using declaration can not refer to a destructor">; def err_using_decl_template_id : Error< @@ -1547,9 +1551,6 @@ def warn_objc_redundant_literal_use : Warning< "using %0 with a literal is redundant">, InGroup<ObjCRedundantLiteralUse>; } -def warn_bool_for_boolean_literal : Warning< - "BOOL of type %0 is non-intergal and unsuitable for a " - "boolean literal - ignored">, InGroup<DiagGroup<"numeric-literals">>; def err_only_annotate_after_access_spec : Error< "access specifier can only have annotation attributes">; def err_attribute_section_invalid_for_target : Error< @@ -1563,6 +1564,9 @@ def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< def warn_attribute_ignored : Warning<"%0 attribute ignored">; def warn_unknown_attribute_ignored : Warning< "unknown attribute %0 ignored">, InGroup<UnknownAttributes>; +def warn_attribute_invalid_on_stmt : Warning< + "attribute %0 cannot be specified on a statement">, + InGroup<IgnoredAttributes>; def warn_declspec_attribute_ignored : Warning< "attribute %0 is ignored, place it after \"%select{class|struct|union|enum}1\" to apply attribute to type declaration">, InGroup<IgnoredAttributes>; def warn_attribute_precede_definition : Warning< @@ -2583,6 +2587,8 @@ def note_template_enum_def_here : Note< "in instantiation of enumeration %q0 requested here">; def note_template_type_alias_instantiation_here : Note< "in instantiation of template type alias %0 requested here">; +def note_template_exception_spec_instantiation_here : Note< + "in instantiation of exception specification for %0 requested here">; def note_default_arg_instantiation_here : Note< "in instantiation of default argument for '%0' required here">; @@ -3798,6 +3804,9 @@ def warn_null_in_comparison_operation : Warning< def err_invalid_this_use : Error< "invalid use of 'this' outside of a non-static member function">; +def err_this_static_member_func : Error< + "'this' cannot be%select{| implicitly}0 used in a static member function " + "declaration">; def err_invalid_member_use_in_static_method : Error< "invalid use of member %0 in static member function">; def err_invalid_qualified_function_type : Error< @@ -3907,7 +3916,7 @@ def err_nosetter_property_incdec : Error< def err_nogetter_property_compound_assignment : Error< "a getter method is needed to perform a compound assignment on a property">; def err_nogetter_property_incdec : Error< - "no getter method %1 for %select{increment|decrement} of property">; + "no getter method %1 for %select{increment|decrement}0 of property">; def error_no_subobject_property_setting : Error< "expression is not assignable">; def err_qualified_objc_access : Error< diff --git a/contrib/llvm/tools/clang/include/clang/Basic/ExceptionSpecificationType.h b/contrib/llvm/tools/clang/include/clang/Basic/ExceptionSpecificationType.h index 98cfd29..e911bde 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/ExceptionSpecificationType.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/ExceptionSpecificationType.h @@ -16,7 +16,7 @@ namespace clang { -/// \brief The various types of exception specifications that exist in C++0x. +/// \brief The various types of exception specifications that exist in C++11. enum ExceptionSpecificationType { EST_None, ///< no exception specification EST_DynamicNone, ///< throw() @@ -24,7 +24,8 @@ enum ExceptionSpecificationType { EST_MSAny, ///< Microsoft throw(...) extension EST_BasicNoexcept, ///< noexcept EST_ComputedNoexcept, ///< noexcept(expression) - EST_Delayed ///< not known yet + EST_Delayed, ///< not known yet + EST_Uninstantiated ///< not instantiated yet }; inline bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType) { @@ -35,6 +36,19 @@ inline bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType) { return ESpecType == EST_BasicNoexcept || ESpecType == EST_ComputedNoexcept; } +/// \brief Possible results from evaluation of a noexcept expression. +enum CanThrowResult { + CT_Cannot, + CT_Dependent, + CT_Can +}; + +inline CanThrowResult mergeCanThrow(CanThrowResult CT1, CanThrowResult CT2) { + // CanThrowResult constants are ordered so that the maximum is the correct + // merge result. + return CT1 > CT2 ? CT1 : CT2; +} + } // end namespace clang #endif // LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h b/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h index 8028a73..b92f1cf 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h @@ -132,7 +132,7 @@ class OnDiskChainedHashTableGenerator { class Bucket { public: io::Offset off; - Item* head; + Item* head; unsigned length; Bucket() {} @@ -201,6 +201,7 @@ public: // Write out the number of items in the bucket. Emit16(out, B.length); + assert(B.length != 0 && "Bucket has a head but zero length?"); // Write out the entries in the bucket. for (Item *I = B.head; I ; I = I->next) { @@ -398,31 +399,30 @@ public: } key_iterator key_end() { return key_iterator(); } - /// \brief Iterates over all the entries in the table, returning - /// a key/data pair. - class item_iterator { + /// \brief Iterates over all the entries in the table, returning the data. + class data_iterator { const unsigned char* Ptr; unsigned NumItemsInBucketLeft; unsigned NumEntriesLeft; Info *InfoObj; public: - typedef std::pair<external_key_type, data_type> value_type; + typedef data_type value_type; - item_iterator(const unsigned char* const Ptr, unsigned NumEntries, + data_iterator(const unsigned char* const Ptr, unsigned NumEntries, Info *InfoObj) : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries), InfoObj(InfoObj) { } - item_iterator() + data_iterator() : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { } - bool operator==(const item_iterator& X) const { + bool operator==(const data_iterator& X) const { return X.NumEntriesLeft == NumEntriesLeft; } - bool operator!=(const item_iterator& X) const { + bool operator!=(const data_iterator& X) const { return X.NumEntriesLeft != NumEntriesLeft; } - item_iterator& operator++() { // Preincrement + data_iterator& operator++() { // Preincrement if (!NumItemsInBucketLeft) { // 'Items' starts with a 16-bit unsigned integer representing the // number of items in this bucket. @@ -438,8 +438,8 @@ public: --NumEntriesLeft; return *this; } - item_iterator operator++(int) { // Postincrement - item_iterator tmp = *this; ++*this; return tmp; + data_iterator operator++(int) { // Postincrement + data_iterator tmp = *this; ++*this; return tmp; } value_type operator*() const { @@ -454,15 +454,14 @@ public: // Read the key. const internal_key_type& Key = InfoObj->ReadKey(LocalPtr, L.first); - return std::make_pair(InfoObj->GetExternalKey(Key), - InfoObj->ReadData(Key, LocalPtr + L.first, L.second)); + return InfoObj->ReadData(Key, LocalPtr + L.first, L.second); } }; - item_iterator item_begin() { - return item_iterator(Base + 4, getNumEntries(), &InfoObj); + data_iterator data_begin() { + return data_iterator(Base + 4, getNumEntries(), &InfoObj); } - item_iterator item_end() { return item_iterator(); } + data_iterator data_end() { return data_iterator(); } Info &getInfoObj() { return InfoObj; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td index 67d71e4..e7718cd 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td @@ -12,6 +12,7 @@ class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> { def NullStmt : Stmt; def CompoundStmt : Stmt; def LabelStmt : Stmt; +def AttributedStmt : Stmt; def IfStmt : Stmt; def SwitchStmt : Stmt; def WhileStmt : Stmt; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h index bbd376a..a03cf83 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h @@ -132,6 +132,11 @@ protected: IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType, WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType; + /// Flag whether the Objective-C built-in boolean type should be signed char. + /// Otherwise, when this flag is not set, the normal built-in boolean type is + /// used. + unsigned UseSignedCharForObjCBool : 1; + /// Control whether the alignment of bit-field types is respected when laying /// out structures. If true, then the alignment of the bit-field type will be /// used to (a) impact the alignment of the containing structure, and (b) @@ -299,6 +304,16 @@ public: return MCountName; } + /// useSignedCharForObjCBool - Check if the Objective-C built-in boolean + /// type should be signed char. Otherwise, if this returns false, the + /// normal built-in boolean type should also be used for Objective-C. + bool useSignedCharForObjCBool() const { + return UseSignedCharForObjCBool; + } + void noSignedCharForObjCBool() { + UseSignedCharForObjCBool = false; + } + /// useBitFieldTypeAlignment() - Check whether the alignment of bit-field /// types is respected when laying out structures. bool useBitFieldTypeAlignment() const { diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def index 2e4d34d..fe0ef30 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def @@ -105,6 +105,7 @@ TOK(eod) // End of preprocessing directive (end of line inside a // directive). TOK(code_completion) // Code completion marker TOK(cxx_defaultarg_end) // C++ default argument end marker +TOK(cxx_exceptspec_end) // C++ exception-specification end marker // C99 6.4.9: Comments. TOK(comment) // Comment (only in -E -C[C] mode) diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td index 88009ed..d9d47c5 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td @@ -428,9 +428,6 @@ def ast_view : Flag<"-ast-view">, HelpText<"Build ASTs and view them with GraphViz">; def print_decl_contexts : Flag<"-print-decl-contexts">, HelpText<"Print DeclContexts and their Decls">; -def pubnames_dump : Flag<"-pubnames-dump">, - HelpText<"Print all of the public (global) names in the source, e.g., the " - "names of all global declarations and macros">; def emit_module : Flag<"-emit-module">, HelpText<"Generate pre-compiled module file from a module map">; def emit_pth : Flag<"-emit-pth">, diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h index fd88c3a..6f1a221 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h @@ -92,6 +92,9 @@ public: return FailureResultFiles; } + /// Returns the sysroot path. + StringRef getSysRoot() const; + /// getArgsForToolChain - Return the derived argument list for the /// tool chain \arg TC (or the default tool chain, if TC is not /// specified). diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h index 5e4ecad..041eabb 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h @@ -14,7 +14,6 @@ #ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H #define LLVM_CLANG_FRONTEND_ASTUNIT_H -#include "clang/Index/ASTLocation.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Sema/Sema.h" #include "clang/Sema/CodeCompleteConsumer.h" @@ -57,8 +56,6 @@ class SourceManager; class TargetInfo; class ASTFrontendAction; -using namespace idx; - /// \brief Utility class for loading a ASTContext from an AST file. /// class ASTUnit : public ModuleLoader { @@ -134,9 +131,6 @@ private: /// The name of the original source file used to generate this ASTUnit. std::string OriginalSourceFile; - // Critical optimization when using clang_getCursor(). - ASTLocation LastLoc; - /// \brief The set of diagnostics produced when creating the preamble. SmallVector<StoredDiagnostic, 4> PreambleDiagnostics; @@ -474,10 +468,6 @@ public: bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; } void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; } - void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; } - ASTLocation getLastASTLocation() const { return LastLoc; } - - StringRef getMainFileName() const; typedef std::vector<Decl *>::iterator top_level_iterator; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h index 8817c5a..8f7fe87 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h @@ -173,15 +173,6 @@ protected: virtual bool usesPreprocessorOnly() const { return true; } }; -class PubnamesDumpAction : public ASTFrontendAction { -protected: - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef InFile); - -public: - virtual bool hasCodeCompletionSupport() const { return false; } -}; - //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h index a051d7f..888388c 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h @@ -42,7 +42,6 @@ namespace frontend { PrintDeclContext, ///< Print DeclContext and their Decls. PrintPreamble, ///< Print the "preamble" of the input file PrintPreprocessedInput, ///< -E mode. - PubnamesDump, ///< Print all of the "public" names in the source. RewriteMacros, ///< Expand macros but not #includes. RewriteObjC, ///< ObjC->C Rewriter. RewriteTest, ///< Rewriter playground diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h index 519d3b6..314003b 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h @@ -18,6 +18,8 @@ #include "clang/Frontend/DiagnosticRenderer.h" +struct SourceColumnMap; + namespace clang { /// \brief Class to encapsulate the logic for formatting and printing a textual @@ -103,15 +105,16 @@ private: SmallVectorImpl<CharSourceRange>& Ranges, ArrayRef<FixItHint> Hints); + void emitSnippet(StringRef SourceLine); + void highlightRange(const CharSourceRange &R, unsigned LineNo, FileID FID, - const std::string &SourceLine, + const SourceColumnMap &map, std::string &CaretLine); + std::string buildFixItInsertionLine(unsigned LineNo, - const char *LineStart, - const char *LineEnd, + const SourceColumnMap &map, ArrayRef<FixItHint> Hints); - void expandTabs(std::string &SourceLine, std::string &CaretLine); void emitParseableFixits(ArrayRef<FixItHint> Hints); }; diff --git a/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h b/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h deleted file mode 100644 index 45097cc..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h +++ /dev/null @@ -1,173 +0,0 @@ -//===--- ASTLocation.h - A <Decl, Stmt> pair --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// ASTLocation is Decl or a Stmt and its immediate Decl parent. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_ASTLOCATION_H -#define LLVM_CLANG_INDEX_ASTLOCATION_H - -#include "clang/AST/TypeLoc.h" -#include "llvm/ADT/PointerIntPair.h" -#include "llvm/Support/Compiler.h" - -namespace clang { - class Decl; - class Stmt; - class NamedDecl; - -namespace idx { - class TranslationUnit; - -/// \brief Represents a Decl or a Stmt and its immediate Decl parent. It's -/// immutable. -/// -/// ASTLocation is intended to be used as a "pointer" into the AST. It is either -/// just a Decl, or a Stmt and its Decl parent. Since a single Stmt is devoid -/// of context, its parent Decl provides all the additional missing information -/// like the declaration context, ASTContext, etc. -/// -class ASTLocation { -public: - enum NodeKind { - N_Decl, N_NamedRef, N_Stmt, N_Type - }; - - struct NamedRef { - NamedDecl *ND; - SourceLocation Loc; - - NamedRef() : ND(0) { } - NamedRef(NamedDecl *nd, SourceLocation loc) : ND(nd), Loc(loc) { } - }; - -private: - llvm::PointerIntPair<Decl *, 2, NodeKind> ParentDecl; - - union { - Decl *D; - Stmt *Stm; - struct { - NamedDecl *ND; - unsigned RawLoc; - } NDRef; - struct { - void *TyPtr; - void *Data; - } Ty; - }; - -public: - ASTLocation() { } - - explicit ASTLocation(const Decl *d) - : ParentDecl(const_cast<Decl*>(d), N_Decl), D(const_cast<Decl*>(d)) { } - - ASTLocation(const Decl *parentDecl, const Stmt *stm) - : ParentDecl(const_cast<Decl*>(parentDecl), N_Stmt), - Stm(const_cast<Stmt*>(stm)) { - if (!stm) ParentDecl.setPointer(0); - } - - ASTLocation(const Decl *parentDecl, NamedDecl *ndRef, SourceLocation loc) - : ParentDecl(const_cast<Decl*>(parentDecl), N_NamedRef) { - if (ndRef) { - NDRef.ND = ndRef; - NDRef.RawLoc = loc.getRawEncoding(); - } else - ParentDecl.setPointer(0); - } - - ASTLocation(const Decl *parentDecl, TypeLoc tyLoc) - : ParentDecl(const_cast<Decl*>(parentDecl), N_Type) { - if (tyLoc) { - Ty.TyPtr = tyLoc.getType().getAsOpaquePtr(); - Ty.Data = tyLoc.getOpaqueData(); - } else - ParentDecl.setPointer(0); - } - - bool isValid() const { return ParentDecl.getPointer() != 0; } - bool isInvalid() const { return !isValid(); } - - NodeKind getKind() const { - assert(isValid()); - return (NodeKind)ParentDecl.getInt(); - } - - Decl *getParentDecl() const { return ParentDecl.getPointer(); } - - Decl *AsDecl() const { - assert(getKind() == N_Decl); - return D; - } - Stmt *AsStmt() const { - assert(getKind() == N_Stmt); - return Stm; - } - NamedRef AsNamedRef() const { - assert(getKind() == N_NamedRef); - return NamedRef(NDRef.ND, SourceLocation::getFromRawEncoding(NDRef.RawLoc)); - } - TypeLoc AsTypeLoc() const { - assert(getKind() == N_Type); - return TypeLoc(QualType::getFromOpaquePtr(Ty.TyPtr), Ty.Data); - } - - Decl *dyn_AsDecl() const { return isValid() && getKind() == N_Decl ? D : 0; } - Stmt *dyn_AsStmt() const { - return isValid() && getKind() == N_Stmt ? Stm : 0; - } - NamedRef dyn_AsNamedRef() const { - return getKind() == N_Type ? AsNamedRef() : NamedRef(); - } - TypeLoc dyn_AsTypeLoc() const { - return getKind() == N_Type ? AsTypeLoc() : TypeLoc(); - } - - bool isDecl() const { return isValid() && getKind() == N_Decl; } - bool isStmt() const { return isValid() && getKind() == N_Stmt; } - bool isNamedRef() const { return isValid() && getKind() == N_NamedRef; } - bool isType() const { return isValid() && getKind() == N_Type; } - - /// \brief Returns the declaration that this ASTLocation references. - /// - /// If this points to a Decl, that Decl is returned. - /// If this points to an Expr that references a Decl, that Decl is returned, - /// otherwise it returns NULL. - Decl *getReferencedDecl(); - const Decl *getReferencedDecl() const { - return const_cast<ASTLocation*>(this)->getReferencedDecl(); - } - - SourceRange getSourceRange() const LLVM_READONLY; - - void print(raw_ostream &OS) const; -}; - -/// \brief Like ASTLocation but also contains the TranslationUnit that the -/// ASTLocation originated from. -class TULocation : public ASTLocation { - TranslationUnit *TU; - -public: - TULocation(TranslationUnit *tu, ASTLocation astLoc) - : ASTLocation(astLoc), TU(tu) { - assert(tu && "Passed null translation unit"); - } - - TranslationUnit *getTU() const { return TU; } -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/Analyzer.h b/contrib/llvm/tools/clang/include/clang/Index/Analyzer.h deleted file mode 100644 index f6b5465..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/Analyzer.h +++ /dev/null @@ -1,56 +0,0 @@ -//===--- Analyzer.h - Analysis for indexing information ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the Analyzer interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_ANALYZER_H -#define LLVM_CLANG_INDEX_ANALYZER_H - -namespace clang { - class Decl; - class ObjCMessageExpr; - -namespace idx { - class Program; - class IndexProvider; - class TULocationHandler; - -/// \brief Provides indexing information, like finding all references of an -/// Entity across translation units. -class Analyzer { - Program &Prog; - IndexProvider &Idxer; - - Analyzer(const Analyzer&); // do not implement - Analyzer &operator=(const Analyzer &); // do not implement - -public: - explicit Analyzer(Program &prog, IndexProvider &idxer) - : Prog(prog), Idxer(idxer) { } - - /// \brief Find all TULocations for declarations of the given Decl and pass - /// them to Handler. - void FindDeclarations(Decl *D, TULocationHandler &Handler); - - /// \brief Find all TULocations for references of the given Decl and pass - /// them to Handler. - void FindReferences(Decl *D, TULocationHandler &Handler); - - /// \brief Find methods that may respond to the given message and pass them - /// to Handler. - void FindObjCMethods(ObjCMessageExpr *MsgE, TULocationHandler &Handler); -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/DeclReferenceMap.h b/contrib/llvm/tools/clang/include/clang/Index/DeclReferenceMap.h deleted file mode 100644 index 73f2fe5..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/DeclReferenceMap.h +++ /dev/null @@ -1,50 +0,0 @@ -//===--- DeclReferenceMap.h - Map Decls to their references -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// DeclReferenceMap creates a mapping from Decls to the ASTLocations that -// reference them. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_DECLREFERENCEMAP_H -#define LLVM_CLANG_INDEX_DECLREFERENCEMAP_H - -#include "clang/Index/ASTLocation.h" -#include "clang/Index/STLExtras.h" -#include <map> - -namespace clang { - class ASTContext; - class NamedDecl; - -namespace idx { - -/// \brief Maps NamedDecls with the ASTLocations that reference them. -/// -/// References are mapped and retrieved using the canonical decls. -class DeclReferenceMap { -public: - explicit DeclReferenceMap(ASTContext &Ctx); - - typedef std::multimap<NamedDecl*, ASTLocation> MapTy; - typedef pair_value_iterator<MapTy::iterator> astlocation_iterator; - - astlocation_iterator refs_begin(NamedDecl *D) const; - astlocation_iterator refs_end(NamedDecl *D) const; - bool refs_empty(NamedDecl *D) const; - -private: - mutable MapTy Map; -}; - -} // end idx namespace - -} // end clang namespace - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/Entity.h b/contrib/llvm/tools/clang/include/clang/Index/Entity.h deleted file mode 100644 index d104458..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/Entity.h +++ /dev/null @@ -1,149 +0,0 @@ -//===--- Entity.h - Cross-translation-unit "token" for decls ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Entity is a ASTContext-independent way to refer to declarations that are -// visible across translation units. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_ENTITY_H -#define LLVM_CLANG_INDEX_ENTITY_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" -#include <string> - -namespace clang { - class ASTContext; - class Decl; - -namespace idx { - class Program; - class EntityImpl; - -/// \brief A ASTContext-independent way to refer to declarations. -/// -/// Entity is basically the link for declarations that are semantically the same -/// in multiple ASTContexts. A client will convert a Decl into an Entity and -/// later use that Entity to find the "same" Decl into another ASTContext. -/// Declarations that are semantically the same and visible across translation -/// units will be associated with the same Entity. -/// -/// An Entity may also refer to declarations that cannot be visible across -/// translation units, e.g. static functions with the same name in multiple -/// translation units will be associated with different Entities. -/// -/// Entities can be checked for equality but note that the same Program object -/// should be used when getting Entities. -/// -class Entity { - /// \brief Stores the Decl directly if it is not visible outside of its own - /// translation unit, otherwise it stores the associated EntityImpl. - llvm::PointerUnion<Decl *, EntityImpl *> Val; - - explicit Entity(Decl *D); - explicit Entity(EntityImpl *impl) : Val(impl) { } - friend class EntityGetter; - -public: - Entity() { } - - /// \brief Find the Decl that can be referred to by this entity. - Decl *getDecl(ASTContext &AST) const; - - /// \brief If this Entity represents a declaration that is internal to its - /// translation unit, getInternalDecl() returns it. - Decl *getInternalDecl() const { - assert(isInternalToTU() && "This Entity is not internal!"); - return Val.get<Decl *>(); - } - - /// \brief Get a printable name for debugging purpose. - std::string getPrintableName() const; - - /// \brief Get an Entity associated with the given Decl. - /// \returns invalid Entity if an Entity cannot refer to this Decl. - static Entity get(Decl *D, Program &Prog); - - /// \brief Get an Entity associated with a name in the global namespace. - static Entity get(StringRef Name, Program &Prog); - - /// \brief true if the Entity is not visible outside the trasnlation unit. - bool isInternalToTU() const { - assert(isValid() && "This Entity is not valid!"); - return Val.is<Decl *>(); - } - - bool isValid() const { return !Val.isNull(); } - bool isInvalid() const { return !isValid(); } - - void *getAsOpaquePtr() const { return Val.getOpaqueValue(); } - static Entity getFromOpaquePtr(void *Ptr) { - Entity Ent; - Ent.Val = llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue(Ptr); - return Ent; - } - - friend bool operator==(const Entity &LHS, const Entity &RHS) { - return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr(); - } - - // For use in a std::map. - friend bool operator < (const Entity &LHS, const Entity &RHS) { - return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr(); - } - - // For use in DenseMap/DenseSet. - static Entity getEmptyMarker() { - Entity Ent; - Ent.Val = - llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-1); - return Ent; - } - static Entity getTombstoneMarker() { - Entity Ent; - Ent.Val = - llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-2); - return Ent; - } -}; - -} // namespace idx - -} // namespace clang - -namespace llvm { -/// Define DenseMapInfo so that Entities can be used as keys in DenseMap and -/// DenseSets. -template<> -struct DenseMapInfo<clang::idx::Entity> { - static inline clang::idx::Entity getEmptyKey() { - return clang::idx::Entity::getEmptyMarker(); - } - - static inline clang::idx::Entity getTombstoneKey() { - return clang::idx::Entity::getTombstoneMarker(); - } - - static unsigned getHashValue(clang::idx::Entity); - - static inline bool - isEqual(clang::idx::Entity LHS, clang::idx::Entity RHS) { - return LHS == RHS; - } -}; - -template <> -struct isPodLike<clang::idx::Entity> { static const bool value = true; }; - -} // end namespace llvm - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/GlobalCallGraph.h b/contrib/llvm/tools/clang/include/clang/Index/GlobalCallGraph.h deleted file mode 100644 index 7ba1cce..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/GlobalCallGraph.h +++ /dev/null @@ -1,149 +0,0 @@ -//== GlobalCallGraph.h - Call graph building --------------------*- C++ -*--==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defined the CallGraph and CallGraphNode classes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_CALLGRAPH -#define LLVM_CLANG_INDEX_CALLGRAPH - -#include "clang/Index/ASTLocation.h" -#include "clang/Index/Entity.h" -#include "clang/Index/Program.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/STLExtras.h" -#include <vector> -#include <map> - -using namespace clang; - -namespace clang { -namespace idx { - -class CallGraphNode { - Entity F; - typedef std::pair<ASTLocation, CallGraphNode*> CallRecord; - std::vector<CallRecord> CalledFunctions; - -public: - CallGraphNode(Entity f) : F(f) {} - - typedef std::vector<CallRecord>::iterator iterator; - typedef std::vector<CallRecord>::const_iterator const_iterator; - - iterator begin() { return CalledFunctions.begin(); } - iterator end() { return CalledFunctions.end(); } - const_iterator begin() const { return CalledFunctions.begin(); } - const_iterator end() const { return CalledFunctions.end(); } - - void addCallee(ASTLocation L, CallGraphNode *Node) { - CalledFunctions.push_back(std::make_pair(L, Node)); - } - - bool hasCallee() const { return begin() != end(); } - - std::string getName() const { return F.getPrintableName(); } - - Decl *getDecl(ASTContext &Ctx) const { return F.getDecl(Ctx); } -}; - -class CallGraph { - /// Program manages all Entities. - Program &Prog; - - typedef std::map<Entity, CallGraphNode *> FunctionMapTy; - - /// FunctionMap owns all CallGraphNodes. - FunctionMapTy FunctionMap; - - /// CallerCtx maps a caller to its ASTContext. - llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx; - - /// Root node is the 'main' function or 0. - CallGraphNode *Root; - - /// ExternalCallingNode has edges to all external functions. - CallGraphNode *ExternalCallingNode; - -public: - CallGraph(Program &P); - ~CallGraph(); - - typedef FunctionMapTy::iterator iterator; - typedef FunctionMapTy::const_iterator const_iterator; - - iterator begin() { return FunctionMap.begin(); } - iterator end() { return FunctionMap.end(); } - const_iterator begin() const { return FunctionMap.begin(); } - const_iterator end() const { return FunctionMap.end(); } - - CallGraphNode *getRoot() { return Root; } - - CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; } - - void addTU(ASTContext &AST); - - Program &getProgram() { return Prog; } - - CallGraphNode *getOrInsertFunction(idx::Entity F); - - Decl *getDecl(CallGraphNode *Node); - - void print(raw_ostream &os); - void dump(); - - void ViewCallGraph() const; -}; - -}} // end clang idx namespace - -namespace llvm { - -template <> struct GraphTraits<clang::idx::CallGraph> { - typedef clang::idx::CallGraph GraphType; - typedef clang::idx::CallGraphNode NodeType; - - typedef std::pair<clang::idx::ASTLocation, NodeType*> CGNPairTy; - typedef std::pointer_to_unary_function<CGNPairTy, NodeType*> CGNDerefFun; - - typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType; - - static NodeType *getEntryNode(GraphType *CG) { - return CG->getExternalCallingNode(); - } - - static ChildIteratorType child_begin(NodeType *N) { - return map_iterator(N->begin(), CGNDerefFun(CGNDeref)); - } - static ChildIteratorType child_end(NodeType *N) { - return map_iterator(N->end(), CGNDerefFun(CGNDeref)); - } - - typedef std::pair<clang::idx::Entity, NodeType*> PairTy; - typedef std::pointer_to_unary_function<PairTy, NodeType*> DerefFun; - - typedef mapped_iterator<GraphType::const_iterator, DerefFun> nodes_iterator; - - static nodes_iterator nodes_begin(const GraphType &CG) { - return map_iterator(CG.begin(), DerefFun(CGDeref)); - } - static nodes_iterator nodes_end(const GraphType &CG) { - return map_iterator(CG.end(), DerefFun(CGDeref)); - } - - static NodeType *CGNDeref(CGNPairTy P) { return P.second; } - - static NodeType *CGDeref(PairTy P) { return P.second; } -}; - -} // end llvm namespace - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/GlobalSelector.h b/contrib/llvm/tools/clang/include/clang/Index/GlobalSelector.h deleted file mode 100644 index 9cd83a8..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/GlobalSelector.h +++ /dev/null @@ -1,100 +0,0 @@ -//===--- GlobalSelector.h - Cross-translation-unit "token" for selectors --===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// GlobalSelector is a ASTContext-independent way to refer to selectors. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_GLOBALSELECTOR_H -#define LLVM_CLANG_INDEX_GLOBALSELECTOR_H - -#include "llvm/ADT/DenseMap.h" -#include <string> - -namespace clang { - class ASTContext; - class Selector; - -namespace idx { - class Program; - -/// \brief A ASTContext-independent way to refer to selectors. -class GlobalSelector { - void *Val; - - explicit GlobalSelector(void *val) : Val(val) { } - -public: - GlobalSelector() : Val(0) { } - - /// \brief Get the ASTContext-specific selector. - Selector getSelector(ASTContext &AST) const; - - bool isValid() const { return Val != 0; } - bool isInvalid() const { return !isValid(); } - - /// \brief Get a printable name for debugging purpose. - std::string getPrintableName() const; - - /// \brief Get a GlobalSelector for the ASTContext-specific selector. - static GlobalSelector get(Selector Sel, Program &Prog); - - void *getAsOpaquePtr() const { return Val; } - - static GlobalSelector getFromOpaquePtr(void *Ptr) { - return GlobalSelector(Ptr); - } - - friend bool operator==(const GlobalSelector &LHS, const GlobalSelector &RHS) { - return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr(); - } - - // For use in a std::map. - friend bool operator< (const GlobalSelector &LHS, const GlobalSelector &RHS) { - return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr(); - } - - // For use in DenseMap/DenseSet. - static GlobalSelector getEmptyMarker() { return GlobalSelector((void*)-1); } - static GlobalSelector getTombstoneMarker() { - return GlobalSelector((void*)-2); - } -}; - -} // namespace idx - -} // namespace clang - -namespace llvm { -/// Define DenseMapInfo so that GlobalSelectors can be used as keys in DenseMap -/// and DenseSets. -template<> -struct DenseMapInfo<clang::idx::GlobalSelector> { - static inline clang::idx::GlobalSelector getEmptyKey() { - return clang::idx::GlobalSelector::getEmptyMarker(); - } - - static inline clang::idx::GlobalSelector getTombstoneKey() { - return clang::idx::GlobalSelector::getTombstoneMarker(); - } - - static unsigned getHashValue(clang::idx::GlobalSelector); - - static inline bool - isEqual(clang::idx::GlobalSelector LHS, clang::idx::GlobalSelector RHS) { - return LHS == RHS; - } -}; - -template <> -struct isPodLike<clang::idx::GlobalSelector> { static const bool value = true;}; - -} // end namespace llvm - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/Handlers.h b/contrib/llvm/tools/clang/include/clang/Index/Handlers.h deleted file mode 100644 index 1e017f8..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/Handlers.h +++ /dev/null @@ -1,82 +0,0 @@ -//===--- Handlers.h - Interfaces for receiving information ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Abstract interfaces for receiving information. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_HANDLERS_H -#define LLVM_CLANG_INDEX_HANDLERS_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/SmallVector.h" - -namespace clang { - -namespace idx { - class Entity; - class TranslationUnit; - class TULocation; - -/// \brief Abstract interface for receiving Entities. -class EntityHandler { -public: - typedef Entity receiving_type; - - virtual ~EntityHandler(); - virtual void Handle(Entity Ent) = 0; -}; - -/// \brief Abstract interface for receiving TranslationUnits. -class TranslationUnitHandler { -public: - typedef TranslationUnit* receiving_type; - - virtual ~TranslationUnitHandler(); - virtual void Handle(TranslationUnit *TU) = 0; -}; - -/// \brief Abstract interface for receiving TULocations. -class TULocationHandler { -public: - typedef TULocation receiving_type; - - virtual ~TULocationHandler(); - virtual void Handle(TULocation TULoc) = 0; -}; - -/// \brief Helper for the Handler classes. Stores the objects into a vector. -/// example: -/// @code -/// Storing<TranslationUnitHandler> TURes; -/// IndexProvider.GetTranslationUnitsFor(Entity, TURes); -/// for (Storing<TranslationUnitHandler>::iterator -/// I = TURes.begin(), E = TURes.end(); I != E; ++I) { .... -/// @endcode -template <typename handler_type> -class Storing : public handler_type { - typedef typename handler_type::receiving_type receiving_type; - typedef SmallVector<receiving_type, 8> StoreTy; - StoreTy Store; - -public: - virtual void Handle(receiving_type Obj) { - Store.push_back(Obj); - } - - typedef typename StoreTy::const_iterator iterator; - iterator begin() const { return Store.begin(); } - iterator end() const { return Store.end(); } -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/IndexProvider.h b/contrib/llvm/tools/clang/include/clang/Index/IndexProvider.h deleted file mode 100644 index 187dd93..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/IndexProvider.h +++ /dev/null @@ -1,38 +0,0 @@ -//===--- IndexProvider.h - Maps information to translation units -*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Maps information to TranslationUnits. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_INDEXPROVIDER_H -#define LLVM_CLANG_INDEX_INDEXPROVIDER_H - -namespace clang { - -namespace idx { - class Entity; - class TranslationUnitHandler; - class GlobalSelector; - -/// \brief Maps information to TranslationUnits. -class IndexProvider { -public: - virtual ~IndexProvider(); - virtual void GetTranslationUnitsFor(Entity Ent, - TranslationUnitHandler &Handler) = 0; - virtual void GetTranslationUnitsFor(GlobalSelector Sel, - TranslationUnitHandler &Handler) = 0; -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/Indexer.h b/contrib/llvm/tools/clang/include/clang/Index/Indexer.h deleted file mode 100644 index 96c585d..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/Indexer.h +++ /dev/null @@ -1,71 +0,0 @@ -//===--- Indexer.h - IndexProvider implementation ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// IndexProvider implementation. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_INDEXER_H -#define LLVM_CLANG_INDEX_INDEXER_H - -#include "clang/Index/IndexProvider.h" -#include "clang/Index/Entity.h" -#include "clang/Index/GlobalSelector.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/DenseMap.h" -#include <map> - -namespace clang { - class ASTContext; - class FunctionDecl; - -namespace idx { - class Program; - class TranslationUnit; - -/// \brief Maps information to TranslationUnits. -class Indexer : public IndexProvider { -public: - typedef llvm::SmallPtrSet<TranslationUnit *, 4> TUSetTy; - typedef llvm::DenseMap<ASTContext *, TranslationUnit *> CtxTUMapTy; - typedef std::map<Entity, TUSetTy> MapTy; - typedef std::map<GlobalSelector, TUSetTy> SelMapTy; - typedef std::map<Entity, std::pair<FunctionDecl*,TranslationUnit*> > DefMapTy; - - explicit Indexer(Program &prog) : - Prog(prog) { } - - Program &getProgram() const { return Prog; } - - /// \brief Find all Entities and map them to the given translation unit. - void IndexAST(TranslationUnit *TU); - - virtual void GetTranslationUnitsFor(Entity Ent, - TranslationUnitHandler &Handler); - virtual void GetTranslationUnitsFor(GlobalSelector Sel, - TranslationUnitHandler &Handler); - - std::pair<FunctionDecl*, TranslationUnit*> getDefinitionFor(Entity Ent); - -private: - Program &Prog; - - MapTy Map; - // Map a function Entity to the its definition. - DefMapTy DefMap; - - CtxTUMapTy CtxTUMap; - SelMapTy SelMap; -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/Program.h b/contrib/llvm/tools/clang/include/clang/Index/Program.h deleted file mode 100644 index 8039192..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/Program.h +++ /dev/null @@ -1,45 +0,0 @@ -//===--- Program.h - Cross-translation unit information ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the idx::Program interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_PROGRAM_H -#define LLVM_CLANG_INDEX_PROGRAM_H - -namespace clang { - class ASTContext; - -namespace idx { - class EntityHandler; - -/// \brief Top level object that owns and maintains information -/// that is common across translation units. -class Program { - void *Impl; - - Program(const Program&); // do not implement - Program &operator=(const Program &); // do not implement - friend class Entity; - friend class GlobalSelector; - -public: - Program(); - ~Program(); - - /// \brief Traverses the AST and passes all the entities to the Handler. - void FindEntities(ASTContext &Ctx, EntityHandler &Handler); -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/STLExtras.h b/contrib/llvm/tools/clang/include/clang/Index/STLExtras.h deleted file mode 100644 index a3693c6..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/STLExtras.h +++ /dev/null @@ -1,63 +0,0 @@ -//===--- STLExtras.h - Helper STL related templates -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Helper templates for using with the STL. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_STLEXTRAS_H -#define LLVM_CLANG_INDEX_STLEXTRAS_H - -namespace clang { - -namespace idx { - -/// \brief Wraps an iterator whose value_type is a pair, and provides -/// pair's second object as the value. -template <typename iter_type> -class pair_value_iterator { - iter_type I; - -public: - typedef typename iter_type::value_type::second_type value_type; - typedef value_type& reference; - typedef value_type* pointer; - typedef typename iter_type::iterator_category iterator_category; - typedef typename iter_type::difference_type difference_type; - - pair_value_iterator() { } - pair_value_iterator(iter_type i) : I(i) { } - - reference operator*() const { return I->second; } - pointer operator->() const { return &I->second; } - - pair_value_iterator& operator++() { - ++I; - return *this; - } - - pair_value_iterator operator++(int) { - pair_value_iterator tmp(*this); - ++(*this); - return tmp; - } - - friend bool operator==(pair_value_iterator L, pair_value_iterator R) { - return L.I == R.I; - } - friend bool operator!=(pair_value_iterator L, pair_value_iterator R) { - return L.I != R.I; - } -}; - -} // end idx namespace - -} // end clang namespace - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/SelectorMap.h b/contrib/llvm/tools/clang/include/clang/Index/SelectorMap.h deleted file mode 100644 index be01702..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/SelectorMap.h +++ /dev/null @@ -1,57 +0,0 @@ -//===--- SelectorMap.h - Maps selectors to methods and messages -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// SelectorMap creates a mapping from selectors to ObjC method declarations -// and ObjC message expressions. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_SELECTORMAP_H -#define LLVM_CLANG_INDEX_SELECTORMAP_H - -#include "clang/Index/ASTLocation.h" -#include "clang/Index/STLExtras.h" -#include "clang/Basic/IdentifierTable.h" -#include <map> - -namespace clang { - class ASTContext; - class ObjCMethodDecl; - -namespace idx { - -/// \brief Maps NamedDecls with the ASTLocations that reference them. -/// -/// References are mapped and retrieved using the canonical decls. -class SelectorMap { -public: - explicit SelectorMap(ASTContext &Ctx); - - typedef std::multimap<Selector, ObjCMethodDecl *> SelMethMapTy; - typedef std::multimap<Selector, ASTLocation> SelRefMapTy; - - typedef pair_value_iterator<SelMethMapTy::iterator> method_iterator; - typedef pair_value_iterator<SelRefMapTy::iterator> astlocation_iterator; - - method_iterator methods_begin(Selector Sel) const; - method_iterator methods_end(Selector Sel) const; - - astlocation_iterator refs_begin(Selector Sel) const; - astlocation_iterator refs_end(Selector Sel) const; - -private: - mutable SelMethMapTy SelMethMap; - mutable SelRefMapTy SelRefMap; -}; - -} // end idx namespace - -} // end clang namespace - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h b/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h deleted file mode 100644 index ba5d48d..0000000 --- a/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h +++ /dev/null @@ -1,41 +0,0 @@ -//===--- TranslationUnit.h - Interface for a translation unit ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Abstract interface for a translation unit. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_TRANSLATIONUNIT_H -#define LLVM_CLANG_INDEX_TRANSLATIONUNIT_H - -namespace clang { - class ASTContext; - class DiagnosticsEngine; - class Preprocessor; - -namespace idx { - class DeclReferenceMap; - class SelectorMap; - -/// \brief Abstract interface for a translation unit. -class TranslationUnit { -public: - virtual ~TranslationUnit(); - virtual ASTContext &getASTContext() = 0; - virtual Preprocessor &getPreprocessor() = 0; - virtual DiagnosticsEngine &getDiagnostic() = 0; - virtual DeclReferenceMap &getDeclReferenceMap() = 0; - virtual SelectorMap &getSelectorMap() = 0; -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h index dff8510..a2bb1b3 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h @@ -15,7 +15,6 @@ #define LLVM_CLANG_PARSE_PARSER_H #include "clang/Basic/Specifiers.h" -#include "clang/Basic/DelayedCleanupPool.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Sema/Sema.h" @@ -192,9 +191,9 @@ class Parser : public CodeCompletionHandler { /// Factory object for creating AttributeList objects. AttributeFactory AttrFactory; - /// \brief Gathers and cleans up objects when parsing of a top-level - /// declaration is finished. - DelayedCleanupPool TopLevelDeclCleanupPool; + /// \brief Gathers and cleans up TemplateIdAnnotations when parsing of a + /// top-level declaration is finished. + SmallVector<TemplateIdAnnotation *, 16> TemplateIds; IdentifierInfo *getSEHExceptKeyword(); @@ -568,9 +567,7 @@ private: const char *&PrevSpec, unsigned &DiagID, bool &isInvalid); - /// \brief Get the TemplateIdAnnotation from the token and put it in the - /// cleanup pool so that it gets destroyed when parsing the current top level - /// declaration is finished. + /// \brief Get the TemplateIdAnnotation from the token. TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok); /// TentativeParsingAction - An object that is used as a kind of "tentative @@ -858,7 +855,7 @@ private: /// argument (C++ [class.mem]p2). struct LateParsedMethodDeclaration : public LateParsedDeclaration { explicit LateParsedMethodDeclaration(Parser *P, Decl *M) - : Self(P), Method(M), TemplateScope(false) { } + : Self(P), Method(M), TemplateScope(false), ExceptionSpecTokens(0) { } virtual void ParseLexedMethodDeclarations(); @@ -878,6 +875,10 @@ private: /// method will be stored so that they can be reintroduced into /// scope at the appropriate times. SmallVector<LateParsedDefaultArgument, 8> DefaultArgs; + + /// \brief The set of tokens that make up an exception-specification that + /// has not yet been parsed. + CachedTokens *ExceptionSpecTokens; }; /// LateParsedMemberInitializer - An initializer for a non-static class data @@ -1420,11 +1421,13 @@ private: // C++ 15: C++ Throw Expression ExprResult ParseThrowExpression(); - ExceptionSpecificationType MaybeParseExceptionSpecification( + ExceptionSpecificationType tryParseExceptionSpecification( + bool Delayed, SourceRange &SpecificationRange, SmallVectorImpl<ParsedType> &DynamicExceptions, SmallVectorImpl<SourceRange> &DynamicExceptionRanges, - ExprResult &NoexceptExpr); + ExprResult &NoexceptExpr, + CachedTokens *&ExceptionSpecTokens); // EndLoc is filled with the location of the last token of the specification. ExceptionSpecificationType ParseDynamicExceptionSpecification( @@ -1517,42 +1520,40 @@ private: //===--------------------------------------------------------------------===// // C99 6.8: Statements and Blocks. - StmtResult ParseStatement(SourceLocation *TrailingElseLoc = NULL) { + StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0) { StmtVector Stmts(Actions); return ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc); } - StmtResult ParseStatementOrDeclaration(StmtVector& Stmts, + StmtResult ParseStatementOrDeclaration(StmtVector &Stmts, + bool OnlyStatement, + SourceLocation *TrailingElseLoc = 0); + StmtResult ParseStatementOrDeclarationAfterAttributes( + StmtVector &Stmts, bool OnlyStatement, - SourceLocation *TrailingElseLoc = NULL); - StmtResult ParseExprStatement(ParsedAttributes &Attrs); - StmtResult ParseLabeledStatement(ParsedAttributes &Attr); - StmtResult ParseCaseStatement(ParsedAttributes &Attr, - bool MissingCase = false, + SourceLocation *TrailingElseLoc, + ParsedAttributesWithRange &Attrs); + StmtResult ParseExprStatement(); + StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs); + StmtResult ParseCaseStatement(bool MissingCase = false, ExprResult Expr = ExprResult()); - StmtResult ParseDefaultStatement(ParsedAttributes &Attr); - StmtResult ParseCompoundStatement(ParsedAttributes &Attr, - bool isStmtExpr = false); - StmtResult ParseCompoundStatement(ParsedAttributes &Attr, - bool isStmtExpr, + StmtResult ParseDefaultStatement(); + StmtResult ParseCompoundStatement(bool isStmtExpr = false); + StmtResult ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags); StmtResult ParseCompoundStatementBody(bool isStmtExpr = false); bool ParseParenExprOrCondition(ExprResult &ExprResult, Decl *&DeclResult, SourceLocation Loc, bool ConvertToBoolean); - StmtResult ParseIfStatement(ParsedAttributes &Attr, - SourceLocation *TrailingElseLoc); - StmtResult ParseSwitchStatement(ParsedAttributes &Attr, - SourceLocation *TrailingElseLoc); - StmtResult ParseWhileStatement(ParsedAttributes &Attr, - SourceLocation *TrailingElseLoc); - StmtResult ParseDoStatement(ParsedAttributes &Attr); - StmtResult ParseForStatement(ParsedAttributes &Attr, - SourceLocation *TrailingElseLoc); - StmtResult ParseGotoStatement(ParsedAttributes &Attr); - StmtResult ParseContinueStatement(ParsedAttributes &Attr); - StmtResult ParseBreakStatement(ParsedAttributes &Attr); - StmtResult ParseReturnStatement(ParsedAttributes &Attr); + StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc); + StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc); + StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc); + StmtResult ParseDoStatement(); + StmtResult ParseForStatement(SourceLocation *TrailingElseLoc); + StmtResult ParseGotoStatement(); + StmtResult ParseContinueStatement(); + StmtResult ParseBreakStatement(); + StmtResult ParseReturnStatement(); StmtResult ParseAsmStatement(bool &msAsm); StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc); @@ -1586,7 +1587,7 @@ private: /// \brief The behavior of this __if_exists or __if_not_exists block /// should. IfExistsBehavior Behavior; -}; + }; bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result); void ParseMicrosoftIfExistsStatement(StmtVector &Stmts); @@ -1602,14 +1603,14 @@ private: //===--------------------------------------------------------------------===// // C++ 6: Statements and Blocks - StmtResult ParseCXXTryBlock(ParsedAttributes &Attr); + StmtResult ParseCXXTryBlock(); StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc); StmtResult ParseCXXCatchBlock(); //===--------------------------------------------------------------------===// // MS: SEH Statements and Blocks - StmtResult ParseSEHTryBlock(ParsedAttributes &Attr); + StmtResult ParseSEHTryBlock(); StmtResult ParseSEHTryBlockCommon(SourceLocation Loc); StmtResult ParseSEHExceptBlock(SourceLocation Loc); StmtResult ParseSEHFinallyBlock(SourceLocation Loc); @@ -1883,6 +1884,7 @@ private: void ProhibitAttributes(ParsedAttributesWithRange &attrs) { if (!attrs.Range.isValid()) return; DiagnoseProhibitedAttributes(attrs); + attrs.clear(); } void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs); @@ -1967,7 +1969,7 @@ private: void ParseTypeofSpecifier(DeclSpec &DS); SourceLocation ParseDecltypeSpecifier(DeclSpec &DS); - void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS, + void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS, SourceLocation StartLoc, SourceLocation EndLoc); void ParseUnderlyingTypeSpecifier(DeclSpec &DS); @@ -2106,8 +2108,8 @@ private: ParsingDeclRAIIObject *DiagsFromTParams = 0); void ParseConstructorInitializer(Decl *ConstructorDecl); MemInitResult ParseMemInitializer(Decl *ConstructorDecl); - void HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo, - Decl *ThisDecl); + void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, + Decl *ThisDecl); //===--------------------------------------------------------------------===// // C++ 10: Derived classes [class.derived] diff --git a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h index 67fd393..2f3dda4 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h @@ -1150,6 +1150,10 @@ struct DeclaratorChunk { /// \brief Pointer to the expression in the noexcept-specifier of this /// function, if it has one. Expr *NoexceptExpr; + + /// \brief Pointer to the cached tokens for an exception-specification + /// that has not yet been parsed. + CachedTokens *ExceptionSpecTokens; }; /// TrailingReturnType - If this isn't null, it's the trailing return type @@ -1172,6 +1176,8 @@ struct DeclaratorChunk { delete[] ArgInfo; if (getExceptionSpecType() == EST_Dynamic) delete[] Exceptions; + else if (getExceptionSpecType() == EST_Delayed) + delete ExceptionSpecTokens; } /// isKNRPrototype - Return true if this is a K&R style identifier list, @@ -1347,6 +1353,7 @@ struct DeclaratorChunk { SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, + CachedTokens *ExceptionSpecTokens, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h b/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h index 3ff0459..c1b4710 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h @@ -178,8 +178,11 @@ namespace clang { ParsedTemplateArgument *getTemplateArgs() { return reinterpret_cast<ParsedTemplateArgument *>(this + 1); } - - static TemplateIdAnnotation* Allocate(unsigned NumArgs) { + + /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and + /// appends it to List. + static TemplateIdAnnotation * + Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) { TemplateIdAnnotation *TemplateId = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + sizeof(ParsedTemplateArgument) * NumArgs); @@ -193,6 +196,7 @@ namespace clang { for (unsigned I = 0; I != NumArgs; ++I) new (TemplateArgs + I) ParsedTemplateArgument(); + List.push_back(TemplateId); return TemplateId; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Scope.h b/contrib/llvm/tools/clang/include/clang/Sema/Scope.h index e9aa173..48f5417 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Scope.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Scope.h @@ -81,13 +81,8 @@ public: /// SwitchScope - This is a scope that corresponds to a switch statement. SwitchScope = 0x800, - /// ThisScope - This is the scope of a struct/union/class definition, - /// outside of any member function definition, where 'this' is nonetheless - /// usable. - ThisScope = 0x1000, - /// TryScope - This is the scope of a C++ try statement. - TryScope = 0x2000 + TryScope = 0x1000 }; private: /// The parent scope for this scope. This is null for the translation-unit diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h index 31c410a..8ac7c3e 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h @@ -446,11 +446,13 @@ public: Sema &S; DeclContext *SavedContext; ProcessingContextState SavedContextState; - + QualType SavedCXXThisTypeOverride; + public: ContextRAII(Sema &S, DeclContext *ContextToPush) : S(S), SavedContext(S.CurContext), - SavedContextState(S.DelayedDiagnostics.pushContext()) + SavedContextState(S.DelayedDiagnostics.pushContext()), + SavedCXXThisTypeOverride(S.CXXThisTypeOverride) { assert(ContextToPush && "pushing null context"); S.CurContext = ContextToPush; @@ -460,6 +462,7 @@ public: if (!SavedContext) return; S.CurContext = SavedContext; S.DelayedDiagnostics.popContext(SavedContextState); + S.CXXThisTypeOverride = SavedCXXThisTypeOverride; SavedContext = 0; } @@ -646,7 +649,7 @@ public: /// A stack of expression evaluation contexts. SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; - + /// SpecialMemberOverloadResult - The overloading result for a special member /// function. /// @@ -898,11 +901,15 @@ public: TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, TypeSourceInfo *ReturnTypeInfo); + /// \brief Package the given type and TSI into a ParsedType. ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo); DeclarationNameInfo GetNameForDeclarator(Declarator &D); DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name); static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo = 0); + CanThrowResult canThrow(const Expr *E); + const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc, + const FunctionProtoType *FPT); bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range); bool CheckDistantExceptionSpec(QualType T); bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New); @@ -1974,6 +1981,10 @@ public: bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC); bool CheckNoReturnAttr(const AttributeList &attr); + /// \brief Stmt attributes - this routine is the top level dispatcher. + StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs, + SourceRange Range); + void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method, bool &IncompleteImpl, unsigned DiagID); void WarnConflictingTypedMethods(ObjCMethodDecl *Method, @@ -2251,6 +2262,9 @@ public: StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt); + StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, const AttrVec &Attrs, + Stmt *SubStmt); + StmtResult ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar, Stmt *ThenVal, @@ -3039,7 +3053,7 @@ public: /// implicitly-declared special member functions. class ImplicitExceptionSpecification { // Pointer to allow copying - ASTContext *Context; + Sema *Self; // We order exception specifications thus: // noexcept is the most restrictive, but is only used in C++0x. // throw() comes next. @@ -3063,9 +3077,9 @@ public: } public: - explicit ImplicitExceptionSpecification(ASTContext &Context) - : Context(&Context), ComputedEST(EST_BasicNoexcept) { - if (!Context.getLangOpts().CPlusPlus0x) + explicit ImplicitExceptionSpecification(Sema &Self) + : Self(&Self), ComputedEST(EST_BasicNoexcept) { + if (!Self.Context.getLangOpts().CPlusPlus0x) ComputedEST = EST_DynamicNone; } @@ -3083,7 +3097,7 @@ public: const QualType *data() const { return Exceptions.data(); } /// \brief Integrate another called method into the collected data. - void CalledDecl(CXXMethodDecl *Method); + void CalledDecl(SourceLocation CallLoc, CXXMethodDecl *Method); /// \brief Integrate an invoked expression into the collected data. void CalledExpr(Expr *E); @@ -3135,6 +3149,25 @@ public: ImplicitExceptionSpecification ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl); + /// \brief Check the given exception-specification and update the + /// extended prototype information with the results. + void checkExceptionSpecification(ExceptionSpecificationType EST, + ArrayRef<ParsedType> DynamicExceptions, + ArrayRef<SourceRange> DynamicExceptionRanges, + Expr *NoexceptExpr, + llvm::SmallVectorImpl<QualType> &Exceptions, + FunctionProtoType::ExtProtoInfo &EPI); + + /// \brief Add an exception-specification to the given member function + /// (or member function template). The exception-specification was parsed + /// after the method itself was declared. + void actOnDelayedExceptionSpecification(Decl *Method, + ExceptionSpecificationType EST, + SourceRange SpecificationRange, + ArrayRef<ParsedType> DynamicExceptions, + ArrayRef<SourceRange> DynamicExceptionRanges, + Expr *NoexceptExpr); + /// \brief Determine if a special member function should have a deleted /// definition when it is defaulted. bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, @@ -3240,6 +3273,22 @@ public: /// special member function. bool isImplicitlyDeleted(FunctionDecl *FD); + /// \brief Check whether 'this' shows up in the type of a static member + /// function after the (naturally empty) cv-qualifier-seq would be. + /// + /// \returns true if an error occurred. + bool checkThisInStaticMemberFunctionType(CXXMethodDecl *Method); + + /// \brief Whether this' shows up in the exception specification of a static + /// member function. + bool checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method); + + /// \brief Check whether 'this' shows up in the attributes of the given + /// static member function. + /// + /// \returns true if an error occurred. + bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method); + /// MaybeBindToTemporary - If the passed in expression has a record type with /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise /// it simply returns the passed in expression. @@ -3321,6 +3370,29 @@ public: /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. QualType getCurrentThisType(); + /// \brief When non-NULL, the C++ 'this' expression is allowed despite the + /// current context not being a non-static member function. In such cases, + /// this provides the type used for 'this'. + QualType CXXThisTypeOverride; + + /// \brief RAII object used to temporarily allow the C++ 'this' expression + /// to be used, with the given qualifiers on the current class type. + class CXXThisScopeRAII { + Sema &S; + QualType OldCXXThisTypeOverride; + bool Enabled; + + public: + /// \brief Introduce a new scope where 'this' may be allowed (when enabled), + /// using the given declaration (which is either a class template or a + /// class) along with the given qualifiers. + /// along with the qualifiers placed on '*this'. + CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals, + bool Enabled = true); + + ~CXXThisScopeRAII(); + }; + /// \brief Make sure the value of 'this' is actually available in the current /// context, if it is a potentially evaluated context. /// @@ -3330,6 +3402,11 @@ public: /// capture list. void CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false); + /// \brief Determine whether the given type is the type of *this that is used + /// outside of the body of a member function for a type that is currently + /// being defined. + bool isThisOutsideMemberFunctionBody(QualType BaseType); + /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); @@ -5120,7 +5197,11 @@ public: /// We are checking the validity of a default template argument that /// has been used when naming a template-id. - DefaultTemplateArgumentChecking + DefaultTemplateArgumentChecking, + + /// We are instantiating the exception specification for a function + /// template which was deferred until it was needed. + ExceptionSpecInstantiation } Kind; /// \brief The point of instantiation within the source code. @@ -5168,6 +5249,7 @@ public: switch (X.Kind) { case TemplateInstantiation: + case ExceptionSpecInstantiation: return true; case PriorTemplateArgumentSubstitution: @@ -5285,6 +5367,13 @@ public: Decl *Entity, SourceRange InstantiationRange = SourceRange()); + struct ExceptionSpecification {}; + /// \brief Note that we are instantiating an exception specification + /// of a function template. + InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + FunctionDecl *Entity, ExceptionSpecification, + SourceRange InstantiationRange = SourceRange()); + /// \brief Note that we are instantiating a default argument in a /// template-id. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, @@ -5474,7 +5563,9 @@ public: TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, - DeclarationName Entity); + DeclarationName Entity, + CXXRecordDecl *ThisContext, + unsigned ThisTypeQuals); ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, @@ -5582,6 +5673,8 @@ public: TemplateArgumentListInfo &Result, const MultiLevelTemplateArgumentList &TemplateArgs); + void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, + FunctionDecl *Function); void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, bool Recursive = false, @@ -6463,11 +6556,11 @@ public: /// and reports the appropriate diagnostics. Returns false on success. /// Can optionally return the value of the expression. ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, - PartialDiagnostic Diag, + const PartialDiagnostic &Diag, bool AllowFold, - PartialDiagnostic FoldDiag); + const PartialDiagnostic &FoldDiag); ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, - PartialDiagnostic Diag, + const PartialDiagnostic &Diag, bool AllowFold = true) { return VerifyIntegerConstantExpression(E, Result, Diag, AllowFold, PDiag(0)); diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h index 4591630..f9bb892 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h @@ -964,6 +964,8 @@ namespace clang { STMT_DEFAULT, /// \brief A LabelStmt record. STMT_LABEL, + /// \brief An AttributedStmt record. + STMT_ATTRIBUTED, /// \brief An IfStmt record. STMT_IF, /// \brief A SwitchStmt record. diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h index 9baaf4b..a9d0fc3 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h @@ -170,6 +170,9 @@ class ReadMethodPoolVisitor; namespace reader { class ASTIdentifierLookupTrait; + /// \brief The on-disk hash table used for the DeclContext's Name lookup table. + typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait> + ASTDeclContextNameLookupTable; } } // end namespace serialization @@ -323,7 +326,9 @@ private: // TU, and when we read those update records, the actual context will not // be available yet (unless it's the TU), so have this pending map using the // ID as a key. It will be realized when the context is actually loaded. - typedef SmallVector<std::pair<void *, ModuleFile*>, 1> DeclContextVisibleUpdates; + typedef + SmallVector<std::pair<serialization::reader::ASTDeclContextNameLookupTable *, + ModuleFile*>, 1> DeclContextVisibleUpdates; typedef llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates> DeclContextVisibleUpdatesPending; @@ -1467,7 +1472,7 @@ public: llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos); /// \brief Load all external visible decls in the given DeclContext. - void completeVisibleDeclsMap(DeclContext *DC); + void completeVisibleDeclsMap(const DeclContext *DC); /// \brief Retrieve the AST context that this AST reader supplements. ASTContext &getContext() { return Context; } diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h index 4c62385..e693f17 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h @@ -76,6 +76,7 @@ public: typedef SmallVectorImpl<uint64_t> RecordDataImpl; friend class ASTDeclWriter; + friend class ASTStmtWriter; private: /// \brief Map that provides the ID numbers of each type within the /// output stream, plus those deserialized from a chained PCH. diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/Module.h b/contrib/llvm/tools/clang/include/clang/Serialization/Module.h index 4c93c33..786ecd3 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/Module.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/Module.h @@ -27,9 +27,14 @@ namespace clang { class DeclContext; class Module; - +template<typename Info> class OnDiskChainedHashTable; + namespace serialization { +namespace reader { + class ASTDeclContextNameLookupTrait; +} + /// \brief Specifies the kind of module that has been loaded. enum ModuleKind { MK_Module, ///< File is a module proper. @@ -43,7 +48,8 @@ struct DeclContextInfo { DeclContextInfo() : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {} - void *NameLookupTableData; // an ASTDeclContextNameLookupTable. + OnDiskChainedHashTable<reader::ASTDeclContextNameLookupTrait> + *NameLookupTableData; // an ASTDeclContextNameLookupTable. const KindDeclIDPair *LexicalDecls; unsigned NumLexicalDecls; }; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index 3cbecf7..d01644ba 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -22,11 +22,6 @@ namespace clang { -namespace idx { - class Indexer; - class TranslationUnit; -} - namespace ento { class CheckerManager; @@ -46,11 +41,6 @@ class AnalysisManager : public BugReporterData { CheckerManager *CheckerMgr; - /// \brief Provide function definitions in other translation units. This is - /// NULL if we don't have multiple translation units. AnalysisManager does - /// not own the Indexer. - idx::Indexer *Idxer; - enum AnalysisScope { ScopeTU, ScopeDecl } AScope; /// \brief The maximum number of exploded nodes the analyzer will generate. @@ -99,7 +89,6 @@ public: StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, - idx::Indexer *idxer, unsigned maxnodes, unsigned maxvisit, bool vizdot, bool vizubi, AnalysisPurgeMode purge, bool eager, bool trim, @@ -137,8 +126,6 @@ public: CheckerManager *getCheckerManager() const { return CheckerMgr; } - idx::Indexer *getIndexer() const { return Idxer; } - virtual ASTContext &getASTContext() { return Ctx; } @@ -186,10 +173,6 @@ public: bool shouldInlineCall() const { return (IPAMode == Inlining); } - bool hasIndexer() const { return Idxer != 0; } - - AnalysisDeclContext *getAnalysisDeclContextInAnotherTU(const Decl *D); - CFG *getCFG(Decl const *D) { return AnaCtxMgr.getContext(D)->getCFG(); } diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index ed01db2..ce3eb1d 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -425,10 +425,12 @@ class MemRegionVal : public Loc { public: explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {} + /// \brief Get the underlining region. const MemRegion* getRegion() const { return static_cast<const MemRegion*>(Data); } + /// \brief Get the underlining region and strip casts. const MemRegion* stripCasts() const; template <typename REGION> diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h index 3430320..625c8ec 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h @@ -33,22 +33,21 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/YAMLParser.h" #include <string> #include <vector> -namespace llvm { -class MemoryBuffer; -} // end namespace llvm - namespace clang { namespace tooling { /// \brief Specifies the working directory and command of a compilation. struct CompileCommand { CompileCommand() {} - CompileCommand(StringRef Directory, ArrayRef<std::string> CommandLine) - : Directory(Directory), CommandLine(CommandLine) {} + CompileCommand(Twine Directory, ArrayRef<std::string> CommandLine) + : Directory(Directory.str()), CommandLine(CommandLine) {} /// \brief The working directory the command was executed from. std::string Directory; @@ -95,6 +94,59 @@ public: StringRef FilePath) const = 0; }; +/// \brief A compilation database that returns a single compile command line. +/// +/// Useful when we want a tool to behave more like a compiler invocation. +class FixedCompilationDatabase : public CompilationDatabase { +public: + /// \brief Creates a FixedCompilationDatabase from the arguments after "--". + /// + /// Parses the given command line for "--". If "--" is found, the rest of + /// the arguments will make up the command line in the returned + /// FixedCompilationDatabase. + /// The arguments after "--" must not include positional parameters or the + /// argv[0] of the tool. Those will be added by the FixedCompilationDatabase + /// when a CompileCommand is requested. The argv[0] of the returned command + /// line will be "clang-tool". + /// + /// Returns NULL in case "--" is not found. + /// + /// The argument list is meant to be compatible with normal llvm command line + /// parsing in main methods. + /// int main(int argc, char **argv) { + /// llvm::OwningPtr<FixedCompilationDatabase> Compilations( + /// FixedCompilationDatabase::loadFromCommandLine(argc, argv)); + /// cl::ParseCommandLineOptions(argc, argv); + /// ... + /// } + /// + /// \param Argc The number of command line arguments - will be changed to + /// the number of arguments before "--", if "--" was found in the argument + /// list. + /// \param Argv Points to the command line arguments. + /// \param Directory The base directory used in the FixedCompilationDatabase. + static FixedCompilationDatabase *loadFromCommandLine(int &Argc, + const char **Argv, + Twine Directory = "."); + + /// \brief Constructs a compilation data base from a specified directory + /// and command line. + FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine); + + /// \brief Returns the given compile command. + /// + /// Will always return a vector with one entry that contains the directory + /// and command line specified at construction with "clang-tool" as argv[0] + /// and 'FilePath' as positional argument. + virtual std::vector<CompileCommand> getCompileCommands( + StringRef FilePath) const; + +private: + /// This is built up to contain a single entry vector to be returned from + /// getCompileCommands after adding the positional argument. + std::vector<CompileCommand> CompileCommands; +}; + /// \brief A JSON based compilation database. /// /// JSON compilation database files must contain a list of JSON objects which @@ -114,7 +166,6 @@ public: /// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS. class JSONCompilationDatabase : public CompilationDatabase { public: - /// \brief Loads a JSON compilation database from the specified file. /// /// Returns NULL and sets ErrorMessage if the database could not be @@ -139,7 +190,7 @@ public: private: /// \brief Constructs a JSON compilation database on a memory buffer. JSONCompilationDatabase(llvm::MemoryBuffer *Database) - : Database(Database) {} + : Database(Database), YAMLStream(Database->getBuffer(), SM) {} /// \brief Parses the database file and creates the index. /// @@ -147,14 +198,17 @@ private: /// failed. bool parse(std::string &ErrorMessage); - // Tuple (directory, commandline) where 'commandline' is a JSON escaped bash - // escaped command line. - typedef std::pair<StringRef, StringRef> CompileCommandRef; + // Tuple (directory, commandline) where 'commandline' pointing to the + // corresponding nodes in the YAML stream. + typedef std::pair<llvm::yaml::ScalarNode*, + llvm::yaml::ScalarNode*> CompileCommandRef; // Maps file paths to the compile command lines for that file. llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile; llvm::OwningPtr<llvm::MemoryBuffer> Database; + llvm::SourceMgr SM; + llvm::yaml::Stream YAMLStream; }; } // end namespace tooling diff --git a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp index acf5e0b..cb4d336 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -481,7 +481,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); // Builtin type for __objc_yes and __objc_no - ObjCBuiltinBoolTy = SignedCharTy; + ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ? + SignedCharTy : BoolTy); ObjCConstantStringType = QualType(); @@ -2193,6 +2194,8 @@ ASTContext::getFunctionType(QualType ResultTy, Size += EPI.NumExceptions * sizeof(QualType); else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { Size += sizeof(Expr*); + } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { + Size += 2 * sizeof(FunctionDecl*); } if (EPI.ConsumedArguments) Size += NumArgs * sizeof(bool); diff --git a/contrib/llvm/tools/clang/lib/AST/Decl.cpp b/contrib/llvm/tools/clang/lib/AST/Decl.cpp index 399f2e4..53032bc 100644 --- a/contrib/llvm/tools/clang/lib/AST/Decl.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Decl.cpp @@ -69,33 +69,25 @@ typedef NamedDecl::LinkageInfo LinkageInfo; namespace { /// Flags controlling the computation of linkage and visibility. struct LVFlags { - bool ConsiderGlobalVisibility; - bool ConsiderVisibilityAttributes; - bool ConsiderTemplateParameterTypes; + const bool ConsiderGlobalVisibility; + const bool ConsiderVisibilityAttributes; + const bool ConsiderTemplateParameterTypes; LVFlags() : ConsiderGlobalVisibility(true), ConsiderVisibilityAttributes(true), ConsiderTemplateParameterTypes(true) { } + LVFlags(bool Global, bool Attributes, bool Parameters) : + ConsiderGlobalVisibility(Global), + ConsiderVisibilityAttributes(Attributes), + ConsiderTemplateParameterTypes(Parameters) { + } + /// \brief Returns a set of flags that is only useful for computing the /// linkage, not the visibility, of a declaration. static LVFlags CreateOnlyDeclLinkage() { - LVFlags F; - F.ConsiderGlobalVisibility = false; - F.ConsiderVisibilityAttributes = false; - F.ConsiderTemplateParameterTypes = false; - return F; - } - - /// Returns a set of flags, otherwise based on these, which ignores - /// off all sources of visibility except template arguments. - LVFlags onlyTemplateVisibility() const { - LVFlags F = *this; - F.ConsiderGlobalVisibility = false; - F.ConsiderVisibilityAttributes = false; - F.ConsiderTemplateParameterTypes = false; - return F; + return LVFlags(false, false, false); } }; } // end anonymous namespace @@ -284,7 +276,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { if (F.ConsiderVisibilityAttributes) { if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) { LV.setVisibility(*Vis, true); - F.ConsiderGlobalVisibility = false; } else { // If we're declared in a namespace with a visibility attribute, // use that namespace's visibility, but don't call it explicit. @@ -295,7 +286,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { if (!ND) continue; if (llvm::Optional<Visibility> Vis = ND->getExplicitVisibility()) { LV.setVisibility(*Vis, true); - F.ConsiderGlobalVisibility = false; break; } } @@ -335,8 +325,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { LinkageInfo TypeLV = getLVForType(Var->getType()); if (TypeLV.linkage() != ExternalLinkage) return LinkageInfo::uniqueExternal(); - LV.mergeVisibilityWithMin(TypeLV.visibility(), - TypeLV.visibilityExplicit()); + LV.mergeVisibilityWithMin(TypeLV); } if (Var->getStorageClass() == SC_PrivateExtern) @@ -412,7 +401,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { = Function->getTemplateSpecializationInfo()) { if (shouldConsiderTemplateLV(Function, specInfo)) { LV.merge(getLVForDecl(specInfo->getTemplate(), - F.onlyTemplateVisibility())); + LVFlags::CreateOnlyDeclLinkage())); const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments; LV.mergeWithMin(getLVForTemplateArgumentList(templateArgs, F)); } @@ -436,7 +425,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { if (shouldConsiderTemplateLV(spec)) { // From the template. LV.merge(getLVForDecl(spec->getSpecializedTemplate(), - F.onlyTemplateVisibility())); + LVFlags::CreateOnlyDeclLinkage())); // The arguments at which the template was instantiated. const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs(); @@ -444,12 +433,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { } } - // Consider -fvisibility unless the type has C linkage. - if (F.ConsiderGlobalVisibility) - F.ConsiderGlobalVisibility = - (Context.getLangOpts().CPlusPlus && - !Tag->getDeclContext()->isExternCContext()); - // - an enumerator belonging to an enumeration with external linkage; } else if (isa<EnumConstantDecl>(D)) { LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()), F); @@ -501,21 +484,46 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { LinkageInfo LV; LV.mergeVisibility(D->getASTContext().getLangOpts().getVisibilityMode()); - // The flags we're going to use to compute the class's visibility. - LVFlags ClassF = F; - + bool DHasExplicitVisibility = false; // If we have an explicit visibility attribute, merge that in. if (F.ConsiderVisibilityAttributes) { if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) { LV.mergeVisibility(*Vis, true); - // Ignore global visibility later, but not this attribute. - F.ConsiderGlobalVisibility = false; + DHasExplicitVisibility = true; + } + } + // Ignore both global visibility and attributes when computing our + // parent's visibility if we already have an explicit one. + LVFlags ClassF = DHasExplicitVisibility ? + LVFlags::CreateOnlyDeclLinkage() : F; - // Ignore both global visibility and attributes when computing our - // parent's visibility. - ClassF = F.onlyTemplateVisibility(); + // If we're paying attention to global visibility, apply + // -finline-visibility-hidden if this is an inline method. + // + // Note that we do this before merging information about + // the class visibility. + if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { + TemplateSpecializationKind TSK = TSK_Undeclared; + if (FunctionTemplateSpecializationInfo *spec + = MD->getTemplateSpecializationInfo()) { + TSK = spec->getTemplateSpecializationKind(); + } else if (MemberSpecializationInfo *MSI = + MD->getMemberSpecializationInfo()) { + TSK = MSI->getTemplateSpecializationKind(); } + + const FunctionDecl *Def = 0; + // InlineVisibilityHidden only applies to definitions, and + // isInlined() only gives meaningful answers on definitions + // anyway. + if (TSK != TSK_ExplicitInstantiationDeclaration && + TSK != TSK_ExplicitInstantiationDefinition && + F.ConsiderGlobalVisibility && + !LV.visibilityExplicit() && + MD->getASTContext().getLangOpts().InlineVisibilityHidden && + MD->hasBody(Def) && Def->isInlined()) + LV.mergeVisibility(HiddenVisibility, true); } // Class members only have linkage if their class has external @@ -534,8 +542,6 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { if (MD->getType()->getLinkage() == UniqueExternalLinkage) return LinkageInfo::uniqueExternal(); - TemplateSpecializationKind TSK = TSK_Undeclared; - // If this is a method template specialization, use the linkage for // the template parameters and arguments. if (FunctionTemplateSpecializationInfo *spec @@ -547,29 +553,6 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { LV.merge(getLVForTemplateParameterList( spec->getTemplate()->getTemplateParameters())); } - - TSK = spec->getTemplateSpecializationKind(); - } else if (MemberSpecializationInfo *MSI = - MD->getMemberSpecializationInfo()) { - TSK = MSI->getTemplateSpecializationKind(); - } - - // If we're paying attention to global visibility, apply - // -finline-visibility-hidden if this is an inline method. - // - // Note that ConsiderGlobalVisibility doesn't yet have information - // about whether containing classes have visibility attributes, - // and that's intentional. - if (TSK != TSK_ExplicitInstantiationDeclaration && - TSK != TSK_ExplicitInstantiationDefinition && - F.ConsiderGlobalVisibility && - MD->getASTContext().getLangOpts().InlineVisibilityHidden) { - // InlineVisibilityHidden only applies to definitions, and - // isInlined() only gives meaningful answers on definitions - // anyway. - const FunctionDecl *Def = 0; - if (MD->hasBody(Def) && Def->isInlined()) - LV.setVisibility(HiddenVisibility); } // Note that in contrast to basically every other situation, we @@ -597,7 +580,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { if (TypeLV.linkage() != ExternalLinkage) LV.mergeLinkage(UniqueExternalLinkage); if (!LV.visibilityExplicit()) - LV.mergeVisibility(TypeLV.visibility(), TypeLV.visibilityExplicit()); + LV.mergeVisibility(TypeLV); } return LV; @@ -802,7 +785,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { LinkageInfo LV; if (Flags.ConsiderVisibilityAttributes) { if (llvm::Optional<Visibility> Vis = Function->getExplicitVisibility()) - LV.setVisibility(*Vis); + LV.setVisibility(*Vis, true); } if (const FunctionDecl *Prev = Function->getPreviousDecl()) { @@ -823,10 +806,10 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { LinkageInfo LV; if (Var->getStorageClass() == SC_PrivateExtern) - LV.setVisibility(HiddenVisibility); + LV.setVisibility(HiddenVisibility, true); else if (Flags.ConsiderVisibilityAttributes) { if (llvm::Optional<Visibility> Vis = Var->getExplicitVisibility()) - LV.setVisibility(*Vis); + LV.setVisibility(*Vis, true); } if (const VarDecl *Prev = Var->getPreviousDecl()) { diff --git a/contrib/llvm/tools/clang/lib/AST/Expr.cpp b/contrib/llvm/tools/clang/lib/AST/Expr.cpp index 868109e..fcde542 100644 --- a/contrib/llvm/tools/clang/lib/AST/Expr.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Expr.cpp @@ -1590,6 +1590,16 @@ void InitListExpr::setArrayFiller(Expr *filler) { inits[i] = filler; } +bool InitListExpr::isStringLiteralInit() const { + if (getNumInits() != 1) + return false; + const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(getType()); + if (!CAT || !CAT->getElementType()->isIntegerType()) + return false; + const Expr *Init = getInit(0)->IgnoreParenImpCasts(); + return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init); +} + SourceRange InitListExpr::getSourceRange() const { if (SyntacticForm) return SyntacticForm->getSourceRange(); @@ -1986,331 +1996,6 @@ QualType Expr::findBoundMemberType(const Expr *expr) { return QualType(); } -static Expr::CanThrowResult MergeCanThrow(Expr::CanThrowResult CT1, - Expr::CanThrowResult CT2) { - // CanThrowResult constants are ordered so that the maximum is the correct - // merge result. - return CT1 > CT2 ? CT1 : CT2; -} - -static Expr::CanThrowResult CanSubExprsThrow(ASTContext &C, const Expr *CE) { - Expr *E = const_cast<Expr*>(CE); - Expr::CanThrowResult R = Expr::CT_Cannot; - for (Expr::child_range I = E->children(); I && R != Expr::CT_Can; ++I) { - R = MergeCanThrow(R, cast<Expr>(*I)->CanThrow(C)); - } - return R; -} - -static Expr::CanThrowResult CanCalleeThrow(ASTContext &Ctx, const Expr *E, - const Decl *D, - bool NullThrows = true) { - if (!D) - return NullThrows ? Expr::CT_Can : Expr::CT_Cannot; - - // See if we can get a function type from the decl somehow. - const ValueDecl *VD = dyn_cast<ValueDecl>(D); - if (!VD) // If we have no clue what we're calling, assume the worst. - return Expr::CT_Can; - - // As an extension, we assume that __attribute__((nothrow)) functions don't - // throw. - if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) - return Expr::CT_Cannot; - - QualType T = VD->getType(); - const FunctionProtoType *FT; - if ((FT = T->getAs<FunctionProtoType>())) { - } else if (const PointerType *PT = T->getAs<PointerType>()) - FT = PT->getPointeeType()->getAs<FunctionProtoType>(); - else if (const ReferenceType *RT = T->getAs<ReferenceType>()) - FT = RT->getPointeeType()->getAs<FunctionProtoType>(); - else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) - FT = MT->getPointeeType()->getAs<FunctionProtoType>(); - else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) - FT = BT->getPointeeType()->getAs<FunctionProtoType>(); - - if (!FT) - return Expr::CT_Can; - - if (FT->getExceptionSpecType() == EST_Delayed) { - assert(isa<CXXConstructorDecl>(D) && - "only constructor exception specs can be unknown"); - Ctx.getDiagnostics().Report(E->getLocStart(), - diag::err_exception_spec_unknown) - << E->getSourceRange(); - return Expr::CT_Can; - } - - return FT->isNothrow(Ctx) ? Expr::CT_Cannot : Expr::CT_Can; -} - -static Expr::CanThrowResult CanDynamicCastThrow(const CXXDynamicCastExpr *DC) { - if (DC->isTypeDependent()) - return Expr::CT_Dependent; - - if (!DC->getTypeAsWritten()->isReferenceType()) - return Expr::CT_Cannot; - - if (DC->getSubExpr()->isTypeDependent()) - return Expr::CT_Dependent; - - return DC->getCastKind() == clang::CK_Dynamic? Expr::CT_Can : Expr::CT_Cannot; -} - -static Expr::CanThrowResult CanTypeidThrow(ASTContext &C, - const CXXTypeidExpr *DC) { - if (DC->isTypeOperand()) - return Expr::CT_Cannot; - - Expr *Op = DC->getExprOperand(); - if (Op->isTypeDependent()) - return Expr::CT_Dependent; - - const RecordType *RT = Op->getType()->getAs<RecordType>(); - if (!RT) - return Expr::CT_Cannot; - - if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) - return Expr::CT_Cannot; - - if (Op->Classify(C).isPRValue()) - return Expr::CT_Cannot; - - return Expr::CT_Can; -} - -Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const { - // C++ [expr.unary.noexcept]p3: - // [Can throw] if in a potentially-evaluated context the expression would - // contain: - switch (getStmtClass()) { - case CXXThrowExprClass: - // - a potentially evaluated throw-expression - return CT_Can; - - case CXXDynamicCastExprClass: { - // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), - // where T is a reference type, that requires a run-time check - CanThrowResult CT = CanDynamicCastThrow(cast<CXXDynamicCastExpr>(this)); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case CXXTypeidExprClass: - // - a potentially evaluated typeid expression applied to a glvalue - // expression whose type is a polymorphic class type - return CanTypeidThrow(C, cast<CXXTypeidExpr>(this)); - - // - a potentially evaluated call to a function, member function, function - // pointer, or member function pointer that does not have a non-throwing - // exception-specification - case CallExprClass: - case CXXMemberCallExprClass: - case CXXOperatorCallExprClass: - case UserDefinedLiteralClass: { - const CallExpr *CE = cast<CallExpr>(this); - CanThrowResult CT; - if (isTypeDependent()) - CT = CT_Dependent; - else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) - CT = CT_Cannot; - else - CT = CanCalleeThrow(C, this, CE->getCalleeDecl()); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case CXXConstructExprClass: - case CXXTemporaryObjectExprClass: { - CanThrowResult CT = CanCalleeThrow(C, this, - cast<CXXConstructExpr>(this)->getConstructor()); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case LambdaExprClass: { - const LambdaExpr *Lambda = cast<LambdaExpr>(this); - CanThrowResult CT = Expr::CT_Cannot; - for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(), - CapEnd = Lambda->capture_init_end(); - Cap != CapEnd; ++Cap) - CT = MergeCanThrow(CT, (*Cap)->CanThrow(C)); - return CT; - } - - case CXXNewExprClass: { - CanThrowResult CT; - if (isTypeDependent()) - CT = CT_Dependent; - else - CT = CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew()); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case CXXDeleteExprClass: { - CanThrowResult CT; - QualType DTy = cast<CXXDeleteExpr>(this)->getDestroyedType(); - if (DTy.isNull() || DTy->isDependentType()) { - CT = CT_Dependent; - } else { - CT = CanCalleeThrow(C, this, - cast<CXXDeleteExpr>(this)->getOperatorDelete()); - if (const RecordType *RT = DTy->getAs<RecordType>()) { - const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - CT = MergeCanThrow(CT, CanCalleeThrow(C, this, RD->getDestructor())); - } - if (CT == CT_Can) - return CT; - } - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case CXXBindTemporaryExprClass: { - // The bound temporary has to be destroyed again, which might throw. - CanThrowResult CT = CanCalleeThrow(C, this, - cast<CXXBindTemporaryExpr>(this)->getTemporary()->getDestructor()); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - // ObjC message sends are like function calls, but never have exception - // specs. - case ObjCMessageExprClass: - case ObjCPropertyRefExprClass: - case ObjCSubscriptRefExprClass: - return CT_Can; - - // All the ObjC literals that are implemented as calls are - // potentially throwing unless we decide to close off that - // possibility. - case ObjCArrayLiteralClass: - case ObjCDictionaryLiteralClass: - case ObjCNumericLiteralClass: - return CT_Can; - - // Many other things have subexpressions, so we have to test those. - // Some are simple: - case ConditionalOperatorClass: - case CompoundLiteralExprClass: - case CXXConstCastExprClass: - case CXXDefaultArgExprClass: - case CXXReinterpretCastExprClass: - case DesignatedInitExprClass: - case ExprWithCleanupsClass: - case ExtVectorElementExprClass: - case InitListExprClass: - case MemberExprClass: - case ObjCIsaExprClass: - case ObjCIvarRefExprClass: - case ParenExprClass: - case ParenListExprClass: - case ShuffleVectorExprClass: - case VAArgExprClass: - return CanSubExprsThrow(C, this); - - // Some might be dependent for other reasons. - case ArraySubscriptExprClass: - case BinaryOperatorClass: - case CompoundAssignOperatorClass: - case CStyleCastExprClass: - case CXXStaticCastExprClass: - case CXXFunctionalCastExprClass: - case ImplicitCastExprClass: - case MaterializeTemporaryExprClass: - case UnaryOperatorClass: { - CanThrowResult CT = isTypeDependent() ? CT_Dependent : CT_Cannot; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms. - case StmtExprClass: - return CT_Can; - - case ChooseExprClass: - if (isTypeDependent() || isValueDependent()) - return CT_Dependent; - return cast<ChooseExpr>(this)->getChosenSubExpr(C)->CanThrow(C); - - case GenericSelectionExprClass: - if (cast<GenericSelectionExpr>(this)->isResultDependent()) - return CT_Dependent; - return cast<GenericSelectionExpr>(this)->getResultExpr()->CanThrow(C); - - // Some expressions are always dependent. - case CXXDependentScopeMemberExprClass: - case CXXUnresolvedConstructExprClass: - case DependentScopeDeclRefExprClass: - return CT_Dependent; - - case AtomicExprClass: - case AsTypeExprClass: - case BinaryConditionalOperatorClass: - case BlockExprClass: - case CUDAKernelCallExprClass: - case DeclRefExprClass: - case ObjCBridgedCastExprClass: - case ObjCIndirectCopyRestoreExprClass: - case ObjCProtocolExprClass: - case ObjCSelectorExprClass: - case OffsetOfExprClass: - case PackExpansionExprClass: - case PseudoObjectExprClass: - case SubstNonTypeTemplateParmExprClass: - case SubstNonTypeTemplateParmPackExprClass: - case UnaryExprOrTypeTraitExprClass: - case UnresolvedLookupExprClass: - case UnresolvedMemberExprClass: - // FIXME: Can any of the above throw? If so, when? - return CT_Cannot; - - case AddrLabelExprClass: - case ArrayTypeTraitExprClass: - case BinaryTypeTraitExprClass: - case TypeTraitExprClass: - case CXXBoolLiteralExprClass: - case CXXNoexceptExprClass: - case CXXNullPtrLiteralExprClass: - case CXXPseudoDestructorExprClass: - case CXXScalarValueInitExprClass: - case CXXThisExprClass: - case CXXUuidofExprClass: - case CharacterLiteralClass: - case ExpressionTraitExprClass: - case FloatingLiteralClass: - case GNUNullExprClass: - case ImaginaryLiteralClass: - case ImplicitValueInitExprClass: - case IntegerLiteralClass: - case ObjCEncodeExprClass: - case ObjCStringLiteralClass: - case ObjCBoolLiteralExprClass: - case OpaqueValueExprClass: - case PredefinedExprClass: - case SizeOfPackExprClass: - case StringLiteralClass: - case UnaryTypeTraitExprClass: - // These expressions can never throw. - return CT_Cannot; - -#define STMT(CLASS, PARENT) case CLASS##Class: -#define STMT_RANGE(Base, First, Last) -#define LAST_STMT_RANGE(BASE, FIRST, LAST) -#define EXPR(CLASS, PARENT) -#define ABSTRACT_STMT(STMT) -#include "clang/AST/StmtNodes.inc" - case NoStmtClass: - llvm_unreachable("Invalid class for expression"); - } - llvm_unreachable("Bogus StmtClass"); -} - Expr* Expr::IgnoreParens() { Expr* E = this; while (true) { diff --git a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp index 01c9fe7..66a88b0 100644 --- a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp @@ -934,6 +934,7 @@ static bool IsGlobalLValue(APValue::LValueBase B) { case Expr::ObjCStringLiteralClass: case Expr::ObjCEncodeExprClass: case Expr::CXXTypeidExprClass: + case Expr::CXXUuidofExprClass: return true; case Expr::CallExprClass: return IsStringLiteralCall(cast<CallExpr>(E)); @@ -1491,15 +1492,19 @@ static unsigned getBaseIndex(const CXXRecordDecl *Derived, llvm_unreachable("base class missing from derived class's bases list"); } -/// Extract the value of a character from a string literal. +/// Extract the value of a character from a string literal. CharType is used to +/// determine the expected signedness of the result -- a string literal used to +/// initialize an array of 'signed char' or 'unsigned char' might contain chars +/// of the wrong signedness. static APSInt ExtractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, - uint64_t Index) { + uint64_t Index, QualType CharType) { // FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant const StringLiteral *S = dyn_cast<StringLiteral>(Lit); assert(S && "unexpected string literal expression kind"); + assert(CharType->isIntegerType() && "unexpected character type"); APSInt Value(S->getCharByteWidth() * Info.Ctx.getCharWidth(), - Lit->getType()->getArrayElementTypeNoTypeQual()->isUnsignedIntegerType()); + CharType->isUnsignedIntegerType()); if (Index < S->getLength()) Value = S->getCodeUnit(Index); return Value; @@ -1546,7 +1551,7 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E, assert(I == N - 1 && "extracting subobject of character?"); assert(!O->hasLValuePath() || O->getLValuePath().empty()); Obj = APValue(ExtractStringLiteralCharacter( - Info, O->getLValueBase().get<const Expr*>(), Index)); + Info, O->getLValueBase().get<const Expr*>(), Index, SubType)); return true; } else if (O->getArrayInitializedElts() > Index) O = &O->getArrayInitializedElt(Index); @@ -2868,6 +2873,7 @@ public: bool VisitStringLiteral(const StringLiteral *E) { return Success(E); } bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { return Success(E); } bool VisitCXXTypeidExpr(const CXXTypeidExpr *E); + bool VisitCXXUuidofExpr(const CXXUuidofExpr *E); bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E); bool VisitUnaryDeref(const UnaryOperator *E); bool VisitUnaryReal(const UnaryOperator *E); @@ -2973,6 +2979,10 @@ bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { return Success(E); } +bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { + return Success(E); +} + bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) { // Handle static data members. if (const VarDecl *VD = dyn_cast<VarDecl>(E->getMemberDecl())) { @@ -3849,8 +3859,7 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { // C++11 [dcl.init.string]p1: A char array [...] can be initialized by [...] // an appropriately-typed string literal enclosed in braces. - if (E->getNumInits() == 1 && E->getInit(0)->isGLValue() && - Info.Ctx.hasSameUnqualifiedType(E->getType(), E->getInit(0)->getType())) { + if (E->isStringLiteralInit()) { LValue LV; if (!EvaluateLValue(E->getInit(0), LV, Info)) return false; @@ -5079,14 +5088,37 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { } } + // The comparison here must be unsigned, and performed with the same + // width as the pointer. + unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy); + uint64_t CompareLHS = LHSOffset.getQuantity(); + uint64_t CompareRHS = RHSOffset.getQuantity(); + assert(PtrSize <= 64 && "Unexpected pointer width"); + uint64_t Mask = ~0ULL >> (64 - PtrSize); + CompareLHS &= Mask; + CompareRHS &= Mask; + + // If there is a base and this is a relational operator, we can only + // compare pointers within the object in question; otherwise, the result + // depends on where the object is located in memory. + if (!LHSValue.Base.isNull() && E->isRelationalOp()) { + QualType BaseTy = getType(LHSValue.Base); + if (BaseTy->isIncompleteType()) + return Error(E); + CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy); + uint64_t OffsetLimit = Size.getQuantity(); + if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit) + return Error(E); + } + switch (E->getOpcode()) { default: llvm_unreachable("missing comparison operator"); - case BO_LT: return Success(LHSOffset < RHSOffset, E); - case BO_GT: return Success(LHSOffset > RHSOffset, E); - case BO_LE: return Success(LHSOffset <= RHSOffset, E); - case BO_GE: return Success(LHSOffset >= RHSOffset, E); - case BO_EQ: return Success(LHSOffset == RHSOffset, E); - case BO_NE: return Success(LHSOffset != RHSOffset, E); + case BO_LT: return Success(CompareLHS < CompareRHS, E); + case BO_GT: return Success(CompareLHS > CompareRHS, E); + case BO_LE: return Success(CompareLHS <= CompareRHS, E); + case BO_GE: return Success(CompareLHS >= CompareRHS, E); + case BO_EQ: return Success(CompareLHS == CompareRHS, E); + case BO_NE: return Success(CompareLHS != CompareRHS, E); } } } diff --git a/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp b/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp index fd616db..6b9fe26 100644 --- a/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp @@ -49,7 +49,10 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC, return DeclContext::lookup_result(); } -ExternalLoadResult +void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) { +} + +ExternalLoadResult ExternalASTSource::FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), SmallVectorImpl<Decl*> &Result) { diff --git a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp index d7b6354..0d405f1 100644 --- a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp @@ -2280,9 +2280,7 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T, } -/// Mangles a member expression. Implicit accesses are not handled, -/// but that should be okay, because you shouldn't be able to -/// make an implicit access in a function template declaration. +/// Mangles a member expression. void CXXNameMangler::mangleMemberExpr(const Expr *base, bool isArrow, NestedNameSpecifier *qualifier, @@ -2291,8 +2289,17 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base, unsigned arity) { // <expression> ::= dt <expression> <unresolved-name> // ::= pt <expression> <unresolved-name> - Out << (isArrow ? "pt" : "dt"); - mangleExpression(base); + if (base) { + if (base->isImplicitCXXThis()) { + // Note: GCC mangles member expressions to the implicit 'this' as + // *this., whereas we represent them as this->. The Itanium C++ ABI + // does not specify anything here, so we follow GCC. + Out << "dtdefpT"; + } else { + Out << (isArrow ? "pt" : "dt"); + mangleExpression(base); + } + } mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity); } @@ -2346,6 +2353,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { // <expr-primary> ::= L <type> <value number> E # integer literal // ::= L <type <value float> E # floating literal // ::= L <mangled-name> E # external name + // ::= fpT # 'this' expression QualType ImplicitlyConvertedToType; recurse: @@ -2361,7 +2369,6 @@ recurse: // These all can only appear in local or variable-initialization // contexts and so should never appear in a mangling. case Expr::AddrLabelExprClass: - case Expr::CXXThisExprClass: case Expr::DesignatedInitExprClass: case Expr::ImplicitValueInitExprClass: case Expr::ParenListExprClass: @@ -2919,6 +2926,10 @@ recurse: mangleExpression(cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr()); break; } + + case Expr::CXXThisExprClass: + Out << "fpT"; + break; } } diff --git a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp index 6af20df..e4d9f0a 100644 --- a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp @@ -97,8 +97,8 @@ Stmt *Stmt::IgnoreImplicit() { /// \brief Strip off all label-like statements. /// -/// This will strip off label statements, case statements, and default -/// statements recursively. +/// This will strip off label statements, case statements, attributed +/// statements and default statements recursively. const Stmt *Stmt::stripLabelLikeStatements() const { const Stmt *S = this; while (true) { @@ -106,6 +106,8 @@ const Stmt *Stmt::stripLabelLikeStatements() const { S = LS->getSubStmt(); else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) S = SC->getSubStmt(); + else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S)) + S = AS->getSubStmt(); else return S; } diff --git a/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp b/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp index 3a44183..0d1066b 100644 --- a/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp +++ b/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp @@ -169,6 +169,23 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { PrintStmt(Node->getSubStmt(), 0); } +void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { + OS << "[["; + bool first = true; + for (AttrVec::const_iterator it = Node->getAttrs().begin(), + end = Node->getAttrs().end(); + it != end; ++it) { + if (!first) { + OS << ", "; + first = false; + } + // TODO: check this + (*it)->printPretty(OS, Context); + } + OS << "]] "; + PrintStmt(Node->getSubStmt(), 0); +} + void StmtPrinter::PrintRawIfStmt(IfStmt *If) { OS << "if ("; PrintExpr(If->getCond()); diff --git a/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp b/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp index e5526ce..e50523a 100644 --- a/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp +++ b/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp @@ -109,6 +109,11 @@ void StmtProfiler::VisitLabelStmt(const LabelStmt *S) { VisitDecl(S->getDecl()); } +void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) { + VisitStmt(S); + // TODO: maybe visit attributes? +} + void StmtProfiler::VisitIfStmt(const IfStmt *S) { VisitStmt(S); VisitDecl(S->getConditionVariable()); @@ -758,6 +763,7 @@ void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) { void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) { VisitExpr(S); + ID.AddBoolean(S->isImplicit()); } void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) { diff --git a/contrib/llvm/tools/clang/lib/AST/Type.cpp b/contrib/llvm/tools/clang/lib/AST/Type.cpp index c82aeaa..3f6a094 100644 --- a/contrib/llvm/tools/clang/lib/AST/Type.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Type.cpp @@ -1546,6 +1546,14 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, else if (epi.NoexceptExpr->isInstantiationDependent()) setInstantiationDependent(); } + } else if (getExceptionSpecType() == EST_Uninstantiated) { + // Store the function decl from which we will resolve our + // exception specification. + FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + numArgs); + slot[0] = epi.ExceptionSpecDecl; + slot[1] = epi.ExceptionSpecTemplate; + // This exception specification doesn't make the type dependent, because + // it's not instantiated as part of instantiating the type. } if (epi.ConsumedArguments) { @@ -1629,6 +1637,8 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, ID.AddPointer(epi.Exceptions[i].getAsOpaquePtr()); } else if (epi.ExceptionSpecType == EST_ComputedNoexcept && epi.NoexceptExpr){ epi.NoexceptExpr->Profile(ID, Context, false); + } else if (epi.ExceptionSpecType == EST_Uninstantiated) { + ID.AddPointer(epi.ExceptionSpecDecl->getCanonicalDecl()); } if (epi.ConsumedArguments) { for (unsigned i = 0; i != NumArgs; ++i) diff --git a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp index 7a45972..107d9fb 100644 --- a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp +++ b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp @@ -2157,13 +2157,12 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents, VTableThunks(new VTableThunkTy[NumVTableThunks]), AddressPoints(AddressPoints) { std::copy(VTableComponents, VTableComponents+NumVTableComponents, - this->VTableComponents); - std::copy(VTableThunks, VTableThunks+NumVTableThunks, this->VTableThunks); + this->VTableComponents.get()); + std::copy(VTableThunks, VTableThunks+NumVTableThunks, + this->VTableThunks.get()); } -VTableLayout::~VTableLayout() { - delete[] VTableComponents; -} +VTableLayout::~VTableLayout() { } VTableContext::~VTableContext() { llvm::DeleteContainerSeconds(VTableLayouts); diff --git a/contrib/llvm/tools/clang/lib/Analysis/CFG.cpp b/contrib/llvm/tools/clang/lib/Analysis/CFG.cpp index d1334a5..2f1f1cb 100644 --- a/contrib/llvm/tools/clang/lib/Analysis/CFG.cpp +++ b/contrib/llvm/tools/clang/lib/Analysis/CFG.cpp @@ -18,6 +18,7 @@ #include "clang/AST/StmtVisitor.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/CharUnits.h" +#include "clang/Basic/AttrKinds.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Format.h" @@ -1069,6 +1070,9 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) { case Stmt::LambdaExprClass: return VisitLambdaExpr(cast<LambdaExpr>(S), asc); + case Stmt::AttributedStmtClass: + return Visit(cast<AttributedStmt>(S)->getSubStmt(), asc); + case Stmt::MemberExprClass: return VisitMemberExpr(cast<MemberExpr>(S), asc); @@ -1131,7 +1135,7 @@ CFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) { /// VisitChildren - Visit the children of a Stmt. CFGBlock *CFGBuilder::VisitChildren(Stmt *Terminator) { - CFGBlock *lastBlock = Block; + CFGBlock *lastBlock = Block; for (Stmt::child_range I = Terminator->children(); I; ++I) if (Stmt *child = *I) if (CFGBlock *b = Visit(child)) @@ -1280,7 +1284,8 @@ static bool CanThrow(Expr *E, ASTContext &Ctx) { const FunctionType *FT = Ty->getAs<FunctionType>(); if (FT) { if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT)) - if (Proto->isNothrow(Ctx)) + if (Proto->getExceptionSpecType() != EST_Uninstantiated && + Proto->isNothrow(Ctx)) return false; } return true; diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp index f938b5a..8c49486 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp @@ -58,6 +58,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { Char32Type = UnsignedInt; Int64Type = SignedLongLong; SigAtomicType = SignedInt; + UseSignedCharForObjCBool = true; UseBitFieldTypeAlignment = true; UseZeroLengthBitfieldAlignment = false; ZeroLengthBitfieldBoundary = 0; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index 1ad37c4..dd2a89a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -365,7 +365,7 @@ protected: DefineStd(Builder, "unix", Opts); Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) - Builder.defineMacro("_POSIX_THREADS"); + Builder.defineMacro("_REENTRANT"); } public: OpenBSDTargetInfo(const std::string &triple) @@ -3546,7 +3546,10 @@ public: virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, bool Enabled) const { - if (Name == "soft-float" || Name == "single-float") { + if (Name == "soft-float" || Name == "single-float" || + Name == "o32" || Name == "n32" || Name == "n64" || Name == "eabi" || + Name == "mips32" || Name == "mips32r2" || + Name == "mips64" || Name == "mips64r2") { Features[Name] = Enabled; return true; } diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp index 36138ac..2b3ed58 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Version.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Version.cpp @@ -32,7 +32,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $"); + static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/branches/release_31/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGBlocks.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGBlocks.cpp index 27bb4ef..f8c7bcd 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGBlocks.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGBlocks.cpp @@ -491,6 +491,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, /// a full-expression so that the block's cleanups are pushed at the /// right place in the stack. static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) { + assert(CGF.HaveInsertPoint()); + // Allocate the block info and place it at the head of the list. CGBlockInfo &blockInfo = *new CGBlockInfo(block, CGF.CurFn->getName()); diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp index 4455f1a..82ee4fc 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp @@ -419,16 +419,37 @@ void CodeGenTypes::GetExpandedTypes(QualType type, uint64_t NumElts = AT->getSize().getZExtValue(); for (uint64_t Elt = 0; Elt < NumElts; ++Elt) GetExpandedTypes(AT->getElementType(), expandedTypes); - } else if (const RecordType *RT = type->getAsStructureType()) { + } else if (const RecordType *RT = type->getAs<RecordType>()) { const RecordDecl *RD = RT->getDecl(); assert(!RD->hasFlexibleArrayMember() && "Cannot expand structure with flexible array."); - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) { - const FieldDecl *FD = *i; - assert(!FD->isBitField() && - "Cannot expand structure with bit-field members."); - GetExpandedTypes(FD->getType(), expandedTypes); + if (RD->isUnion()) { + // Unions can be here only in degenerative cases - all the fields are same + // after flattening. Thus we have to use the "largest" field. + const FieldDecl *LargestFD = 0; + CharUnits UnionSize = CharUnits::Zero(); + + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i) { + const FieldDecl *FD = *i; + assert(!FD->isBitField() && + "Cannot expand structure with bit-field members."); + CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType()); + if (UnionSize < FieldSize) { + UnionSize = FieldSize; + LargestFD = FD; + } + } + if (LargestFD) + GetExpandedTypes(LargestFD->getType(), expandedTypes); + } else { + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i) { + const FieldDecl *FD = *i; + assert(!FD->isBitField() && + "Cannot expand structure with bit-field members."); + GetExpandedTypes(FD->getType(), expandedTypes); + } } } else if (const ComplexType *CT = type->getAs<ComplexType>()) { llvm::Type *EltTy = ConvertType(CT->getElementType()); @@ -443,32 +464,55 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV, llvm::Function::arg_iterator AI) { assert(LV.isSimple() && "Unexpected non-simple lvalue during struct expansion."); - llvm::Value *Addr = LV.getAddress(); if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { unsigned NumElts = AT->getSize().getZExtValue(); QualType EltTy = AT->getElementType(); for (unsigned Elt = 0; Elt < NumElts; ++Elt) { - llvm::Value *EltAddr = Builder.CreateConstGEP2_32(Addr, 0, Elt); + llvm::Value *EltAddr = Builder.CreateConstGEP2_32(LV.getAddress(), 0, Elt); LValue LV = MakeAddrLValue(EltAddr, EltTy); AI = ExpandTypeFromArgs(EltTy, LV, AI); } - } else if (const RecordType *RT = Ty->getAsStructureType()) { + } else if (const RecordType *RT = Ty->getAs<RecordType>()) { RecordDecl *RD = RT->getDecl(); - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) { - FieldDecl *FD = *i; - QualType FT = FD->getType(); - - // FIXME: What are the right qualifiers here? - LValue LV = EmitLValueForField(Addr, FD, 0); - AI = ExpandTypeFromArgs(FT, LV, AI); + if (RD->isUnion()) { + // Unions can be here only in degenerative cases - all the fields are same + // after flattening. Thus we have to use the "largest" field. + const FieldDecl *LargestFD = 0; + CharUnits UnionSize = CharUnits::Zero(); + + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i) { + const FieldDecl *FD = *i; + assert(!FD->isBitField() && + "Cannot expand structure with bit-field members."); + CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType()); + if (UnionSize < FieldSize) { + UnionSize = FieldSize; + LargestFD = FD; + } + } + if (LargestFD) { + // FIXME: What are the right qualifiers here? + LValue SubLV = EmitLValueForField(LV, LargestFD); + AI = ExpandTypeFromArgs(LargestFD->getType(), SubLV, AI); + } + } else { + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i) { + FieldDecl *FD = *i; + QualType FT = FD->getType(); + + // FIXME: What are the right qualifiers here? + LValue SubLV = EmitLValueForField(LV, FD); + AI = ExpandTypeFromArgs(FT, SubLV, AI); + } } } else if (const ComplexType *CT = Ty->getAs<ComplexType>()) { QualType EltTy = CT->getElementType(); - llvm::Value *RealAddr = Builder.CreateStructGEP(Addr, 0, "real"); + llvm::Value *RealAddr = Builder.CreateStructGEP(LV.getAddress(), 0, "real"); EmitStoreThroughLValue(RValue::get(AI++), MakeAddrLValue(RealAddr, EltTy)); - llvm::Value *ImagAddr = Builder.CreateStructGEP(Addr, 1, "imag"); + llvm::Value *ImagAddr = Builder.CreateStructGEP(LV.getAddress(), 1, "imag"); EmitStoreThroughLValue(RValue::get(AI++), MakeAddrLValue(ImagAddr, EltTy)); } else { EmitStoreThroughLValue(RValue::get(AI), LV); @@ -1760,26 +1804,38 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV, EltRV = EmitLoadOfLValue(LV); ExpandTypeToArgs(EltTy, EltRV, Args, IRFuncTy); } - } else if (const RecordType *RT = Ty->getAsStructureType()) { + } else if (const RecordType *RT = Ty->getAs<RecordType>()) { RecordDecl *RD = RT->getDecl(); assert(RV.isAggregate() && "Unexpected rvalue during struct expansion"); - llvm::Value *Addr = RV.getAggregateAddr(); - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) { - FieldDecl *FD = *i; - QualType FT = FD->getType(); - - // FIXME: What are the right qualifiers here? - LValue LV = EmitLValueForField(Addr, FD, 0); - RValue FldRV; - if (FT->isAnyComplexType()) - // FIXME: Volatile? - FldRV = RValue::getComplex(LoadComplexFromAddr(LV.getAddress(), false)); - else if (CodeGenFunction::hasAggregateLLVMType(FT)) - FldRV = LV.asAggregateRValue(); - else - FldRV = EmitLoadOfLValue(LV); - ExpandTypeToArgs(FT, FldRV, Args, IRFuncTy); + LValue LV = MakeAddrLValue(RV.getAggregateAddr(), Ty); + + if (RD->isUnion()) { + const FieldDecl *LargestFD = 0; + CharUnits UnionSize = CharUnits::Zero(); + + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i) { + const FieldDecl *FD = *i; + assert(!FD->isBitField() && + "Cannot expand structure with bit-field members."); + CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType()); + if (UnionSize < FieldSize) { + UnionSize = FieldSize; + LargestFD = FD; + } + } + if (LargestFD) { + RValue FldRV = EmitRValueForField(LV, LargestFD); + ExpandTypeToArgs(LargestFD->getType(), FldRV, Args, IRFuncTy); + } + } else { + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i) { + FieldDecl *FD = *i; + + RValue FldRV = EmitRValueForField(LV, FD); + ExpandTypeToArgs(FD->getType(), FldRV, Args, IRFuncTy); + } } } else if (Ty->isAnyComplexType()) { ComplexPairTy CV = RV.getComplexVal(); diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp index 6303e20..2aedf95 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp @@ -555,15 +555,17 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, QualType FieldType = Field->getType(); llvm::Value *ThisPtr = CGF.LoadCXXThis(); + QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); LValue LHS; - + // If we are initializing an anonymous union field, drill down to the field. if (MemberInit->isIndirectMemberInitializer()) { LHS = CGF.EmitLValueForAnonRecordField(ThisPtr, MemberInit->getIndirectMember(), 0); FieldType = MemberInit->getIndirectMember()->getAnonField()->getType(); } else { - LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0); + LValue ThisLHSLV = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); + LHS = CGF.EmitLValueForFieldInitialization(ThisLHSLV, Field); } // Special case: if we are in a copy or move constructor, and we are copying @@ -585,7 +587,8 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, unsigned SrcArgIndex = Args.size() - 1; llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); - LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0); + LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); + LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field); // Copy the aggregate. CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType, @@ -978,7 +981,9 @@ namespace { void Emit(CodeGenFunction &CGF, Flags flags) { // Find the address of the field. llvm::Value *thisValue = CGF.LoadCXXThis(); - LValue LV = CGF.EmitLValueForField(thisValue, field, /*CVRQualifiers=*/0); + QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent()); + LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy); + LValue LV = CGF.EmitLValueForField(ThisLV, field); assert(LV.isSimple()); CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer, diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp index 7301d20..d286d24 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp @@ -184,7 +184,6 @@ CGDebugInfo::getClassName(const RecordDecl *RD) { const TemplateArgument *Args; unsigned NumArgs; - std::string Buffer; if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { const TemplateSpecializationType *TST = cast<TemplateSpecializationType>(TAW->getType()); @@ -195,16 +194,17 @@ CGDebugInfo::getClassName(const RecordDecl *RD) { Args = TemplateArgs.data(); NumArgs = TemplateArgs.size(); } - Buffer = RD->getIdentifier()->getNameStart(); + StringRef Name = RD->getIdentifier()->getName(); PrintingPolicy Policy(CGM.getLangOpts()); - Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args, - NumArgs, - Policy); + std::string TemplateArgList = + TemplateSpecializationType::PrintTemplateArgumentList(Args, NumArgs, Policy); // Copy this name on the side and use its reference. - char *StrPtr = DebugInfoNames.Allocate<char>(Buffer.length()); - memcpy(StrPtr, Buffer.data(), Buffer.length()); - return StringRef(StrPtr, Buffer.length()); + size_t Length = Name.size() + TemplateArgList.size(); + char *StrPtr = DebugInfoNames.Allocate<char>(Length); + memcpy(StrPtr, Name.data(), Name.size()); + memcpy(StrPtr + Name.size(), TemplateArgList.data(), TemplateArgList.size()); + return StringRef(StrPtr, Length); } /// getOrCreateFile - Get the file debug info descriptor for the input location. diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp index 8c154f0..6447779 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp @@ -1171,6 +1171,10 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { // If this was emitted as a global constant, we're done. if (emission.wasEmittedAsGlobal()) return; + // If we don't have an insertion point, we're done. Sema prevents + // us from jumping into any of these scopes anyway. + if (!HaveInsertPoint()) return; + const VarDecl &D = *emission.Variable; // Check the type for a cleanup. diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp index 08970fd..5f2b1f0 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp @@ -24,6 +24,7 @@ #include "clang/Frontend/CodeGenOptions.h" #include "llvm/Intrinsics.h" #include "llvm/LLVMContext.h" +#include "llvm/Support/MDBuilder.h" #include "llvm/Target/TargetData.h" using namespace clang; using namespace CodeGen; @@ -398,8 +399,8 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, break; case SubobjectAdjustment::FieldAdjustment: { - LValue LV = - CGF.EmitLValueForField(Object, Adjustment.Field, 0); + LValue LV = CGF.MakeAddrLValue(Object, E->getType()); + LV = CGF.EmitLValueForField(LV, Adjustment.Field); if (LV.isSimple()) { Object = LV.getAddress(); break; @@ -908,16 +909,8 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { } } - if (End == Min) - return NULL; - - llvm::Value *LowAndHigh[2]; - LowAndHigh[0] = llvm::ConstantInt::get(LTy, Min); - LowAndHigh[1] = llvm::ConstantInt::get(LTy, End); - - llvm::LLVMContext &C = getLLVMContext(); - llvm::MDNode *Range = llvm::MDNode::get(C, LowAndHigh); - return Range; + llvm::MDBuilder MDHelper(getLLVMContext()); + return MDHelper.createRange(Min, End); } llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, @@ -1577,8 +1570,12 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { // Use special handling for lambdas. if (!V) { - if (FieldDecl *FD = LambdaCaptureFields.lookup(VD)) - return EmitLValueForField(CXXABIThisValue, FD, 0); + if (FieldDecl *FD = LambdaCaptureFields.lookup(VD)) { + QualType LambdaTagType = getContext().getTagDeclType(FD->getParent()); + LValue LambdaLV = MakeNaturalAlignAddrLValue(CXXABIThisValue, + LambdaTagType); + return EmitLValueForField(LambdaLV, FD); + } assert(isa<BlockDecl>(CurCodeDecl) && E->refersToEnclosingLocal()); CharUnits alignment = getContext().getDeclAlign(VD); @@ -1973,32 +1970,19 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { } LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { - bool isNonGC = false; Expr *BaseExpr = E->getBase(); - llvm::Value *BaseValue = NULL; - Qualifiers BaseQuals; // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar. - if (E->isArrow()) { - BaseValue = EmitScalarExpr(BaseExpr); - const PointerType *PTy = - BaseExpr->getType()->getAs<PointerType>(); - BaseQuals = PTy->getPointeeType().getQualifiers(); - } else { - LValue BaseLV = EmitLValue(BaseExpr); - if (BaseLV.isNonGC()) - isNonGC = true; - // FIXME: this isn't right for bitfields. - BaseValue = BaseLV.getAddress(); - QualType BaseTy = BaseExpr->getType(); - BaseQuals = BaseTy.getQualifiers(); - } + LValue BaseLV; + if (E->isArrow()) + BaseLV = MakeNaturalAlignAddrLValue(EmitScalarExpr(BaseExpr), + BaseExpr->getType()->getPointeeType()); + else + BaseLV = EmitLValue(BaseExpr); NamedDecl *ND = E->getMemberDecl(); if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) { - LValue LV = EmitLValueForField(BaseValue, Field, - BaseQuals.getCVRQualifiers()); - LV.setNonGC(isNonGC); + LValue LV = EmitLValueForField(BaseLV, Field); setObjCGCLValueClass(getContext(), E, LV); return LV; } @@ -2032,8 +2016,10 @@ LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue, IndirectFieldDecl::chain_iterator I = Field->chain_begin(), IEnd = Field->chain_end(); while (true) { - LValue LV = EmitLValueForField(BaseValue, cast<FieldDecl>(*I), - CVRQualifiers); + QualType RecordTy = + getContext().getTypeDeclType(cast<FieldDecl>(*I)->getParent()); + LValue LV = EmitLValueForField(MakeAddrLValue(BaseValue, RecordTy), + cast<FieldDecl>(*I)); if (++I == IEnd) return LV; assert(LV.isSimple()); @@ -2042,19 +2028,25 @@ LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue, } } -LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr, - const FieldDecl *field, - unsigned cvr) { +LValue CodeGenFunction::EmitLValueForField(LValue base, + const FieldDecl *field) { if (field->isBitField()) - return EmitLValueForBitfield(baseAddr, field, cvr); + return EmitLValueForBitfield(base.getAddress(), field, + base.getVRQualifiers()); const RecordDecl *rec = field->getParent(); QualType type = field->getType(); CharUnits alignment = getContext().getDeclAlign(field); + // FIXME: It should be impossible to have an LValue without alignment for a + // complete type. + if (!base.getAlignment().isZero()) + alignment = std::min(alignment, base.getAlignment()); + bool mayAlias = rec->hasAttr<MayAliasAttr>(); - llvm::Value *addr = baseAddr; + llvm::Value *addr = base.getAddress(); + unsigned cvr = base.getVRQualifiers(); if (rec->isUnion()) { // For unions, there is no pointer adjustment. assert(!type->isReferenceType() && "union has reference member"); @@ -2117,30 +2109,33 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr, } LValue -CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value *BaseValue, - const FieldDecl *Field, - unsigned CVRQualifiers) { +CodeGenFunction::EmitLValueForFieldInitialization(LValue Base, + const FieldDecl *Field) { QualType FieldType = Field->getType(); if (!FieldType->isReferenceType()) - return EmitLValueForField(BaseValue, Field, CVRQualifiers); + return EmitLValueForField(Base, Field); const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(Field->getParent()); unsigned idx = RL.getLLVMFieldNo(Field); - llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx); + llvm::Value *V = Builder.CreateStructGEP(Base.getAddress(), idx); assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs"); - // Make sure that the address is pointing to the right type. This is critical // for both unions and structs. A union needs a bitcast, a struct element // will need a bitcast if the LLVM type laid out doesn't match the desired // type. llvm::Type *llvmType = ConvertTypeForMem(FieldType); - unsigned AS = cast<llvm::PointerType>(V->getType())->getAddressSpace(); - V = Builder.CreateBitCast(V, llvmType->getPointerTo(AS)); - + V = EmitBitCastOfLValueToProperType(*this, V, llvmType, Field->getName()); + CharUnits Alignment = getContext().getDeclAlign(Field); + + // FIXME: It should be impossible to have an LValue without alignment for a + // complete type. + if (!Base.getAlignment().isZero()) + Alignment = std::min(Alignment, Base.getAlignment()); + return MakeAddrLValue(V, FieldType, Alignment); } @@ -2378,6 +2373,19 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr( return MakeAddrLValue(RV.getScalarVal(), E->getType()); } +RValue CodeGenFunction::EmitRValueForField(LValue LV, + const FieldDecl *FD) { + QualType FT = FD->getType(); + LValue FieldLV = EmitLValueForField(LV, FD); + if (FT->isAnyComplexType()) + return RValue::getComplex( + LoadComplexFromAddr(FieldLV.getAddress(), + FieldLV.isVolatileQualified())); + else if (CodeGenFunction::hasAggregateLLVMType(FT)) + return FieldLV.asAggregateRValue(); + + return EmitLoadOfLValue(FieldLV); +} //===--------------------------------------------------------------------===// // Expression Emission @@ -3158,11 +3166,10 @@ void CodeGenFunction::SetFPAccuracy(llvm::Value *Val, float Accuracy) { if (Accuracy == 0.0 || !isa<llvm::Instruction>(Val)) return; - llvm::Value *ULPs = llvm::ConstantFP::get(Builder.getFloatTy(), Accuracy); - llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), ULPs); + llvm::MDBuilder MDHelper(getLLVMContext()); + llvm::MDNode *Node = MDHelper.createFPMath(Accuracy); - cast<llvm::Instruction>(Val)->setMetadata(llvm::LLVMContext::MD_fpaccuracy, - Node); + cast<llvm::Instruction>(Val)->setMetadata(llvm::LLVMContext::MD_fpmath, Node); } namespace { diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp index b6efc1c..7b0e0f5 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp @@ -238,7 +238,10 @@ void AggExprEmitter::EmitMoveFromReturnSlot(const Expr *E, RValue Src) { // Otherwise, do a final copy, assert(Dest.getAddr() != Src.getAggregateAddr()); - EmitFinalDestCopy(E, Src, /*Ignore*/ true); + std::pair<CharUnits, CharUnits> TypeInfo = + CGF.getContext().getTypeInfoInChars(E->getType()); + CharUnits Alignment = std::min(TypeInfo.second, Dest.getAlignment()); + EmitFinalDestCopy(E, Src, /*Ignore*/ true, Alignment.getQuantity()); } /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. @@ -348,7 +351,8 @@ void AggExprEmitter::EmitStdInitializerList(llvm::Value *destPtr, CGF.ErrorUnsupported(initList, "weird std::initializer_list"); return; } - LValue start = CGF.EmitLValueForFieldInitialization(destPtr, *field, 0); + LValue DestLV = CGF.MakeNaturalAlignAddrLValue(destPtr, initList->getType()); + LValue start = CGF.EmitLValueForFieldInitialization(DestLV, *field); llvm::Value *arrayStart = Builder.CreateStructGEP(alloc, 0, "arraystart"); CGF.EmitStoreThroughLValue(RValue::get(arrayStart), start); ++field; @@ -357,7 +361,7 @@ void AggExprEmitter::EmitStdInitializerList(llvm::Value *destPtr, CGF.ErrorUnsupported(initList, "weird std::initializer_list"); return; } - LValue endOrLength = CGF.EmitLValueForFieldInitialization(destPtr, *field, 0); + LValue endOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *field); if (ctx.hasSameType(field->getType(), elementPtr)) { // End pointer. llvm::Value *arrayEnd = Builder.CreateStructGEP(alloc,numInits, "arrayend"); @@ -912,28 +916,24 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { return; } - llvm::Value *DestPtr = EnsureSlot(E->getType()).getAddr(); + AggValueSlot Dest = EnsureSlot(E->getType()); + LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(), + Dest.getAlignment()); // Handle initialization of an array. if (E->getType()->isArrayType()) { - if (E->getNumInits() > 0) { - QualType T1 = E->getType(); - QualType T2 = E->getInit(0)->getType(); - if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) { - EmitAggLoadOfLValue(E->getInit(0)); - return; - } - } + if (E->isStringLiteralInit()) + return Visit(E->getInit(0)); QualType elementType = CGF.getContext().getAsArrayType(E->getType())->getElementType(); llvm::PointerType *APType = - cast<llvm::PointerType>(DestPtr->getType()); + cast<llvm::PointerType>(Dest.getAddr()->getType()); llvm::ArrayType *AType = cast<llvm::ArrayType>(APType->getElementType()); - EmitArrayInit(DestPtr, AType, elementType, E); + EmitArrayInit(Dest.getAddr(), AType, elementType, E); return; } @@ -966,7 +966,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { // FIXME: volatility FieldDecl *Field = E->getInitializedFieldInUnion(); - LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0); + LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestLV, Field); if (NumInitElements) { // Store the initializer into the field EmitInitializationToLValue(E->getInit(0), FieldLoc); @@ -1004,8 +1004,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { CGF.getTypes().isZeroInitializable(E->getType())) break; - // FIXME: volatility - LValue LV = CGF.EmitLValueForFieldInitialization(DestPtr, *field, 0); + + LValue LV = CGF.EmitLValueForFieldInitialization(DestLV, *field); // We never generate write-barries for initialized fields. LV.setNonGC(true); diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp index d3ba770..c69c883 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp @@ -1815,13 +1815,16 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *Value, void CodeGenFunction::EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Slot) { RunCleanupsScope Scope(*this); + LValue SlotLV = MakeAddrLValue(Slot.getAddr(), E->getType(), + Slot.getAlignment()); CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin(); for (LambdaExpr::capture_init_iterator i = E->capture_init_begin(), e = E->capture_init_end(); i != e; ++i, ++CurField) { // Emit initialization - LValue LV = EmitLValueForFieldInitialization(Slot.getAddr(), *CurField, 0); + + LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField); ArrayRef<VarDecl *> ArrayIndexes; if (CurField->getType()->isArrayType()) ArrayIndexes = E->getCaptureInitIndexVars(i); diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExprConstant.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExprConstant.cpp index d528e0c..bc9f9ef 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGExprConstant.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExprConstant.cpp @@ -758,17 +758,13 @@ public: } llvm::Constant *EmitArrayInitialization(InitListExpr *ILE) { - unsigned NumInitElements = ILE->getNumInits(); - if (NumInitElements == 1 && - CGM.getContext().hasSameUnqualifiedType(ILE->getType(), - ILE->getInit(0)->getType()) && - (isa<StringLiteral>(ILE->getInit(0)) || - isa<ObjCEncodeExpr>(ILE->getInit(0)))) + if (ILE->isStringLiteralInit()) return Visit(ILE->getInit(0)); llvm::ArrayType *AType = cast<llvm::ArrayType>(ConvertType(ILE->getType())); llvm::Type *ElemTy = AType->getElementType(); + unsigned NumInitElements = ILE->getNumInits(); unsigned NumElements = AType->getNumElements(); // Initialising an array requires us to automatically diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp index bf42dcb..a1d0789 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp @@ -79,6 +79,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::CompoundStmtClass: case Stmt::DeclStmtClass: case Stmt::LabelStmtClass: + case Stmt::AttributedStmtClass: case Stmt::GotoStmtClass: case Stmt::BreakStmtClass: case Stmt::ContinueStmtClass: @@ -173,6 +174,8 @@ bool CodeGenFunction::EmitSimpleStmt(const Stmt *S) { case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break; case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break; case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break; + case Stmt::AttributedStmtClass: + EmitAttributedStmt(cast<AttributedStmt>(*S)); break; case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break; case Stmt::BreakStmtClass: EmitBreakStmt(cast<BreakStmt>(*S)); break; case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break; @@ -332,6 +335,10 @@ void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { EmitStmt(S.getSubStmt()); } +void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { + EmitStmt(S.getSubStmt()); +} + void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { // If this code is reachable then emit a stop point (if generating // debug info). We have to do this ourselves because we are on the diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp index 06e90b6..2939062 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp @@ -22,8 +22,9 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/StmtCXX.h" #include "clang/Frontend/CodeGenOptions.h" -#include "llvm/Target/TargetData.h" #include "llvm/Intrinsics.h" +#include "llvm/Support/MDBuilder.h" +#include "llvm/Target/TargetData.h" using namespace clang; using namespace CodeGen; @@ -362,8 +363,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, LambdaThisCaptureField); if (LambdaThisCaptureField) { // If this lambda captures this, load it. - LValue ThisLValue = EmitLValueForField(CXXABIThisValue, - LambdaThisCaptureField, 0); + QualType LambdaTagType = + getContext().getTagDeclType(LambdaThisCaptureField->getParent()); + LValue LambdaLV = MakeNaturalAlignAddrLValue(CXXABIThisValue, + LambdaTagType); + LValue ThisLValue = EmitLValueForField(LambdaLV, + LambdaThisCaptureField); CXXThisValue = EmitLoadOfLValue(ThisLValue).getScalarVal(); } } else { diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h index 3e0cd14..83f1e2d 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h @@ -1948,6 +1948,7 @@ public: void EmitLabel(const LabelDecl *D); // helper for EmitLabelStmt. void EmitLabelStmt(const LabelStmt &S); + void EmitAttributedStmt(const AttributedStmt &S); void EmitGotoStmt(const GotoStmt &S); void EmitIndirectGotoStmt(const IndirectGotoStmt &S); void EmitIfStmt(const IfStmt &S); @@ -2104,6 +2105,8 @@ public: LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e); + RValue EmitRValueForField(LValue LV, const FieldDecl *FD); + class ConstantEmission { llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference; ConstantEmission(llvm::Constant *C, bool isReference) @@ -2143,15 +2146,13 @@ public: LValue EmitLValueForAnonRecordField(llvm::Value* Base, const IndirectFieldDecl* Field, unsigned CVRQualifiers); - LValue EmitLValueForField(llvm::Value* Base, const FieldDecl* Field, - unsigned CVRQualifiers); + LValue EmitLValueForField(LValue Base, const FieldDecl* Field); /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that /// if the Field is a reference, this will return the address of the reference /// and not the address of the value stored in the reference. - LValue EmitLValueForFieldInitialization(llvm::Value* Base, - const FieldDecl* Field, - unsigned CVRQualifiers); + LValue EmitLValueForFieldInitialization(LValue Base, + const FieldDecl* Field); LValue EmitLValueForIvar(QualType ObjectTy, llvm::Value* Base, const ObjCIvarDecl *Ivar, diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp index c0ccf4d..9a55c08 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp @@ -1241,7 +1241,7 @@ CodeGenModule::CreateOrReplaceCXXRuntimeVariable(StringRef Name, /// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the /// given global variable. If Ty is non-null and if the global doesn't exist, -/// then it will be greated with the specified type instead of whatever the +/// then it will be created with the specified type instead of whatever the /// normal requested type would be. llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty) { diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.cpp index 9ee3f1d..a3cadcf 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -28,7 +28,7 @@ using namespace CodeGen; CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext, const LangOptions &Features, MangleContext &MContext) : Context(Ctx), VMContext(VMContext), Features(Features), MContext(MContext), - Root(0), Char(0) { + MDHelper(VMContext), Root(0), Char(0) { } CodeGenTBAA::~CodeGenTBAA() { @@ -40,7 +40,7 @@ llvm::MDNode *CodeGenTBAA::getRoot() { // (or a different version of this front-end), their TBAA trees will // remain distinct, and the optimizer will treat them conservatively. if (!Root) - Root = getTBAAInfoForNamedType("Simple C/C++ TBAA", 0); + Root = MDHelper.createTBAARoot("Simple C/C++ TBAA"); return Root; } @@ -51,33 +51,11 @@ llvm::MDNode *CodeGenTBAA::getChar() { // these special powers only cover user-accessible memory, and doesn't // include things like vtables. if (!Char) - Char = getTBAAInfoForNamedType("omnipotent char", getRoot()); + Char = MDHelper.createTBAANode("omnipotent char", getRoot()); return Char; } -/// getTBAAInfoForNamedType - Create a TBAA tree node with the given string -/// as its identifier, and the given Parent node as its tree parent. -llvm::MDNode *CodeGenTBAA::getTBAAInfoForNamedType(StringRef NameStr, - llvm::MDNode *Parent, - bool Readonly) { - // Currently there is only one flag defined - the readonly flag. - llvm::Value *Flags = 0; - if (Readonly) - Flags = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), true); - - // Set up the mdnode operand list. - llvm::Value *Ops[] = { - llvm::MDString::get(VMContext, NameStr), - Parent, - Flags - }; - - // Create the mdnode. - unsigned Len = llvm::array_lengthof(Ops) - !Flags; - return llvm::MDNode::get(VMContext, llvm::makeArrayRef(Ops, Len)); -} - static bool TypeHasMayAlias(QualType QTy) { // Tagged types have declarations, and therefore may have attributes. if (const TagType *TTy = dyn_cast<TagType>(QTy)) @@ -137,7 +115,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { // "underlying types". default: return MetadataCache[Ty] = - getTBAAInfoForNamedType(BTy->getName(Features), getChar()); + MDHelper.createTBAANode(BTy->getName(Features), getChar()); } } @@ -145,7 +123,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { // TODO: Implement C++'s type "similarity" and consider dis-"similar" // pointers distinct. if (Ty->isPointerType()) - return MetadataCache[Ty] = getTBAAInfoForNamedType("any pointer", + return MetadataCache[Ty] = MDHelper.createTBAANode("any pointer", getChar()); // Enum types are distinct types. In C++ they have "underlying types", @@ -173,7 +151,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { llvm::raw_svector_ostream Out(OutName); MContext.mangleCXXRTTIName(QualType(ETy, 0), Out); Out.flush(); - return MetadataCache[Ty] = getTBAAInfoForNamedType(OutName, getChar()); + return MetadataCache[Ty] = MDHelper.createTBAANode(OutName, getChar()); } // For now, handle any other kind of type conservatively. @@ -181,5 +159,5 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { } llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() { - return getTBAAInfoForNamedType("vtable pointer", getRoot()); + return MDHelper.createTBAANode("vtable pointer", getRoot()); } diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.h index 8e08498..4a97852 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.h +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.h @@ -17,6 +17,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/MDBuilder.h" namespace llvm { class LLVMContext; @@ -41,6 +42,9 @@ class CodeGenTBAA { const LangOptions &Features; MangleContext &MContext; + // MDHelper - Helper for creating metadata. + llvm::MDBuilder MDHelper; + /// MetadataCache - This maps clang::Types to llvm::MDNodes describing them. llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; @@ -55,10 +59,6 @@ class CodeGenTBAA { /// considered to be equivalent to it. llvm::MDNode *getChar(); - llvm::MDNode *getTBAAInfoForNamedType(StringRef NameStr, - llvm::MDNode *Parent, - bool Readonly = false); - public: CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext, const LangOptions &Features, diff --git a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp index 3ed1778..2b71fdd 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp @@ -2527,19 +2527,16 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const { static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, ASTContext &Context, uint64_t *HAMembers = 0) { - uint64_t Members; + uint64_t Members = 0; if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { if (!isHomogeneousAggregate(AT->getElementType(), Base, Context, &Members)) return false; Members *= AT->getSize().getZExtValue(); } else if (const RecordType *RT = Ty->getAs<RecordType>()) { const RecordDecl *RD = RT->getDecl(); - if (RD->isUnion() || RD->hasFlexibleArrayMember()) + if (RD->hasFlexibleArrayMember()) return false; - if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { - if (!CXXRD->isAggregate()) - return false; - } + Members = 0; for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i) { @@ -2547,7 +2544,9 @@ static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t FldMembers; if (!isHomogeneousAggregate(FD->getType(), Base, Context, &FldMembers)) return false; - Members += FldMembers; + + Members = (RD->isUnion() ? + std::max(Members, FldMembers) : Members + FldMembers); } } else { Members = 1; @@ -2584,7 +2583,8 @@ static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, // Homogeneous Aggregates can have at most 4 members of the base type. if (HAMembers) *HAMembers = Members; - return (Members <= 4); + + return (Members > 0 && Members <= 4); } ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty) const { @@ -2609,8 +2609,10 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty) const { if (getABIKind() == ARMABIInfo::AAPCS_VFP) { // Homogeneous Aggregates need to be expanded. const Type *Base = 0; - if (isHomogeneousAggregate(Ty, Base, getContext())) + if (isHomogeneousAggregate(Ty, Base, getContext())) { + assert(Base && "Base class should be set for homogeneous aggregate"); return ABIArgInfo::getExpand(); + } } // Otherwise, pass by coercing to a structure of the appropriate size. @@ -2776,9 +2778,11 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { // Check for homogeneous aggregates with AAPCS-VFP. if (getABIKind() == AAPCS_VFP) { const Type *Base = 0; - if (isHomogeneousAggregate(RetTy, Base, getContext())) + if (isHomogeneousAggregate(RetTy, Base, getContext())) { + assert(Base && "Base class should be set for homogeneous aggregate"); // Homogeneous Aggregates are returned directly. return ABIArgInfo::getDirect(); + } } // Aggregates <= 4 bytes are returned in r0; other aggregates diff --git a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp index 42c8449..5553fc9 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp @@ -230,3 +230,7 @@ void Compilation::initCompilationForDiagnostics(void) { Redirects[1] = new const llvm::sys::Path(); Redirects[2] = new const llvm::sys::Path(); } + +StringRef Compilation::getSysRoot(void) const { + return getDriver().SysRoot; +} diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp index 40e0c00..bb78a41 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp @@ -49,8 +49,8 @@ Driver::Driver(StringRef ClangExecutable, bool IsProduction, DiagnosticsEngine &Diags) : Opts(createDriverOptTable()), Diags(Diags), - ClangExecutable(ClangExecutable), UseStdLib(true), - DefaultTargetTriple(DefaultTargetTriple), + ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT), + UseStdLib(true), DefaultTargetTriple(DefaultTargetTriple), DefaultImageName(DefaultImageName), DriverTitle("clang \"gcc-compatible\" driver"), CCPrintOptionsFilename(0), CCPrintHeadersFilename(0), @@ -660,9 +660,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { llvm::outs() << "\n"; llvm::outs() << "libraries: =" << ResourceDir; - std::string sysroot; - if (Arg *A = C.getArgs().getLastArg(options::OPT__sysroot_EQ)) - sysroot = A->getValue(C.getArgs()); + StringRef sysroot = C.getSysRoot(); for (ToolChain::path_list::const_iterator it = TC.getFilePaths().begin(), ie = TC.getFilePaths().end(); it != ie; ++it) { @@ -872,30 +870,30 @@ void Driver::BuildUniversalActions(const ToolChain &TC, // Handle debug info queries. Arg *A = Args.getLastArg(options::OPT_g_Group); - if (A && !A->getOption().matches(options::OPT_g0) && - !A->getOption().matches(options::OPT_gstabs) && - ContainsCompileOrAssembleAction(Actions.back())) { - - // Add a 'dsymutil' step if necessary, when debug info is enabled and we - // have a compile input. We need to run 'dsymutil' ourselves in such cases - // because the debug info will refer to a temporary object file which is - // will be removed at the end of the compilation process. - if (Act->getType() == types::TY_Image) { - ActionList Inputs; - Inputs.push_back(Actions.back()); - Actions.pop_back(); - Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM)); - } + if (A && !A->getOption().matches(options::OPT_g0) && + !A->getOption().matches(options::OPT_gstabs) && + ContainsCompileOrAssembleAction(Actions.back())) { + + // Add a 'dsymutil' step if necessary, when debug info is enabled and we + // have a compile input. We need to run 'dsymutil' ourselves in such cases + // because the debug info will refer to a temporary object file which is + // will be removed at the end of the compilation process. + if (Act->getType() == types::TY_Image) { + ActionList Inputs; + Inputs.push_back(Actions.back()); + Actions.pop_back(); + Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM)); + } - // Verify the output (debug information only) if we passed '-verify'. - if (Args.hasArg(options::OPT_verify)) { - ActionList VerifyInputs; - VerifyInputs.push_back(Actions.back()); - Actions.pop_back(); - Actions.push_back(new VerifyJobAction(VerifyInputs, - types::TY_Nothing)); - } + // Verify the output (debug information only) if we passed '-verify'. + if (Args.hasArg(options::OPT_verify)) { + ActionList VerifyInputs; + VerifyInputs.push_back(Actions.back()); + Actions.pop_back(); + Actions.push_back(new VerifyJobAction(VerifyInputs, + types::TY_Nothing)); } + } } } diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp index fa9ed49..81657d8 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp @@ -35,10 +35,6 @@ #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX -#ifndef CLANG_PREFIX -#define CLANG_PREFIX -#endif - using namespace clang::driver; using namespace clang::driver::toolchains; using namespace clang; @@ -584,7 +580,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { // If no '-miphoneos-version-min' specified on the command line and // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default - // based on isysroot. + // based on -isysroot. if (iOSTarget.empty()) { if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { StringRef first, second; @@ -1090,6 +1086,7 @@ bool Generic_GCC::GCCVersion::operator<(const GCCVersion &RHS) const { // a patch. if (RHS.Patch == -1) return true; if (Patch == -1) return false; if (Patch < RHS.Patch) return true; if (Patch > RHS.Patch) return false; + if (PatchSuffix == RHS.PatchSuffix) return false; // Finally, between completely tied version numbers, the version with the // suffix loses as we prefer full releases. @@ -1107,7 +1104,7 @@ static StringRef getGCCToolchainDir(const ArgList &Args) { /// \brief Construct a GCCInstallationDetector from the driver. /// /// This performs all of the autodetection and sets up the various paths. -/// Once constructed, a GCCInstallation is esentially immutable. +/// Once constructed, a GCCInstallationDetector is essentially immutable. /// /// FIXME: We shouldn't need an explicit TargetTriple parameter here, and /// should instead pull the target out of the driver. This is currently @@ -1618,10 +1615,10 @@ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Arg // back to '/usr/lib' if it doesn't exist. if ((Triple.getArch() == llvm::Triple::x86 || Triple.getArch() == llvm::Triple::ppc) && - llvm::sys::fs::exists(getDriver().SysRoot + CLANG_PREFIX "/usr/lib32/crt1.o")) - getFilePaths().push_back(getDriver().SysRoot + CLANG_PREFIX "/usr/lib32"); + llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) + getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); else - getFilePaths().push_back(getDriver().SysRoot + CLANG_PREFIX "/usr/lib"); + getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); } Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA, @@ -2067,7 +2064,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // If the GCC installation we found is inside of the sysroot, we want to // prefer libraries installed in the parent prefix of the GCC installation. // It is important to *not* use these paths when the GCC installation is - // outside of the system root as that can pick up un-intented libraries. + // outside of the system root as that can pick up unintended libraries. // This usually happens when there is an external cross compiler on the // host system, and a more minimal sysroot available that is the target of // the cross. diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp index d3dab19..04fa8a1 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp @@ -377,10 +377,11 @@ void Clang::AddPreprocessingOptions(Compilation &C, // If we have a --sysroot, and don't have an explicit -isysroot flag, add an // -isysroot to the CC1 invocation. - if (Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) { + StringRef sysroot = C.getSysRoot(); + if (sysroot != "") { if (!Args.hasArg(options::OPT_isysroot)) { CmdArgs.push_back("-isysroot"); - CmdArgs.push_back(A->getValue(Args)); + CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); } } @@ -4017,9 +4018,10 @@ void darwin::Link::AddLinkArgs(Compilation &C, // Give --sysroot= preference, over the Apple specific behavior to also use // --isysroot as the syslibroot. - if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) { + StringRef sysroot = C.getSysRoot(); + if (sysroot != "") { CmdArgs.push_back("-syslibroot"); - CmdArgs.push_back(A->getValue(Args)); + CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { CmdArgs.push_back("-syslibroot"); CmdArgs.push_back(A->getValue(Args)); diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp index e32fa63..7aa9603 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp @@ -643,8 +643,10 @@ void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, DiagnosticConsumer *Client = 0; if (CaptureDiagnostics) Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); - Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd- ArgBegin, - ArgBegin, Client); + Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd-ArgBegin, + ArgBegin, Client, + /*ShouldOwnClient=*/true, + /*ShouldCloneClient=*/false); } else if (CaptureDiagnostics) { Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics)); } diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp index cab6b90..803e418 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp @@ -651,6 +651,10 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { // created. This complexity should be lifted elsewhere. getTarget().setForcedLangOptions(getLangOpts()); + // rewriter project will change target built-in bool type from its default. + if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) + getTarget().noSignedCharForObjCBool(); + // Validate/process some options. if (getHeaderSearchOpts().Verbose) OS << "clang -cc1 version " CLANG_VERSION_STRING diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp index 612a0d8..eedc318 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp @@ -429,7 +429,6 @@ static const char *getActionName(frontend::ActionKind Kind) { case frontend::PrintDeclContext: return "-print-decl-contexts"; case frontend::PrintPreamble: return "-print-preamble"; case frontend::PrintPreprocessedInput: return "-E"; - case frontend::PubnamesDump: return "-pubnames-dump"; case frontend::RewriteMacros: return "-rewrite-macros"; case frontend::RewriteObjC: return "-rewrite-objc"; case frontend::RewriteTest: return "-rewrite-test"; @@ -1371,8 +1370,6 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::PrintPreamble; break; case OPT_E: Opts.ProgramAction = frontend::PrintPreprocessedInput; break; - case OPT_pubnames_dump: - Opts.ProgramAction = frontend::PubnamesDump; break; case OPT_rewrite_macros: Opts.ProgramAction = frontend::RewriteMacros; break; case OPT_rewrite_objc: diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp index b4a439d..737ee4a 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp @@ -25,7 +25,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -#include <set> using namespace clang; @@ -355,77 +354,6 @@ ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, return new ASTConsumer(); } -namespace { - class PubnamesDumpConsumer : public ASTConsumer { - Preprocessor &PP; - - /// \brief Determine whether the given identifier provides a 'public' name. - bool isPublicName(IdentifierInfo *II) { - // If there are any top-level declarations associated with this - // identifier, it is a public name. - if (II->getFETokenInfo<void>()) - return true; - - // If this identifier is the name of a non-builtin macro that isn't - // defined on the command line or implicitly by the front end, it is a - // public name. - if (II->hasMacroDefinition()) { - if (MacroInfo *M = PP.getMacroInfo(II)) - if (!M->isBuiltinMacro()) { - SourceLocation Loc = M->getDefinitionLoc(); - FileID File = PP.getSourceManager().getFileID(Loc); - if (PP.getSourceManager().getFileEntryForID(File)) - return true; - } - } - - return false; - } - - public: - PubnamesDumpConsumer(Preprocessor &PP) : PP(PP) { } - - virtual void HandleTranslationUnit(ASTContext &Ctx) { - std::set<StringRef> Pubnames; - - // Add the names of any non-builtin macros. - for (IdentifierTable::iterator I = Ctx.Idents.begin(), - IEnd = Ctx.Idents.end(); - I != IEnd; ++I) { - if (isPublicName(I->second)) - Pubnames.insert(I->first()); - } - - // If there is an external identifier lookup source, consider those - // identifiers as well. - if (IdentifierInfoLookup *External - = Ctx.Idents.getExternalIdentifierLookup()) { - OwningPtr<IdentifierIterator> Iter(External->getIdentifiers()); - do { - StringRef Name = Iter->Next(); - if (Name.empty()) - break; - - if (isPublicName(PP.getIdentifierInfo(Name))) - Pubnames.insert(Name); - } while (true); - } - - // Print the names, in lexicographical order. - for (std::set<StringRef>::iterator N = Pubnames.begin(), - NEnd = Pubnames.end(); - N != NEnd; ++N) { - llvm::outs() << *N << '\n'; - } - } - }; -} - -ASTConsumer *PubnamesDumpAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { - return new PubnamesDumpConsumer(CI.getPreprocessor()); -} - //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp index 7f01cd9..fc3388d 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp @@ -29,9 +29,6 @@ #include "clang/Config/config.h" // C_INCLUDE_DIRS -#ifndef CLANG_PREFIX -#define CLANG_PREFIX -#endif using namespace clang; using namespace clang::frontend; @@ -319,7 +316,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, } break; case llvm::Triple::FreeBSD: - AddPath(CLANG_PREFIX "/usr/include/clang/" CLANG_VERSION_STRING, + AddPath("/usr/include/clang/" CLANG_VERSION_STRING, System, false, false, false); break; @@ -328,7 +325,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, } if ( os != llvm::Triple::RTEMS ) - AddPath(CLANG_PREFIX "/usr/include", System, false, false, false); + AddPath("/usr/include", System, false, false, false); } void InitHeaderSearch:: @@ -408,9 +405,8 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp case llvm::Triple::FreeBSD: // FreeBSD 8.0 // FreeBSD 7.3 - AddGnuCPlusPlusIncludePaths(CLANG_PREFIX "/usr/include/c++/4.2", - "", "", "", triple); - AddGnuCPlusPlusIncludePaths(CLANG_PREFIX "/usr/include/c++/4.2/backward", + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2/backward", "", "", "", triple); break; case llvm::Triple::NetBSD: diff --git a/contrib/llvm/tools/clang/lib/Frontend/TextDiagnostic.cpp b/contrib/llvm/tools/clang/lib/Frontend/TextDiagnostic.cpp index 9f5dcb4..65fb1ae 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/TextDiagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/TextDiagnostic.cpp @@ -10,13 +10,17 @@ #include "clang/Frontend/TextDiagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/ConvertUTF.h" #include "clang/Frontend/DiagnosticOptions.h" #include "clang/Lex/Lexer.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Locale.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include <algorithm> + using namespace clang; static const enum raw_ostream::Colors noteColor = @@ -36,23 +40,269 @@ static const enum raw_ostream::Colors savedColor = /// \brief Number of spaces to indent when word-wrapping. const unsigned WordWrapIndentation = 6; +int bytesSincePreviousTabOrLineBegin(StringRef SourceLine, size_t i) { + int bytes = 0; + while (0<i) { + if (SourceLine[--i]=='\t') + break; + ++bytes; + } + return bytes; +} + +/// \brief returns a printable representation of first item from input range +/// +/// This function returns a printable representation of the next item in a line +/// of source. If the next byte begins a valid and printable character, that +/// character is returned along with 'true'. +/// +/// Otherwise, if the next byte begins a valid, but unprintable character, a +/// printable, escaped representation of the character is returned, along with +/// 'false'. Otherwise a printable, escaped representation of the next byte +/// is returned along with 'false'. +/// +/// \note The index is updated to be used with a subsequent call to +/// printableTextForNextCharacter. +/// +/// \param SourceLine The line of source +/// \param i Pointer to byte index, +/// \param TabStop used to expand tabs +/// \return pair(printable text, 'true' iff original text was printable) +/// +std::pair<SmallString<16>,bool> +printableTextForNextCharacter(StringRef SourceLine, size_t *i, + unsigned TabStop) { + assert(i && "i must not be null"); + assert(*i<SourceLine.size() && "must point to a valid index"); + + if (SourceLine[*i]=='\t') { + assert(0 < TabStop && TabStop <= DiagnosticOptions::MaxTabStop && + "Invalid -ftabstop value"); + unsigned col = bytesSincePreviousTabOrLineBegin(SourceLine, *i); + unsigned NumSpaces = TabStop - col%TabStop; + assert(0 < NumSpaces && NumSpaces <= TabStop + && "Invalid computation of space amt"); + ++(*i); + + SmallString<16> expandedTab; + expandedTab.assign(NumSpaces, ' '); + return std::make_pair(expandedTab, true); + } + + // FIXME: this data is copied from the private implementation of ConvertUTF.h + static const char trailingBytesForUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 + }; + + unsigned char const *begin, *end; + begin = reinterpret_cast<unsigned char const *>(&*(SourceLine.begin() + *i)); + end = begin + SourceLine.size(); + + if (isLegalUTF8Sequence(begin, end)) { + UTF32 c; + UTF32 *cptr = &c; + unsigned char const *original_begin = begin; + char trailingBytes = trailingBytesForUTF8[(unsigned char)SourceLine[*i]]; + unsigned char const *cp_end = begin+trailingBytes+1; + + ConversionResult res = ConvertUTF8toUTF32(&begin, cp_end, &cptr, cptr+1, + strictConversion); + (void)res; + assert(conversionOK==res); + assert(0 < begin-original_begin + && "we must be further along in the string now"); + *i += begin-original_begin; + + if (!llvm::sys::locale::isPrint(c)) { + // If next character is valid UTF-8, but not printable + SmallString<16> expandedCP("<U+>"); + while (c) { + expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(c%16)); + c/=16; + } + while (expandedCP.size() < 8) + expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(0)); + return std::make_pair(expandedCP, false); + } + + // If next character is valid UTF-8, and printable + return std::make_pair(SmallString<16>(original_begin, cp_end), true); + + } + + // If next byte is not valid UTF-8 (and therefore not printable) + SmallString<16> expandedByte("<XX>"); + unsigned char byte = SourceLine[*i]; + expandedByte[1] = llvm::hexdigit(byte / 16); + expandedByte[2] = llvm::hexdigit(byte % 16); + ++(*i); + return std::make_pair(expandedByte, false); +} + +void expandTabs(std::string &SourceLine, unsigned TabStop) { + size_t i = SourceLine.size(); + while (i>0) { + i--; + if (SourceLine[i]!='\t') + continue; + size_t tmp_i = i; + std::pair<SmallString<16>,bool> res + = printableTextForNextCharacter(SourceLine, &tmp_i, TabStop); + SourceLine.replace(i, 1, res.first.c_str()); + } +} + +/// This function takes a raw source line and produces a mapping from the bytes +/// of the printable representation of the line to the columns those printable +/// characters will appear at (numbering the first column as 0). +/// +/// If a byte 'i' corresponds to muliple columns (e.g. the byte contains a tab +/// character) then the the array will map that byte to the first column the +/// tab appears at and the next value in the map will have been incremented +/// more than once. +/// +/// If a byte is the first in a sequence of bytes that together map to a single +/// entity in the output, then the array will map that byte to the appropriate +/// column while the subsequent bytes will be -1. +/// +/// The last element in the array does not correspond to any byte in the input +/// and instead is the number of columns needed to display the source +/// +/// example: (given a tabstop of 8) +/// +/// "a \t \u3042" -> {0,1,2,8,9,-1,-1,11} +/// +/// (\u3042 is represented in UTF-8 by three bytes and takes two columns to +/// display) +void byteToColumn(StringRef SourceLine, unsigned TabStop, + SmallVectorImpl<int> &out) { + out.clear(); + + if (SourceLine.empty()) { + out.resize(1u,0); + return; + } + + out.resize(SourceLine.size()+1, -1); + + int columns = 0; + size_t i = 0; + while (i<SourceLine.size()) { + out[i] = columns; + std::pair<SmallString<16>,bool> res + = printableTextForNextCharacter(SourceLine, &i, TabStop); + columns += llvm::sys::locale::columnWidth(res.first); + } + out.back() = columns; +} + +/// This function takes a raw source line and produces a mapping from columns +/// to the byte of the source line that produced the character displaying at +/// that column. This is the inverse of the mapping produced by byteToColumn() +/// +/// The last element in the array is the number of bytes in the source string +/// +/// example: (given a tabstop of 8) +/// +/// "a \t \u3042" -> {0,1,2,-1,-1,-1,-1,-1,3,4,-1,7} +/// +/// (\u3042 is represented in UTF-8 by three bytes and takes two columns to +/// display) +void columnToByte(StringRef SourceLine, unsigned TabStop, + SmallVectorImpl<int> &out) { + out.clear(); + + if (SourceLine.empty()) { + out.resize(1u, 0); + return; + } + + int columns = 0; + size_t i = 0; + while (i<SourceLine.size()) { + out.resize(columns+1, -1); + out.back() = i; + std::pair<SmallString<16>,bool> res + = printableTextForNextCharacter(SourceLine, &i, TabStop); + columns += llvm::sys::locale::columnWidth(res.first); + } + out.resize(columns+1, -1); + out.back() = i; +} + +struct SourceColumnMap { + SourceColumnMap(StringRef SourceLine, unsigned TabStop) + : m_SourceLine(SourceLine) { + + ::byteToColumn(SourceLine, TabStop, m_byteToColumn); + ::columnToByte(SourceLine, TabStop, m_columnToByte); + + assert(m_byteToColumn.size()==SourceLine.size()+1); + assert(0 < m_byteToColumn.size() && 0 < m_columnToByte.size()); + assert(m_byteToColumn.size() + == static_cast<unsigned>(m_columnToByte.back()+1)); + assert(static_cast<unsigned>(m_byteToColumn.back()+1) + == m_columnToByte.size()); + } + int columns() const { return m_byteToColumn.back(); } + int bytes() const { return m_columnToByte.back(); } + int byteToColumn(int n) const { + assert(0<=n && n<static_cast<int>(m_byteToColumn.size())); + return m_byteToColumn[n]; + } + int columnToByte(int n) const { + assert(0<=n && n<static_cast<int>(m_columnToByte.size())); + return m_columnToByte[n]; + } + StringRef getSourceLine() const { + return m_SourceLine; + } + +private: + const std::string m_SourceLine; + SmallVector<int,200> m_byteToColumn; + SmallVector<int,200> m_columnToByte; +}; + +// used in assert in selectInterestingSourceRegion() +namespace { +struct char_out_of_range { + const char lower,upper; + char_out_of_range(char lower, char upper) : + lower(lower), upper(upper) {} + bool operator()(char c) { return c < lower || upper < c; } +}; +} + /// \brief When the source code line we want to print is too long for /// the terminal, select the "interesting" region. static void selectInterestingSourceRegion(std::string &SourceLine, std::string &CaretLine, std::string &FixItInsertionLine, - unsigned EndOfCaretToken, - unsigned Columns) { - unsigned MaxSize = std::max(SourceLine.size(), - std::max(CaretLine.size(), - FixItInsertionLine.size())); - if (MaxSize > SourceLine.size()) - SourceLine.resize(MaxSize, ' '); - if (MaxSize > CaretLine.size()) - CaretLine.resize(MaxSize, ' '); - if (!FixItInsertionLine.empty() && MaxSize > FixItInsertionLine.size()) - FixItInsertionLine.resize(MaxSize, ' '); - + unsigned Columns, + const SourceColumnMap &map) { + unsigned MaxColumns = std::max<unsigned>(map.columns(), + std::max(CaretLine.size(), + FixItInsertionLine.size())); + // if the number of columns is less than the desired number we're done + if (MaxColumns <= Columns) + return; + + // no special characters allowed in CaretLine or FixItInsertionLine + assert(CaretLine.end() == + std::find_if(CaretLine.begin(), CaretLine.end(), + char_out_of_range(' ','~'))); + assert(FixItInsertionLine.end() == + std::find_if(FixItInsertionLine.begin(), FixItInsertionLine.end(), + char_out_of_range(' ','~'))); + // Find the slice that we need to display the full caret line // correctly. unsigned CaretStart = 0, CaretEnd = CaretLine.size(); @@ -64,10 +314,8 @@ static void selectInterestingSourceRegion(std::string &SourceLine, if (!isspace(CaretLine[CaretEnd - 1])) break; - // Make sure we don't chop the string shorter than the caret token - // itself. - if (CaretEnd < EndOfCaretToken) - CaretEnd = EndOfCaretToken; + // caret has already been inserted into CaretLine so the above whitespace + // check is guaranteed to include the caret // If we have a fix-it line, make sure the slice includes all of the // fix-it information. @@ -81,10 +329,8 @@ static void selectInterestingSourceRegion(std::string &SourceLine, if (!isspace(FixItInsertionLine[FixItEnd - 1])) break; - if (FixItStart < CaretStart) - CaretStart = FixItStart; - if (FixItEnd > CaretEnd) - CaretEnd = FixItEnd; + CaretStart = std::min(FixItStart, CaretStart); + CaretEnd = std::max(FixItEnd, CaretEnd); } // CaretLine[CaretStart, CaretEnd) contains all of the interesting @@ -92,62 +338,72 @@ static void selectInterestingSourceRegion(std::string &SourceLine, // number of columns we have, try to grow the slice to encompass // more context. - // If the end of the interesting region comes before we run out of - // space in the terminal, start at the beginning of the line. - if (Columns > 3 && CaretEnd < Columns - 3) - CaretStart = 0; + unsigned SourceStart = map.columnToByte(std::min<unsigned>(CaretStart, + map.columns())); + unsigned SourceEnd = map.columnToByte(std::min<unsigned>(CaretEnd, + map.columns())); + + unsigned CaretColumnsOutsideSource = CaretEnd-CaretStart + - (map.byteToColumn(SourceEnd)-map.byteToColumn(SourceStart)); + + char const *front_ellipse = " ..."; + char const *front_space = " "; + char const *back_ellipse = "..."; + unsigned ellipses_space = strlen(front_ellipse) + strlen(back_ellipse); unsigned TargetColumns = Columns; - if (TargetColumns > 8) - TargetColumns -= 8; // Give us extra room for the ellipses. - unsigned SourceLength = SourceLine.size(); - while ((CaretEnd - CaretStart) < TargetColumns) { + // Give us extra room for the ellipses + // and any of the caret line that extends past the source + if (TargetColumns > ellipses_space+CaretColumnsOutsideSource) + TargetColumns -= ellipses_space+CaretColumnsOutsideSource; + + while (SourceStart>0 || SourceEnd<SourceLine.size()) { bool ExpandedRegion = false; - // Move the start of the interesting region left until we've - // pulled in something else interesting. - if (CaretStart == 1) - CaretStart = 0; - else if (CaretStart > 1) { - unsigned NewStart = CaretStart - 1; + + if (SourceStart>0) { + unsigned NewStart = SourceStart-1; // Skip over any whitespace we see here; we're looking for // another bit of interesting text. - while (NewStart && isspace(SourceLine[NewStart])) + while (NewStart && + (map.byteToColumn(NewStart)==-1 || isspace(SourceLine[NewStart]))) --NewStart; // Skip over this bit of "interesting" text. - while (NewStart && !isspace(SourceLine[NewStart])) + while (NewStart && + (map.byteToColumn(NewStart)!=-1 && !isspace(SourceLine[NewStart]))) --NewStart; // Move up to the non-whitespace character we just saw. if (NewStart) ++NewStart; - // If we're still within our limit, update the starting - // position within the source/caret line. - if (CaretEnd - NewStart <= TargetColumns) { - CaretStart = NewStart; + unsigned NewColumns = map.byteToColumn(SourceEnd) - + map.byteToColumn(NewStart); + if (NewColumns <= TargetColumns) { + SourceStart = NewStart; ExpandedRegion = true; } } - // Move the end of the interesting region right until we've - // pulled in something else interesting. - if (CaretEnd != SourceLength) { - assert(CaretEnd < SourceLength && "Unexpected caret position!"); - unsigned NewEnd = CaretEnd; + if (SourceEnd<SourceLine.size()) { + unsigned NewEnd = SourceEnd+1; // Skip over any whitespace we see here; we're looking for // another bit of interesting text. - while (NewEnd != SourceLength && isspace(SourceLine[NewEnd - 1])) + while (NewEnd<SourceLine.size() && + (map.byteToColumn(NewEnd)==-1 || isspace(SourceLine[NewEnd]))) ++NewEnd; // Skip over this bit of "interesting" text. - while (NewEnd != SourceLength && !isspace(SourceLine[NewEnd - 1])) + while (NewEnd<SourceLine.size() && + (map.byteToColumn(NewEnd)!=-1 && !isspace(SourceLine[NewEnd]))) ++NewEnd; - if (NewEnd - CaretStart <= TargetColumns) { - CaretEnd = NewEnd; + unsigned NewColumns = map.byteToColumn(NewEnd) - + map.byteToColumn(SourceStart); + if (NewColumns <= TargetColumns) { + SourceEnd = NewEnd; ExpandedRegion = true; } } @@ -156,21 +412,41 @@ static void selectInterestingSourceRegion(std::string &SourceLine, break; } + CaretStart = map.byteToColumn(SourceStart); + CaretEnd = map.byteToColumn(SourceEnd) + CaretColumnsOutsideSource; + // [CaretStart, CaretEnd) is the slice we want. Update the various // output lines to show only this slice, with two-space padding // before the lines so that it looks nicer. - if (CaretEnd < SourceLine.size()) - SourceLine.replace(CaretEnd, std::string::npos, "..."); - if (CaretEnd < CaretLine.size()) - CaretLine.erase(CaretEnd, std::string::npos); - if (FixItInsertionLine.size() > CaretEnd) - FixItInsertionLine.erase(CaretEnd, std::string::npos); - - if (CaretStart > 2) { - SourceLine.replace(0, CaretStart, " ..."); - CaretLine.replace(0, CaretStart, " "); - if (FixItInsertionLine.size() >= CaretStart) - FixItInsertionLine.replace(0, CaretStart, " "); + + assert(CaretStart!=(unsigned)-1 && CaretEnd!=(unsigned)-1 && + SourceStart!=(unsigned)-1 && SourceEnd!=(unsigned)-1); + assert(SourceStart <= SourceEnd); + assert(CaretStart <= CaretEnd); + + unsigned BackColumnsRemoved + = map.byteToColumn(SourceLine.size())-map.byteToColumn(SourceEnd); + unsigned FrontColumnsRemoved = CaretStart; + unsigned ColumnsKept = CaretEnd-CaretStart; + + // We checked up front that the line needed truncation + assert(FrontColumnsRemoved+ColumnsKept+BackColumnsRemoved > Columns); + + // The line needs some trunctiona, and we'd prefer to keep the front + // if possible, so remove the back + if (BackColumnsRemoved) + SourceLine.replace(SourceEnd, std::string::npos, back_ellipse); + + // If that's enough then we're done + if (FrontColumnsRemoved+ColumnsKept <= Columns) + return; + + // Otherwise remove the front as well + if (FrontColumnsRemoved) { + SourceLine.replace(0, SourceStart, front_ellipse); + CaretLine.replace(0, CaretStart, front_space); + if (!FixItInsertionLine.empty()) + FixItInsertionLine.replace(0, CaretStart, front_space); } } @@ -564,10 +840,13 @@ void TextDiagnostic::emitSnippetAndCaret( // Get information about the buffer it points into. bool Invalid = false; - const char *BufStart = SM.getBufferData(FID, &Invalid).data(); + StringRef BufData = SM.getBufferData(FID, &Invalid); if (Invalid) return; + const char *BufStart = BufData.data(); + const char *BufEnd = BufStart + BufData.size(); + unsigned LineNo = SM.getLineNumber(FID, FileOffset); unsigned ColNo = SM.getColumnNumber(FID, FileOffset); unsigned CaretEndColNo @@ -581,7 +860,7 @@ void TextDiagnostic::emitSnippetAndCaret( // Compute the line end. Scan forward from the error position to the end of // the line. const char *LineEnd = TokPtr; - while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0') + while (*LineEnd != '\n' && *LineEnd != '\r' && LineEnd!=BufEnd) ++LineEnd; // FIXME: This shouldn't be necessary, but the CaretEndColNo can extend past @@ -596,19 +875,30 @@ void TextDiagnostic::emitSnippetAndCaret( // length as the line of source code. std::string CaretLine(LineEnd-LineStart, ' '); + const SourceColumnMap sourceColMap(SourceLine, DiagOpts.TabStop); + // Highlight all of the characters covered by Ranges with ~ characters. for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(), E = Ranges.end(); I != E; ++I) - highlightRange(*I, LineNo, FID, SourceLine, CaretLine); + highlightRange(*I, LineNo, FID, sourceColMap, CaretLine); // Next, insert the caret itself. - if (ColNo-1 < CaretLine.size()) - CaretLine[ColNo-1] = '^'; - else - CaretLine.push_back('^'); + ColNo = sourceColMap.byteToColumn(ColNo-1); + if (CaretLine.size()<ColNo+1) + CaretLine.resize(ColNo+1, ' '); + CaretLine[ColNo] = '^'; + + std::string FixItInsertionLine = buildFixItInsertionLine(LineNo, + sourceColMap, + Hints); - expandTabs(SourceLine, CaretLine); + // If the source line is too long for our terminal, select only the + // "interesting" source region within that line. + unsigned Columns = DiagOpts.MessageLength; + if (Columns) + selectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine, + Columns, sourceColMap); // If we are in -fdiagnostics-print-source-range-info mode, we are trying // to produce easily machine parsable output. Add a space before the @@ -619,23 +909,12 @@ void TextDiagnostic::emitSnippetAndCaret( CaretLine = ' ' + CaretLine; } - std::string FixItInsertionLine = buildFixItInsertionLine(LineNo, - LineStart, LineEnd, - Hints); - - // If the source line is too long for our terminal, select only the - // "interesting" source region within that line. - unsigned Columns = DiagOpts.MessageLength; - if (Columns && SourceLine.size() > Columns) - selectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine, - CaretEndColNo, Columns); - // Finally, remove any blank spaces from the end of CaretLine. while (CaretLine[CaretLine.size()-1] == ' ') CaretLine.erase(CaretLine.end()-1); // Emit what we have computed. - OS << SourceLine << '\n'; + emitSnippet(SourceLine); if (DiagOpts.ShowColors) OS.changeColor(caretColor, true); @@ -658,13 +937,49 @@ void TextDiagnostic::emitSnippetAndCaret( emitParseableFixits(Hints); } +void TextDiagnostic::emitSnippet(StringRef line) +{ + if (line.empty()) + return; + + size_t i = 0; + + std::string to_print; + bool print_reversed = false; + + while (i<line.size()) { + std::pair<SmallString<16>,bool> res + = printableTextForNextCharacter(line, &i, DiagOpts.TabStop); + bool was_printable = res.second; + + if (DiagOpts.ShowColors + && was_printable==print_reversed) { + if (print_reversed) + OS.reverseColor(); + OS << to_print; + to_print.clear(); + if (DiagOpts.ShowColors) + OS.resetColor(); + } + + print_reversed = !was_printable; + to_print += res.first.str(); + } + + if (print_reversed && DiagOpts.ShowColors) + OS.reverseColor(); + OS << to_print; + if (print_reversed && DiagOpts.ShowColors) + OS.resetColor(); + + OS << '\n'; +} + /// \brief Highlight a SourceRange (with ~'s) for any characters on LineNo. void TextDiagnostic::highlightRange(const CharSourceRange &R, unsigned LineNo, FileID FID, - const std::string &SourceLine, + const SourceColumnMap &map, std::string &CaretLine) { - assert(CaretLine.size() == SourceLine.size() && - "Expect a correspondence between source and caret line!"); if (!R.isValid()) return; SourceLocation Begin = SM.getExpansionLoc(R.getBegin()); @@ -694,7 +1009,7 @@ void TextDiagnostic::highlightRange(const CharSourceRange &R, } // Compute the column number of the end. - unsigned EndColNo = CaretLine.size(); + unsigned EndColNo = map.getSourceLine().size(); if (EndLineNo == LineNo) { EndColNo = SM.getExpansionColumnNumber(End); if (EndColNo) { @@ -714,15 +1029,17 @@ void TextDiagnostic::highlightRange(const CharSourceRange &R, // Check that a token range does not highlight only whitespace. if (R.isTokenRange()) { // Pick the first non-whitespace column. - while (StartColNo < SourceLine.size() && - (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t')) + while (StartColNo < map.getSourceLine().size() && + (map.getSourceLine()[StartColNo] == ' ' || + map.getSourceLine()[StartColNo] == '\t')) ++StartColNo; // Pick the last non-whitespace column. - if (EndColNo > SourceLine.size()) - EndColNo = SourceLine.size(); + if (EndColNo > map.getSourceLine().size()) + EndColNo = map.getSourceLine().size(); while (EndColNo-1 && - (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t')) + (map.getSourceLine()[EndColNo-1] == ' ' || + map.getSourceLine()[EndColNo-1] == '\t')) --EndColNo; // If the start/end passed each other, then we are trying to highlight a @@ -731,15 +1048,24 @@ void TextDiagnostic::highlightRange(const CharSourceRange &R, assert(StartColNo <= EndColNo && "Trying to highlight whitespace??"); } + assert(StartColNo <= map.getSourceLine().size() && "Invalid range!"); + assert(EndColNo <= map.getSourceLine().size() && "Invalid range!"); + // Fill the range with ~'s. - for (unsigned i = StartColNo; i < EndColNo; ++i) - CaretLine[i] = '~'; + StartColNo = map.byteToColumn(StartColNo); + EndColNo = map.byteToColumn(EndColNo); + + assert(StartColNo <= EndColNo && "Invalid range!"); + if (CaretLine.size() < EndColNo) + CaretLine.resize(EndColNo,' '); + std::fill(CaretLine.begin()+StartColNo,CaretLine.begin()+EndColNo,'~'); } -std::string TextDiagnostic::buildFixItInsertionLine(unsigned LineNo, - const char *LineStart, - const char *LineEnd, - ArrayRef<FixItHint> Hints) { +std::string TextDiagnostic::buildFixItInsertionLine( + unsigned LineNo, + const SourceColumnMap &map, + ArrayRef<FixItHint> Hints) { + std::string FixItInsertionLine; if (Hints.empty() || !DiagOpts.ShowFixits) return FixItInsertionLine; @@ -755,13 +1081,32 @@ std::string TextDiagnostic::buildFixItInsertionLine(unsigned LineNo, // Insert the new code into the line just below the code // that the user wrote. unsigned HintColNo - = SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second); + = SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second) - 1; + // hint must start inside the source or right at the end + assert(HintColNo<static_cast<unsigned>(map.bytes())+1); + HintColNo = map.byteToColumn(HintColNo); + + // FIXME: if the fixit includes tabs or other characters that do not + // take up a single column per byte when displayed then + // I->CodeToInsert.size() is not a column number and we're mixing + // units (columns + bytes). We should get printable versions + // of each fixit before using them. unsigned LastColumnModified - = HintColNo - 1 + I->CodeToInsert.size(); + = HintColNo + I->CodeToInsert.size(); + + if (LastColumnModified > static_cast<unsigned>(map.bytes())) { + unsigned LastExistingColumn = map.byteToColumn(map.bytes()); + unsigned AddedColumns = LastColumnModified-LastExistingColumn; + LastColumnModified = LastExistingColumn + AddedColumns; + } else { + LastColumnModified = map.byteToColumn(LastColumnModified); + } + if (LastColumnModified > FixItInsertionLine.size()) FixItInsertionLine.resize(LastColumnModified, ' '); + assert(HintColNo+I->CodeToInsert.size() <= FixItInsertionLine.size()); std::copy(I->CodeToInsert.begin(), I->CodeToInsert.end(), - FixItInsertionLine.begin() + HintColNo - 1); + FixItInsertionLine.begin() + HintColNo); } else { FixItInsertionLine.clear(); break; @@ -769,72 +1114,11 @@ std::string TextDiagnostic::buildFixItInsertionLine(unsigned LineNo, } } - if (FixItInsertionLine.empty()) - return FixItInsertionLine; - - // Now that we have the entire fixit line, expand the tabs in it. - // Since we don't want to insert spaces in the middle of a word, - // find each word and the column it should line up with and insert - // spaces until they match. - unsigned FixItPos = 0; - unsigned LinePos = 0; - unsigned TabExpandedCol = 0; - unsigned LineLength = LineEnd - LineStart; - - while (FixItPos < FixItInsertionLine.size() && LinePos < LineLength) { - // Find the next word in the FixIt line. - while (FixItPos < FixItInsertionLine.size() && - FixItInsertionLine[FixItPos] == ' ') - ++FixItPos; - unsigned CharDistance = FixItPos - TabExpandedCol; - - // Walk forward in the source line, keeping track of - // the tab-expanded column. - for (unsigned I = 0; I < CharDistance; ++I, ++LinePos) - if (LinePos >= LineLength || LineStart[LinePos] != '\t') - ++TabExpandedCol; - else - TabExpandedCol = - (TabExpandedCol/DiagOpts.TabStop + 1) * DiagOpts.TabStop; - - // Adjust the fixit line to match this column. - FixItInsertionLine.insert(FixItPos, TabExpandedCol-FixItPos, ' '); - FixItPos = TabExpandedCol; - - // Walk to the end of the word. - while (FixItPos < FixItInsertionLine.size() && - FixItInsertionLine[FixItPos] != ' ') - ++FixItPos; - } + expandTabs(FixItInsertionLine, DiagOpts.TabStop); return FixItInsertionLine; } -void TextDiagnostic::expandTabs(std::string &SourceLine, - std::string &CaretLine) { - // Scan the source line, looking for tabs. If we find any, manually expand - // them to spaces and update the CaretLine to match. - for (unsigned i = 0; i != SourceLine.size(); ++i) { - if (SourceLine[i] != '\t') continue; - - // Replace this tab with at least one space. - SourceLine[i] = ' '; - - // Compute the number of spaces we need to insert. - unsigned TabStop = DiagOpts.TabStop; - assert(0 < TabStop && TabStop <= DiagnosticOptions::MaxTabStop && - "Invalid -ftabstop value"); - unsigned NumSpaces = ((i+TabStop)/TabStop * TabStop) - (i+1); - assert(NumSpaces < TabStop && "Invalid computation of space amt"); - - // Insert spaces into the SourceLine. - SourceLine.insert(i+1, NumSpaces, ' '); - - // Insert spaces or ~'s into CaretLine. - CaretLine.insert(i+1, NumSpaces, CaretLine[i] == '~' ? '~' : ' '); - } -} - void TextDiagnostic::emitParseableFixits(ArrayRef<FixItHint> Hints) { if (!DiagOpts.ShowParseableFixits) return; @@ -878,4 +1162,3 @@ void TextDiagnostic::emitParseableFixits(ArrayRef<FixItHint> Hints) { OS << "\"\n"; } } - diff --git a/contrib/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/contrib/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 2066505..07d2b8d 100644 --- a/contrib/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/contrib/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -72,7 +72,6 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { case PrintDeclContext: return new DeclContextPrintAction(); case PrintPreamble: return new PrintPreambleAction(); case PrintPreprocessedInput: return new PrintPreprocessedAction(); - case PubnamesDump: return new PubnamesDumpAction(); case RewriteMacros: return new RewriteMacrosAction(); case RewriteObjC: return new RewriteObjCAction(); case RewriteTest: return new RewriteTestAction(); diff --git a/contrib/llvm/tools/clang/lib/Headers/avx2intrin.h b/contrib/llvm/tools/clang/lib/Headers/avx2intrin.h index d165f1f..884c46d 100644 --- a/contrib/llvm/tools/clang/lib/Headers/avx2intrin.h +++ b/contrib/llvm/tools/clang/lib/Headers/avx2intrin.h @@ -822,7 +822,9 @@ _mm256_permutevar8x32_epi32(__m256i a, __m256i b) #define _mm256_permute4x64_pd(V, M) __extension__ ({ \ __m256d __V = (V); \ - (__m256d)__builtin_ia32_permdf256((__v4df)__V, (M)); }) + (__m256d)__builtin_shufflevector((__v4df)__V, (__v4df) _mm256_setzero_pd(), \ + (M) & 0x3, ((M) & 0xc) >> 2, \ + ((M) & 0x30) >> 4, ((M) & 0xc0) >> 6); }) static __inline__ __m256 __attribute__((__always_inline__, __nodebug__)) _mm256_permutevar8x32_ps(__m256 a, __m256 b) @@ -832,16 +834,14 @@ _mm256_permutevar8x32_ps(__m256 a, __m256 b) #define _mm256_permute4x64_epi64(V, M) __extension__ ({ \ __m256i __V = (V); \ - (__m256i)__builtin_ia32_permdi256(__V, (M)); }) + (__m256i)__builtin_shufflevector((__v4di)__V, (__v4di) _mm256_setzero_si256(), \ + (M) & 0x3, ((M) & 0xc) >> 2, \ + ((M) & 0x30) >> 4, ((M) & 0xc0) >> 6); }) #define _mm256_permute2x128_si256(V1, V2, M) __extension__ ({ \ __m256i __V1 = (V1); \ __m256i __V2 = (V2); \ - __builtin_shufflevector(__V1, __V2, \ - ((M) & 0x3) * 2, \ - ((M) & 0x3) * 2 + 1, \ - (((M) & 0x30) >> 4) * 2, \ - (((M) & 0x30) >> 4) * 2 + 1); }) + (__m256i)__builtin_ia32_permti256(__V1, __V2, (M)); }) #define _mm256_extracti128_si256(A, O) __extension__ ({ \ __m256i __A = (A); \ diff --git a/contrib/llvm/tools/clang/lib/Headers/avxintrin.h b/contrib/llvm/tools/clang/lib/Headers/avxintrin.h index 7a0ec3f..ee7f835 100644 --- a/contrib/llvm/tools/clang/lib/Headers/avxintrin.h +++ b/contrib/llvm/tools/clang/lib/Headers/avxintrin.h @@ -289,37 +289,17 @@ _mm256_permutevar_ps(__m256 a, __m256i c) #define _mm256_permute2f128_pd(V1, V2, M) __extension__ ({ \ __m256d __V1 = (V1); \ __m256d __V2 = (V2); \ - (__m256d)__builtin_shufflevector((__v4df)__V1, (__v4df)__V2, \ - ((M) & 0x3) * 2, \ - ((M) & 0x3) * 2 + 1, \ - (((M) & 0x30) >> 4) * 2, \ - (((M) & 0x30) >> 4) * 2 + 1); }) + (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)__V1, (__v4df)__V2, (M)); }) #define _mm256_permute2f128_ps(V1, V2, M) __extension__ ({ \ __m256 __V1 = (V1); \ __m256 __V2 = (V2); \ - (__m256)__builtin_shufflevector((__v8sf)__V1, (__v8sf)__V2, \ - ((M) & 0x3) * 4, \ - ((M) & 0x3) * 4 + 1, \ - ((M) & 0x3) * 4 + 2, \ - ((M) & 0x3) * 4 + 3, \ - (((M) & 0x30) >> 4) * 4, \ - (((M) & 0x30) >> 4) * 4 + 1, \ - (((M) & 0x30) >> 4) * 4 + 2, \ - (((M) & 0x30) >> 4) * 4 + 3); }) + (__m256)__builtin_ia32_vperm2f128_ps256((__v8sf)__V1, (__v8sf)__V2, (M)); }) #define _mm256_permute2f128_si256(V1, V2, M) __extension__ ({ \ __m256i __V1 = (V1); \ __m256i __V2 = (V2); \ - (__m256i)__builtin_shufflevector((__v8si)__V1, (__v8si)__V2, \ - ((M) & 0x3) * 4, \ - ((M) & 0x3) * 4 + 1, \ - ((M) & 0x3) * 4 + 2, \ - ((M) & 0x3) * 4 + 3, \ - (((M) & 0x30) >> 4) * 4, \ - (((M) & 0x30) >> 4) * 4 + 1, \ - (((M) & 0x30) >> 4) * 4 + 2, \ - (((M) & 0x30) >> 4) * 4 + 3); }) + (__m256i)__builtin_ia32_vperm2f128_si256((__v8si)__V1, (__v8si)__V2, (M)); }) /* Vector Blend */ #define _mm256_blend_pd(V1, V2, M) __extension__ ({ \ diff --git a/contrib/llvm/tools/clang/lib/Index/ASTLocation.cpp b/contrib/llvm/tools/clang/lib/Index/ASTLocation.cpp deleted file mode 100644 index fce6099..0000000 --- a/contrib/llvm/tools/clang/lib/Index/ASTLocation.cpp +++ /dev/null @@ -1,114 +0,0 @@ -//===--- ASTLocation.cpp - A <Decl, Stmt> pair ------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// ASTLocation is Decl or a Stmt and its immediate Decl parent. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/ASTLocation.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/Stmt.h" -#include "clang/AST/Expr.h" -#include "clang/AST/ExprObjC.h" -using namespace clang; -using namespace idx; - -static Decl *getDeclFromExpr(Stmt *E) { - if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) - return RefExpr->getDecl(); - if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) - return ME->getMemberDecl(); - if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) - return RE->getDecl(); - - if (CallExpr *CE = dyn_cast<CallExpr>(E)) - return getDeclFromExpr(CE->getCallee()); - if (CastExpr *CE = dyn_cast<CastExpr>(E)) - return getDeclFromExpr(CE->getSubExpr()); - - return 0; -} - -Decl *ASTLocation::getReferencedDecl() { - if (isInvalid()) - return 0; - - switch (getKind()) { - case N_Type: - return 0; - case N_Decl: - return D; - case N_NamedRef: - return NDRef.ND; - case N_Stmt: - return getDeclFromExpr(Stm); - } - - llvm_unreachable("Invalid ASTLocation Kind!"); -} - -SourceRange ASTLocation::getSourceRange() const { - if (isInvalid()) - return SourceRange(); - - switch (getKind()) { - case N_Decl: - return D->getSourceRange(); - case N_Stmt: - return Stm->getSourceRange(); - case N_NamedRef: - return SourceRange(AsNamedRef().Loc, AsNamedRef().Loc); - case N_Type: - return AsTypeLoc().getLocalSourceRange(); - } - - llvm_unreachable("Invalid ASTLocation Kind!"); -} - -void ASTLocation::print(raw_ostream &OS) const { - if (isInvalid()) { - OS << "<< Invalid ASTLocation >>\n"; - return; - } - - ASTContext &Ctx = getParentDecl()->getASTContext(); - - switch (getKind()) { - case N_Decl: - OS << "[Decl: " << AsDecl()->getDeclKindName() << " "; - if (const NamedDecl *ND = dyn_cast<NamedDecl>(AsDecl())) - OS << *ND; - break; - - case N_Stmt: - OS << "[Stmt: " << AsStmt()->getStmtClassName() << " "; - AsStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOpts())); - break; - - case N_NamedRef: - OS << "[NamedRef: " << AsNamedRef().ND->getDeclKindName() << " "; - OS << *AsNamedRef().ND; - break; - - case N_Type: { - QualType T = AsTypeLoc().getType(); - OS << "[Type: " << T->getTypeClassName() << " " << T.getAsString(); - } - } - - OS << "] <"; - - SourceRange Range = getSourceRange(); - SourceManager &SourceMgr = Ctx.getSourceManager(); - Range.getBegin().print(OS, SourceMgr); - OS << ", "; - Range.getEnd().print(OS, SourceMgr); - OS << ">\n"; -} diff --git a/contrib/llvm/tools/clang/lib/Index/ASTVisitor.h b/contrib/llvm/tools/clang/lib/Index/ASTVisitor.h deleted file mode 100644 index 0b8425b..0000000 --- a/contrib/llvm/tools/clang/lib/Index/ASTVisitor.h +++ /dev/null @@ -1,143 +0,0 @@ -//===--- ASTVisitor.h - Visitor for an ASTContext ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ASTVisitor interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_ASTVISITOR_H -#define LLVM_CLANG_INDEX_ASTVISITOR_H - -#include "clang/AST/DeclVisitor.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/AST/TypeLocVisitor.h" - -namespace clang { - -namespace idx { - -/// \brief Traverses the full AST, both Decls and Stmts. -template<typename ImplClass> -class ASTVisitor : public DeclVisitor<ImplClass>, - public StmtVisitor<ImplClass>, - public TypeLocVisitor<ImplClass> { -public: - ASTVisitor() : CurrentDecl(0) { } - - Decl *CurrentDecl; - - typedef ASTVisitor<ImplClass> Base; - typedef DeclVisitor<ImplClass> BaseDeclVisitor; - typedef StmtVisitor<ImplClass> BaseStmtVisitor; - typedef TypeLocVisitor<ImplClass> BaseTypeLocVisitor; - - using BaseStmtVisitor::Visit; - - //===--------------------------------------------------------------------===// - // DeclVisitor - //===--------------------------------------------------------------------===// - - void Visit(Decl *D) { - Decl *PrevDecl = CurrentDecl; - CurrentDecl = D; - BaseDeclVisitor::Visit(D); - CurrentDecl = PrevDecl; - } - - void VisitDeclaratorDecl(DeclaratorDecl *D) { - BaseDeclVisitor::VisitDeclaratorDecl(D); - if (TypeSourceInfo *TInfo = D->getTypeSourceInfo()) - Visit(TInfo->getTypeLoc()); - } - - void VisitFunctionDecl(FunctionDecl *D) { - BaseDeclVisitor::VisitFunctionDecl(D); - if (D->isThisDeclarationADefinition()) - Visit(D->getBody()); - } - - void VisitObjCMethodDecl(ObjCMethodDecl *D) { - BaseDeclVisitor::VisitObjCMethodDecl(D); - if (D->getBody()) - Visit(D->getBody()); - } - - void VisitBlockDecl(BlockDecl *D) { - BaseDeclVisitor::VisitBlockDecl(D); - Visit(D->getBody()); - } - - void VisitVarDecl(VarDecl *D) { - BaseDeclVisitor::VisitVarDecl(D); - if (Expr *Init = D->getInit()) - Visit(Init); - } - - void VisitDecl(Decl *D) { - if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)) - return; - - if (DeclContext *DC = dyn_cast<DeclContext>(D)) - static_cast<ImplClass*>(this)->VisitDeclContext(DC); - } - - void VisitDeclContext(DeclContext *DC) { - for (DeclContext::decl_iterator - I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) - Visit(*I); - } - - //===--------------------------------------------------------------------===// - // StmtVisitor - //===--------------------------------------------------------------------===// - - void VisitDeclStmt(DeclStmt *Node) { - for (DeclStmt::decl_iterator - I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) - Visit(*I); - } - - void VisitBlockExpr(BlockExpr *Node) { - // The BlockDecl is also visited by 'VisitDeclContext()'. No need to visit it twice. - } - - void VisitStmt(Stmt *Node) { - for (Stmt::child_range I = Node->children(); I; ++I) - if (*I) - Visit(*I); - } - - //===--------------------------------------------------------------------===// - // TypeLocVisitor - //===--------------------------------------------------------------------===// - - void Visit(TypeLoc TL) { - for (; TL; TL = TL.getNextTypeLoc()) - BaseTypeLocVisitor::Visit(TL); - } - - void VisitArrayLoc(ArrayTypeLoc TL) { - BaseTypeLocVisitor::VisitArrayTypeLoc(TL); - if (TL.getSizeExpr()) - Visit(TL.getSizeExpr()); - } - - void VisitFunctionTypeLoc(FunctionTypeLoc TL) { - BaseTypeLocVisitor::VisitFunctionTypeLoc(TL); - for (unsigned i = 0; i != TL.getNumArgs(); ++i) - Visit(TL.getArg(i)); - } - -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/lib/Index/Analyzer.cpp b/contrib/llvm/tools/clang/lib/Index/Analyzer.cpp deleted file mode 100644 index f77e6ef..0000000 --- a/contrib/llvm/tools/clang/lib/Index/Analyzer.cpp +++ /dev/null @@ -1,470 +0,0 @@ -//===--- Analyzer.cpp - Analysis for indexing information -------*- 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 the Analyzer interface. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/Analyzer.h" -#include "clang/Index/Entity.h" -#include "clang/Index/TranslationUnit.h" -#include "clang/Index/Handlers.h" -#include "clang/Index/ASTLocation.h" -#include "clang/Index/GlobalSelector.h" -#include "clang/Index/DeclReferenceMap.h" -#include "clang/Index/SelectorMap.h" -#include "clang/Index/IndexProvider.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/ExprObjC.h" -#include "llvm/ADT/SmallSet.h" -using namespace clang; -using namespace idx; - -namespace { - -//===----------------------------------------------------------------------===// -// DeclEntityAnalyzer Implementation -//===----------------------------------------------------------------------===// - -class DeclEntityAnalyzer : public TranslationUnitHandler { - Entity Ent; - TULocationHandler &TULocHandler; - -public: - DeclEntityAnalyzer(Entity ent, TULocationHandler &handler) - : Ent(ent), TULocHandler(handler) { } - - virtual void Handle(TranslationUnit *TU) { - assert(TU && "Passed null translation unit"); - - Decl *D = Ent.getDecl(TU->getASTContext()); - assert(D && "Couldn't resolve Entity"); - - for (Decl::redecl_iterator I = D->redecls_begin(), - E = D->redecls_end(); I != E; ++I) - TULocHandler.Handle(TULocation(TU, ASTLocation(*I))); - } -}; - -//===----------------------------------------------------------------------===// -// RefEntityAnalyzer Implementation -//===----------------------------------------------------------------------===// - -class RefEntityAnalyzer : public TranslationUnitHandler { - Entity Ent; - TULocationHandler &TULocHandler; - -public: - RefEntityAnalyzer(Entity ent, TULocationHandler &handler) - : Ent(ent), TULocHandler(handler) { } - - virtual void Handle(TranslationUnit *TU) { - assert(TU && "Passed null translation unit"); - - Decl *D = Ent.getDecl(TU->getASTContext()); - assert(D && "Couldn't resolve Entity"); - NamedDecl *ND = dyn_cast<NamedDecl>(D); - if (!ND) - return; - - DeclReferenceMap &RefMap = TU->getDeclReferenceMap(); - for (DeclReferenceMap::astlocation_iterator - I = RefMap.refs_begin(ND), E = RefMap.refs_end(ND); I != E; ++I) - TULocHandler.Handle(TULocation(TU, *I)); - } -}; - -//===----------------------------------------------------------------------===// -// RefSelectorAnalyzer Implementation -//===----------------------------------------------------------------------===// - -/// \brief Accepts an ObjC method and finds all message expressions that this -/// method may respond to. -class RefSelectorAnalyzer : public TranslationUnitHandler { - Program &Prog; - TULocationHandler &TULocHandler; - - // The original ObjCInterface associated with the method. - Entity IFaceEnt; - GlobalSelector GlobSel; - bool IsInstanceMethod; - - /// \brief Super classes of the ObjCInterface. - typedef llvm::SmallSet<Entity, 16> EntitiesSetTy; - EntitiesSetTy HierarchyEntities; - -public: - RefSelectorAnalyzer(ObjCMethodDecl *MD, - Program &prog, TULocationHandler &handler) - : Prog(prog), TULocHandler(handler) { - assert(MD); - - // FIXME: Protocol methods. - assert(!isa<ObjCProtocolDecl>(MD->getDeclContext()) && - "Protocol methods not supported yet"); - - ObjCInterfaceDecl *IFD = MD->getClassInterface(); - assert(IFD); - IFaceEnt = Entity::get(IFD, Prog); - GlobSel = GlobalSelector::get(MD->getSelector(), Prog); - IsInstanceMethod = MD->isInstanceMethod(); - - for (ObjCInterfaceDecl *Cls = IFD->getSuperClass(); - Cls; Cls = Cls->getSuperClass()) - HierarchyEntities.insert(Entity::get(Cls, Prog)); - } - - virtual void Handle(TranslationUnit *TU) { - assert(TU && "Passed null translation unit"); - - ASTContext &Ctx = TU->getASTContext(); - // Null means it doesn't exist in this translation unit. - ObjCInterfaceDecl *IFace = - cast_or_null<ObjCInterfaceDecl>(IFaceEnt.getDecl(Ctx)); - Selector Sel = GlobSel.getSelector(Ctx); - - SelectorMap &SelMap = TU->getSelectorMap(); - for (SelectorMap::astlocation_iterator - I = SelMap.refs_begin(Sel), E = SelMap.refs_end(Sel); I != E; ++I) { - if (ValidReference(*I, IFace)) - TULocHandler.Handle(TULocation(TU, *I)); - } - } - - /// \brief Determines whether the given message expression is likely to end - /// up at the given interface decl. - /// - /// It returns true "eagerly", meaning it will return false only if it can - /// "prove" statically that the interface cannot accept this message. - bool ValidReference(ASTLocation ASTLoc, ObjCInterfaceDecl *IFace) { - assert(ASTLoc.isStmt()); - - // FIXME: Finding @selector references should be through another Analyzer - // method, like FindSelectors. - if (isa<ObjCSelectorExpr>(ASTLoc.AsStmt())) - return false; - - ObjCInterfaceDecl *MsgD = 0; - ObjCMessageExpr *Msg = cast<ObjCMessageExpr>(ASTLoc.AsStmt()); - - switch (Msg->getReceiverKind()) { - case ObjCMessageExpr::Instance: { - const ObjCObjectPointerType *OPT = - Msg->getInstanceReceiver()->getType()->getAsObjCInterfacePointerType(); - - // Can be anything! Accept it as a possibility.. - if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()) - return true; - - // Expecting class method. - if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) - return !IsInstanceMethod; - - MsgD = OPT->getInterfaceDecl(); - assert(MsgD); - - // Should be an instance method. - if (!IsInstanceMethod) - return false; - break; - } - - case ObjCMessageExpr::Class: { - // Expecting class method. - if (IsInstanceMethod) - return false; - - MsgD = Msg->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); - break; - } - - case ObjCMessageExpr::SuperClass: - // Expecting class method. - if (IsInstanceMethod) - return false; - - MsgD = Msg->getSuperType()->getAs<ObjCObjectType>()->getInterface(); - break; - - case ObjCMessageExpr::SuperInstance: - // Expecting instance method. - if (!IsInstanceMethod) - return false; - - MsgD = Msg->getSuperType()->getAs<ObjCObjectPointerType>() - ->getInterfaceDecl(); - break; - } - - assert(MsgD); - - // Same interface ? We have a winner! - if (declaresSameEntity(MsgD, IFace)) - return true; - - // If the message interface is a superclass of the original interface, - // accept this message as a possibility. - if (HierarchyEntities.count(Entity::get(MsgD, Prog))) - return true; - - // If the message interface is a subclass of the original interface, accept - // the message unless there is a subclass in the hierarchy that will - // "steal" the message (thus the message "will go" to the subclass and not - /// the original interface). - if (IFace) { - Selector Sel = Msg->getSelector(); - for (ObjCInterfaceDecl *Cls = MsgD; Cls; Cls = Cls->getSuperClass()) { - if (declaresSameEntity(Cls, IFace)) - return true; - if (Cls->getMethod(Sel, IsInstanceMethod)) - return false; - } - } - - // The interfaces are unrelated, don't accept the message. - return false; - } -}; - -//===----------------------------------------------------------------------===// -// MessageAnalyzer Implementation -//===----------------------------------------------------------------------===// - -/// \brief Accepts an ObjC message expression and finds all methods that may -/// respond to it. -class MessageAnalyzer : public TranslationUnitHandler { - Program &Prog; - TULocationHandler &TULocHandler; - - // The ObjCInterface associated with the message. Can be null/invalid. - Entity MsgIFaceEnt; - GlobalSelector GlobSel; - bool CanBeInstanceMethod; - bool CanBeClassMethod; - - /// \brief Super classes of the ObjCInterface. - typedef llvm::SmallSet<Entity, 16> EntitiesSetTy; - EntitiesSetTy HierarchyEntities; - - /// \brief The interface in the message interface hierarchy that "intercepts" - /// the selector. - Entity ReceiverIFaceEnt; - -public: - MessageAnalyzer(ObjCMessageExpr *Msg, - Program &prog, TULocationHandler &handler) - : Prog(prog), TULocHandler(handler), - CanBeInstanceMethod(false), - CanBeClassMethod(false) { - - assert(Msg); - - ObjCInterfaceDecl *MsgD = 0; - - while (true) { - switch (Msg->getReceiverKind()) { - case ObjCMessageExpr::Instance: { - const ObjCObjectPointerType *OPT = - Msg->getInstanceReceiver()->getType() - ->getAsObjCInterfacePointerType(); - - if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()) { - CanBeInstanceMethod = CanBeClassMethod = true; - break; - } - - if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) { - CanBeClassMethod = true; - break; - } - - MsgD = OPT->getInterfaceDecl(); - assert(MsgD); - CanBeInstanceMethod = true; - break; - } - - case ObjCMessageExpr::Class: - CanBeClassMethod = true; - MsgD = Msg->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); - break; - - case ObjCMessageExpr::SuperClass: - CanBeClassMethod = true; - MsgD = Msg->getSuperType()->getAs<ObjCObjectType>()->getInterface(); - break; - - case ObjCMessageExpr::SuperInstance: - CanBeInstanceMethod = true; - MsgD = Msg->getSuperType()->getAs<ObjCObjectPointerType>() - ->getInterfaceDecl(); - break; - } - } - - assert(CanBeInstanceMethod || CanBeClassMethod); - - Selector sel = Msg->getSelector(); - assert(!sel.isNull()); - - MsgIFaceEnt = Entity::get(MsgD, Prog); - GlobSel = GlobalSelector::get(sel, Prog); - - if (MsgD) { - for (ObjCInterfaceDecl *Cls = MsgD->getSuperClass(); - Cls; Cls = Cls->getSuperClass()) - HierarchyEntities.insert(Entity::get(Cls, Prog)); - - // Find the interface in the hierarchy that "receives" the message. - for (ObjCInterfaceDecl *Cls = MsgD; Cls; Cls = Cls->getSuperClass()) { - bool isReceiver = false; - - ObjCInterfaceDecl::lookup_const_iterator Meth, MethEnd; - for (llvm::tie(Meth, MethEnd) = Cls->lookup(sel); - Meth != MethEnd; ++Meth) { - if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth)) - if ((MD->isInstanceMethod() && CanBeInstanceMethod) || - (MD->isClassMethod() && CanBeClassMethod)) { - isReceiver = true; - break; - } - } - - if (isReceiver) { - ReceiverIFaceEnt = Entity::get(Cls, Prog); - break; - } - } - } - } - - virtual void Handle(TranslationUnit *TU) { - assert(TU && "Passed null translation unit"); - ASTContext &Ctx = TU->getASTContext(); - - // Null means it doesn't exist in this translation unit or there was no - // interface that was determined to receive the original message. - ObjCInterfaceDecl *ReceiverIFace = - cast_or_null<ObjCInterfaceDecl>(ReceiverIFaceEnt.getDecl(Ctx)); - - // No subclass for the original receiver interface, so it remains the - // receiver. - if (ReceiverIFaceEnt.isValid() && ReceiverIFace == 0) - return; - - // Null means it doesn't exist in this translation unit or there was no - // interface associated with the message in the first place. - ObjCInterfaceDecl *MsgIFace = - cast_or_null<ObjCInterfaceDecl>(MsgIFaceEnt.getDecl(Ctx)); - - Selector Sel = GlobSel.getSelector(Ctx); - SelectorMap &SelMap = TU->getSelectorMap(); - for (SelectorMap::method_iterator - I = SelMap.methods_begin(Sel), E = SelMap.methods_end(Sel); - I != E; ++I) { - ObjCMethodDecl *D = *I; - if (ValidMethod(D, MsgIFace, ReceiverIFace)) { - for (ObjCMethodDecl::redecl_iterator - RI = D->redecls_begin(), RE = D->redecls_end(); RI != RE; ++RI) - TULocHandler.Handle(TULocation(TU, ASTLocation(*RI))); - } - } - } - - /// \brief Determines whether the given method is likely to accept the - /// original message. - /// - /// It returns true "eagerly", meaning it will return false only if it can - /// "prove" statically that the method cannot accept the original message. - bool ValidMethod(ObjCMethodDecl *D, ObjCInterfaceDecl *MsgIFace, - ObjCInterfaceDecl *ReceiverIFace) { - assert(D); - - // FIXME: Protocol methods ? - if (isa<ObjCProtocolDecl>(D->getDeclContext())) - return false; - - // No specific interface associated with the message. Can be anything. - if (MsgIFaceEnt.isInvalid()) - return true; - - if ((!CanBeInstanceMethod && D->isInstanceMethod()) || - (!CanBeClassMethod && D->isClassMethod())) - return false; - - ObjCInterfaceDecl *IFace = D->getClassInterface(); - assert(IFace); - - // If the original message interface is the same or a superclass of the - // given interface, accept the method as a possibility. - if (MsgIFace && MsgIFace->isSuperClassOf(IFace)) - return true; - - if (ReceiverIFace) { - // The given interface, "overrides" the receiver. - if (ReceiverIFace->isSuperClassOf(IFace)) - return true; - } else { - // No receiver was found for the original message. - assert(ReceiverIFaceEnt.isInvalid()); - - // If the original message interface is a subclass of the given interface, - // accept the message. - if (HierarchyEntities.count(Entity::get(IFace, Prog))) - return true; - } - - // The interfaces are unrelated, or the receiver interface wasn't - // "overriden". - return false; - } -}; - -} // end anonymous namespace - -//===----------------------------------------------------------------------===// -// Analyzer Implementation -//===----------------------------------------------------------------------===// - -void Analyzer::FindDeclarations(Decl *D, TULocationHandler &Handler) { - assert(D && "Passed null declaration"); - Entity Ent = Entity::get(D, Prog); - if (Ent.isInvalid()) - return; - - DeclEntityAnalyzer DEA(Ent, Handler); - Idxer.GetTranslationUnitsFor(Ent, DEA); -} - -void Analyzer::FindReferences(Decl *D, TULocationHandler &Handler) { - assert(D && "Passed null declaration"); - if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { - RefSelectorAnalyzer RSA(MD, Prog, Handler); - GlobalSelector Sel = GlobalSelector::get(MD->getSelector(), Prog); - Idxer.GetTranslationUnitsFor(Sel, RSA); - return; - } - - Entity Ent = Entity::get(D, Prog); - if (Ent.isInvalid()) - return; - - RefEntityAnalyzer REA(Ent, Handler); - Idxer.GetTranslationUnitsFor(Ent, REA); -} - -/// \brief Find methods that may respond to the given message and pass them -/// to Handler. -void Analyzer::FindObjCMethods(ObjCMessageExpr *Msg, - TULocationHandler &Handler) { - assert(Msg); - MessageAnalyzer MsgAnalyz(Msg, Prog, Handler); - GlobalSelector GlobSel = GlobalSelector::get(Msg->getSelector(), Prog); - Idxer.GetTranslationUnitsFor(GlobSel, MsgAnalyz); -} diff --git a/contrib/llvm/tools/clang/lib/Index/DeclReferenceMap.cpp b/contrib/llvm/tools/clang/lib/Index/DeclReferenceMap.cpp deleted file mode 100644 index 3fd4336..0000000 --- a/contrib/llvm/tools/clang/lib/Index/DeclReferenceMap.cpp +++ /dev/null @@ -1,90 +0,0 @@ -//===--- DeclReferenceMap.cpp - Map Decls to their references -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// DeclReferenceMap creates a mapping from Decls to the ASTLocations that -// reference them. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/DeclReferenceMap.h" -#include "clang/Index/ASTLocation.h" -#include "ASTVisitor.h" -using namespace clang; -using namespace idx; - -namespace { - -class RefMapper : public ASTVisitor<RefMapper> { - DeclReferenceMap::MapTy ⤅ - -public: - RefMapper(DeclReferenceMap::MapTy &map) : Map(map) { } - - void VisitDeclRefExpr(DeclRefExpr *Node); - void VisitMemberExpr(MemberExpr *Node); - void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); - - void VisitTypedefTypeLoc(TypedefTypeLoc TL); - void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); -}; - -} // anonymous namespace - -//===----------------------------------------------------------------------===// -// RefMapper Implementation -//===----------------------------------------------------------------------===// - -void RefMapper::VisitDeclRefExpr(DeclRefExpr *Node) { - NamedDecl *PrimD = cast<NamedDecl>(Node->getDecl()->getCanonicalDecl()); - Map.insert(std::make_pair(PrimD, ASTLocation(CurrentDecl, Node))); -} - -void RefMapper::VisitMemberExpr(MemberExpr *Node) { - NamedDecl *PrimD = cast<NamedDecl>(Node->getMemberDecl()->getCanonicalDecl()); - Map.insert(std::make_pair(PrimD, ASTLocation(CurrentDecl, Node))); -} - -void RefMapper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { - Map.insert(std::make_pair(Node->getDecl(), ASTLocation(CurrentDecl, Node))); -} - -void RefMapper::VisitTypedefTypeLoc(TypedefTypeLoc TL) { - NamedDecl *ND = TL.getTypedefNameDecl(); - Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc()))); -} - -void RefMapper::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { - NamedDecl *ND = TL.getIFaceDecl(); - Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc()))); -} - -//===----------------------------------------------------------------------===// -// DeclReferenceMap Implementation -//===----------------------------------------------------------------------===// - -DeclReferenceMap::DeclReferenceMap(ASTContext &Ctx) { - RefMapper(Map).Visit(Ctx.getTranslationUnitDecl()); -} - -DeclReferenceMap::astlocation_iterator -DeclReferenceMap::refs_begin(NamedDecl *D) const { - NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl()); - return astlocation_iterator(Map.lower_bound(Prim)); -} - -DeclReferenceMap::astlocation_iterator -DeclReferenceMap::refs_end(NamedDecl *D) const { - NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl()); - return astlocation_iterator(Map.upper_bound(Prim)); -} - -bool DeclReferenceMap::refs_empty(NamedDecl *D) const { - NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl()); - return refs_begin(Prim) == refs_end(Prim); -} diff --git a/contrib/llvm/tools/clang/lib/Index/Entity.cpp b/contrib/llvm/tools/clang/lib/Index/Entity.cpp deleted file mode 100644 index fbab6d8..0000000 --- a/contrib/llvm/tools/clang/lib/Index/Entity.cpp +++ /dev/null @@ -1,270 +0,0 @@ -//===--- Entity.cpp - Cross-translation-unit "token" for decls ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Entity is a ASTContext-independent way to refer to declarations that are -// visible across translation units. -// -//===----------------------------------------------------------------------===// - -#include "EntityImpl.h" -#include "ProgramImpl.h" -#include "clang/Index/Program.h" -#include "clang/Index/GlobalSelector.h" -#include "clang/AST/Decl.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/DeclVisitor.h" -using namespace clang; -using namespace idx; - -// FIXME: Entity is really really basic currently, mostly written to work -// on variables and functions. Should support types and other decls eventually.. - - -//===----------------------------------------------------------------------===// -// EntityGetter -//===----------------------------------------------------------------------===// - -namespace clang { -namespace idx { - -/// \brief Gets the Entity associated with a Decl. -class EntityGetter : public DeclVisitor<EntityGetter, Entity> { - Program &Prog; - ProgramImpl &ProgImpl; - -public: - EntityGetter(Program &prog, ProgramImpl &progImpl) - : Prog(prog), ProgImpl(progImpl) { } - - // Get an Entity. - Entity getEntity(Entity Parent, DeclarationName Name, - unsigned IdNS, bool isObjCInstanceMethod); - - // Get an Entity associated with the name in the global namespace. - Entity getGlobalEntity(StringRef Name); - - Entity VisitNamedDecl(NamedDecl *D); - Entity VisitVarDecl(VarDecl *D); - Entity VisitFieldDecl(FieldDecl *D); - Entity VisitFunctionDecl(FunctionDecl *D); - Entity VisitTypeDecl(TypeDecl *D); -}; - -} -} - -Entity EntityGetter::getEntity(Entity Parent, DeclarationName Name, - unsigned IdNS, bool isObjCInstanceMethod) { - llvm::FoldingSetNodeID ID; - EntityImpl::Profile(ID, Parent, Name, IdNS, isObjCInstanceMethod); - - ProgramImpl::EntitySetTy &Entities = ProgImpl.getEntities(); - void *InsertPos = 0; - if (EntityImpl *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos)) - return Entity(Ent); - - void *Buf = ProgImpl.Allocate(sizeof(EntityImpl)); - EntityImpl *New = - new (Buf) EntityImpl(Parent, Name, IdNS, isObjCInstanceMethod); - Entities.InsertNode(New, InsertPos); - - return Entity(New); -} - -Entity EntityGetter::getGlobalEntity(StringRef Name) { - IdentifierInfo *II = &ProgImpl.getIdents().get(Name); - DeclarationName GlobName(II); - unsigned IdNS = Decl::IDNS_Ordinary; - return getEntity(Entity(), GlobName, IdNS, false); -} - -Entity EntityGetter::VisitNamedDecl(NamedDecl *D) { - Entity Parent; - if (!D->getDeclContext()->isTranslationUnit()) { - Parent = Visit(cast<Decl>(D->getDeclContext())); - // FIXME: Anonymous structs ? - if (Parent.isInvalid()) - return Entity(); - } - if (Parent.isValid() && Parent.isInternalToTU()) - return Entity(D); - - // FIXME: Only works for DeclarationNames that are identifiers and selectors. - // Treats other DeclarationNames as internal Decls for now.. - - DeclarationName LocalName = D->getDeclName(); - if (!LocalName) - return Entity(D); - - DeclarationName GlobName; - - if (IdentifierInfo *II = LocalName.getAsIdentifierInfo()) { - IdentifierInfo *GlobII = &ProgImpl.getIdents().get(II->getName()); - GlobName = DeclarationName(GlobII); - } else { - Selector LocalSel = LocalName.getObjCSelector(); - - // Treats other DeclarationNames as internal Decls for now.. - if (LocalSel.isNull()) - return Entity(D); - - Selector GlobSel = - (uintptr_t)GlobalSelector::get(LocalSel, Prog).getAsOpaquePtr(); - GlobName = DeclarationName(GlobSel); - } - - assert(GlobName); - - unsigned IdNS = D->getIdentifierNamespace(); - - ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D); - bool isObjCInstanceMethod = MD && MD->isInstanceMethod(); - return getEntity(Parent, GlobName, IdNS, isObjCInstanceMethod); -} - -Entity EntityGetter::VisitVarDecl(VarDecl *D) { - // Local variables have no linkage, make invalid Entities. - if (D->hasLocalStorage()) - return Entity(); - - // If it's static it cannot be referred to by another translation unit. - if (D->getStorageClass() == SC_Static) - return Entity(D); - - return VisitNamedDecl(D); -} - -Entity EntityGetter::VisitFunctionDecl(FunctionDecl *D) { - // If it's static it cannot be referred to by another translation unit. - if (D->getStorageClass() == SC_Static) - return Entity(D); - - return VisitNamedDecl(D); -} - -Entity EntityGetter::VisitFieldDecl(FieldDecl *D) { - // Make FieldDecl an invalid Entity since it has no linkage. - return Entity(); -} - -Entity EntityGetter::VisitTypeDecl(TypeDecl *D) { - // Although in C++ class name has external linkage, usually the definition of - // the class is available in the same translation unit when it's needed. So we - // make all of them invalid Entity. - return Entity(); -} - -//===----------------------------------------------------------------------===// -// EntityImpl Implementation -//===----------------------------------------------------------------------===// - -Decl *EntityImpl::getDecl(ASTContext &AST) { - DeclContext *DC = - Parent.isInvalid() ? AST.getTranslationUnitDecl() - : cast<DeclContext>(Parent.getDecl(AST)); - if (!DC) - return 0; // Couldn't get the parent context. - - DeclarationName LocalName; - - if (IdentifierInfo *GlobII = Name.getAsIdentifierInfo()) { - IdentifierInfo &II = AST.Idents.get(GlobII->getName()); - LocalName = DeclarationName(&II); - } else { - Selector GlobSel = Name.getObjCSelector(); - assert(!GlobSel.isNull() && "A not handled yet declaration name"); - GlobalSelector GSel = - GlobalSelector::getFromOpaquePtr(GlobSel.getAsOpaquePtr()); - LocalName = GSel.getSelector(AST); - } - - assert(LocalName); - - DeclContext::lookup_result Res = DC->lookup(LocalName); - for (DeclContext::lookup_iterator I = Res.first, E = Res.second; I!=E; ++I) { - Decl *D = *I; - if (D->getIdentifierNamespace() == IdNS) { - if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { - if (MD->isInstanceMethod() == IsObjCInstanceMethod) - return MD; - } else - return D; - } - } - - return 0; // Failed to find a decl using this Entity. -} - -/// \brief Get an Entity associated with the given Decl. -/// \returns Null if an Entity cannot refer to this Decl. -Entity EntityImpl::get(Decl *D, Program &Prog, ProgramImpl &ProgImpl) { - assert(D && "Passed null Decl"); - return EntityGetter(Prog, ProgImpl).Visit(D); -} - -/// \brief Get an Entity associated with a global name. -Entity EntityImpl::get(StringRef Name, Program &Prog, - ProgramImpl &ProgImpl) { - return EntityGetter(Prog, ProgImpl).getGlobalEntity(Name); -} - -std::string EntityImpl::getPrintableName() { - return Name.getAsString(); -} - -//===----------------------------------------------------------------------===// -// Entity Implementation -//===----------------------------------------------------------------------===// - -Entity::Entity(Decl *D) : Val(D->getCanonicalDecl()) { } - -/// \brief Find the Decl that can be referred to by this entity. -Decl *Entity::getDecl(ASTContext &AST) const { - if (isInvalid()) - return 0; - - if (Decl *D = Val.dyn_cast<Decl *>()) - // Check that the passed AST is actually the one that this Decl belongs to. - return (&D->getASTContext() == &AST) ? D : 0; - - return Val.get<EntityImpl *>()->getDecl(AST); -} - -std::string Entity::getPrintableName() const { - if (isInvalid()) - return "<< Invalid >>"; - - if (Decl *D = Val.dyn_cast<Decl *>()) { - if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) - return ND->getNameAsString(); - else - return std::string(); - } - - return Val.get<EntityImpl *>()->getPrintableName(); -} - -/// \brief Get an Entity associated with the given Decl. -/// \returns Null if an Entity cannot refer to this Decl. -Entity Entity::get(Decl *D, Program &Prog) { - if (D == 0) - return Entity(); - ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl); - return EntityImpl::get(D, Prog, ProgImpl); -} - -Entity Entity::get(StringRef Name, Program &Prog) { - ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl); - return EntityImpl::get(Name, Prog, ProgImpl); -} - -unsigned -llvm::DenseMapInfo<Entity>::getHashValue(Entity E) { - return DenseMapInfo<void*>::getHashValue(E.getAsOpaquePtr()); -} diff --git a/contrib/llvm/tools/clang/lib/Index/EntityImpl.h b/contrib/llvm/tools/clang/lib/Index/EntityImpl.h deleted file mode 100644 index 6d6a0c6..0000000 --- a/contrib/llvm/tools/clang/lib/Index/EntityImpl.h +++ /dev/null @@ -1,71 +0,0 @@ -//===--- EntityImpl.h - Internal Entity implementation---------*- C++ -*-=====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Internal implementation for the Entity class -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_ENTITYIMPL_H -#define LLVM_CLANG_INDEX_ENTITYIMPL_H - -#include "clang/Index/Entity.h" -#include "clang/AST/DeclarationName.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/StringSet.h" - -namespace clang { - -namespace idx { - class ProgramImpl; - -class EntityImpl : public llvm::FoldingSetNode { - Entity Parent; - DeclarationName Name; - - /// \brief Identifier namespace. - unsigned IdNS; - - /// \brief If Name is a selector, this keeps track whether it's for an - /// instance method. - bool IsObjCInstanceMethod; - -public: - EntityImpl(Entity parent, DeclarationName name, unsigned idNS, - bool isObjCInstanceMethod) - : Parent(parent), Name(name), IdNS(idNS), - IsObjCInstanceMethod(isObjCInstanceMethod) { } - - /// \brief Find the Decl that can be referred to by this entity. - Decl *getDecl(ASTContext &AST); - - /// \brief Get an Entity associated with the given Decl. - /// \returns Null if an Entity cannot refer to this Decl. - static Entity get(Decl *D, Program &Prog, ProgramImpl &ProgImpl); - static Entity get(StringRef Name, Program &Prog, ProgramImpl &ProgImpl); - - std::string getPrintableName(); - - void Profile(llvm::FoldingSetNodeID &ID) const { - Profile(ID, Parent, Name, IdNS, IsObjCInstanceMethod); - } - static void Profile(llvm::FoldingSetNodeID &ID, Entity Parent, - DeclarationName Name, unsigned IdNS, - bool isObjCInstanceMethod) { - ID.AddPointer(Parent.getAsOpaquePtr()); - ID.AddPointer(Name.getAsOpaquePtr()); - ID.AddInteger(IdNS); - ID.AddBoolean(isObjCInstanceMethod); - } -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/lib/Index/GlobalCallGraph.cpp b/contrib/llvm/tools/clang/lib/Index/GlobalCallGraph.cpp deleted file mode 100644 index a21b52a..0000000 --- a/contrib/llvm/tools/clang/lib/Index/GlobalCallGraph.cpp +++ /dev/null @@ -1,152 +0,0 @@ -//== GlobalCallGraph.cpp - Call graph building ------------------*- C++ -*--==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defined the CallGraph and CGBuilder classes. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/GlobalCallGraph.h" - -#include "clang/AST/ASTContext.h" -#include "clang/AST/StmtVisitor.h" - -#include "llvm/Support/GraphWriter.h" - -using namespace clang::idx; -using clang::FunctionDecl; -using clang::DeclContext; -using clang::ASTContext; - -namespace { -class CGBuilder : public StmtVisitor<CGBuilder> { - - CallGraph &G; - FunctionDecl *FD; - - Entity CallerEnt; - - CallGraphNode *CallerNode; - -public: - CGBuilder(CallGraph &g, FunctionDecl *fd, Entity E, CallGraphNode *N) - : G(g), FD(fd), CallerEnt(E), CallerNode(N) {} - - void VisitStmt(Stmt *S) { VisitChildren(S); } - - void VisitCallExpr(CallExpr *CE); - - void VisitChildren(Stmt *S) { - for (Stmt::child_range I = S->children(); I; ++I) - if (*I) - static_cast<CGBuilder*>(this)->Visit(*I); - } -}; -} - -void CGBuilder::VisitCallExpr(CallExpr *CE) { - if (FunctionDecl *CalleeDecl = CE->getDirectCallee()) { - Entity Ent = Entity::get(CalleeDecl, G.getProgram()); - CallGraphNode *CalleeNode = G.getOrInsertFunction(Ent); - CallerNode->addCallee(ASTLocation(FD, CE), CalleeNode); - } -} - -CallGraph::CallGraph(Program &P) : Prog(P), Root(0) { - ExternalCallingNode = getOrInsertFunction(Entity()); -} - -CallGraph::~CallGraph() { - if (!FunctionMap.empty()) { - for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end(); - I != E; ++I) - delete I->second; - FunctionMap.clear(); - } -} - -void CallGraph::addTU(ASTContext& Ctx) { - DeclContext *DC = Ctx.getTranslationUnitDecl(); - for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); - I != E; ++I) { - - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { - if (FD->doesThisDeclarationHaveABody()) { - // Set caller's ASTContext. - Entity Ent = Entity::get(FD, Prog); - CallGraphNode *Node = getOrInsertFunction(Ent); - CallerCtx[Node] = &Ctx; - - // If this function has external linkage, anything could call it. - if (FD->isGlobal()) - ExternalCallingNode->addCallee(idx::ASTLocation(), Node); - - // Set root node to 'main' function. - if (FD->getNameAsString() == "main") - Root = Node; - - CGBuilder builder(*this, FD, Ent, Node); - builder.Visit(FD->getBody()); - } - } - } -} - -CallGraphNode *CallGraph::getOrInsertFunction(Entity F) { - CallGraphNode *&Node = FunctionMap[F]; - if (Node) - return Node; - - return Node = new CallGraphNode(F); -} - -Decl *CallGraph::getDecl(CallGraphNode *Node) { - // Get the function's context. - ASTContext *Ctx = CallerCtx[Node]; - - return Node->getDecl(*Ctx); -} - -void CallGraph::print(raw_ostream &os) { - for (iterator I = begin(), E = end(); I != E; ++I) { - if (I->second->hasCallee()) { - os << "function: " << I->first.getPrintableName() - << " calls:\n"; - for (CallGraphNode::iterator CI = I->second->begin(), - CE = I->second->end(); CI != CE; ++CI) { - os << " " << CI->second->getName(); - } - os << '\n'; - } - } -} - -void CallGraph::dump() { - print(llvm::errs()); -} - -void CallGraph::ViewCallGraph() const { - llvm::ViewGraph(*this, "CallGraph"); -} - -namespace llvm { - -template <> -struct DOTGraphTraits<CallGraph> : public DefaultDOTGraphTraits { - - DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} - - static std::string getNodeLabel(const CallGraphNode *Node, - const CallGraph &CG) { - return Node->getName(); - - } - -}; - -} diff --git a/contrib/llvm/tools/clang/lib/Index/GlobalSelector.cpp b/contrib/llvm/tools/clang/lib/Index/GlobalSelector.cpp deleted file mode 100644 index 2fe6f95..0000000 --- a/contrib/llvm/tools/clang/lib/Index/GlobalSelector.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//===-- GlobalSelector.cpp - Cross-translation-unit "token" for selectors -===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// GlobalSelector is a ASTContext-independent way to refer to selectors. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/GlobalSelector.h" -#include "ProgramImpl.h" -#include "clang/Index/Program.h" -#include "clang/AST/ASTContext.h" -using namespace clang; -using namespace idx; - -/// \brief Get the ASTContext-specific selector. -Selector GlobalSelector::getSelector(ASTContext &AST) const { - if (isInvalid()) - return Selector(); - - Selector GlobSel = Selector(reinterpret_cast<uintptr_t>(Val)); - - SmallVector<IdentifierInfo *, 8> Ids; - for (unsigned i = 0, e = GlobSel.isUnarySelector() ? 1 : GlobSel.getNumArgs(); - i != e; ++i) { - IdentifierInfo *GlobII = GlobSel.getIdentifierInfoForSlot(i); - IdentifierInfo *II = &AST.Idents.get(GlobII->getName()); - Ids.push_back(II); - } - - return AST.Selectors.getSelector(GlobSel.getNumArgs(), Ids.data()); -} - -/// \brief Get a printable name for debugging purpose. -std::string GlobalSelector::getPrintableName() const { - if (isInvalid()) - return "<< Invalid >>"; - - Selector GlobSel = Selector(reinterpret_cast<uintptr_t>(Val)); - return GlobSel.getAsString(); -} - -/// \brief Get a GlobalSelector for the ASTContext-specific selector. -GlobalSelector GlobalSelector::get(Selector Sel, Program &Prog) { - if (Sel.isNull()) - return GlobalSelector(); - - ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl); - - SmallVector<IdentifierInfo *, 8> Ids; - for (unsigned i = 0, e = Sel.isUnarySelector() ? 1 : Sel.getNumArgs(); - i != e; ++i) { - IdentifierInfo *II = Sel.getIdentifierInfoForSlot(i); - IdentifierInfo *GlobII = &ProgImpl.getIdents().get(II->getName()); - Ids.push_back(GlobII); - } - - Selector GlobSel = ProgImpl.getSelectors().getSelector(Sel.getNumArgs(), - Ids.data()); - return GlobalSelector(GlobSel.getAsOpaquePtr()); -} - -unsigned -llvm::DenseMapInfo<GlobalSelector>::getHashValue(GlobalSelector Sel) { - return DenseMapInfo<void*>::getHashValue(Sel.getAsOpaquePtr()); -} diff --git a/contrib/llvm/tools/clang/lib/Index/Handlers.cpp b/contrib/llvm/tools/clang/lib/Index/Handlers.cpp deleted file mode 100644 index 1e9a27d..0000000 --- a/contrib/llvm/tools/clang/lib/Index/Handlers.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//===--- Handlers.cpp - Interfaces for receiving information ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Abstract interfaces for receiving information. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/Handlers.h" -#include "clang/Index/Entity.h" -using namespace clang; -using namespace idx; - -// Out-of-line to give the virtual tables a home. -EntityHandler::~EntityHandler() { } -TranslationUnitHandler::~TranslationUnitHandler() { } -TULocationHandler::~TULocationHandler() { } diff --git a/contrib/llvm/tools/clang/lib/Index/IndexProvider.cpp b/contrib/llvm/tools/clang/lib/Index/IndexProvider.cpp deleted file mode 100644 index eea0988..0000000 --- a/contrib/llvm/tools/clang/lib/Index/IndexProvider.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===- IndexProvider.cpp - Maps information to translation units -*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Maps information to TranslationUnits. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/IndexProvider.h" -#include "clang/Index/Entity.h" -using namespace clang; -using namespace idx; - -// Out-of-line to give the virtual table a home. -IndexProvider::~IndexProvider() { } diff --git a/contrib/llvm/tools/clang/lib/Index/Indexer.cpp b/contrib/llvm/tools/clang/lib/Index/Indexer.cpp deleted file mode 100644 index ebba43c..0000000 --- a/contrib/llvm/tools/clang/lib/Index/Indexer.cpp +++ /dev/null @@ -1,121 +0,0 @@ -//===--- Indexer.cpp - IndexProvider implementation -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// IndexProvider implementation. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/Indexer.h" -#include "clang/Index/Program.h" -#include "clang/Index/Handlers.h" -#include "clang/Index/TranslationUnit.h" -#include "ASTVisitor.h" -#include "clang/AST/DeclBase.h" -using namespace clang; -using namespace idx; - -namespace { - -class EntityIndexer : public EntityHandler { - TranslationUnit *TU; - Indexer::MapTy ⤅ - Indexer::DefMapTy &DefMap; - -public: - EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map, - Indexer::DefMapTy &defmap) - : TU(tu), Map(map), DefMap(defmap) { } - - virtual void Handle(Entity Ent) { - if (Ent.isInternalToTU()) - return; - Map[Ent].insert(TU); - - Decl *D = Ent.getDecl(TU->getASTContext()); - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - if (FD->doesThisDeclarationHaveABody()) - DefMap[Ent] = std::make_pair(FD, TU); - } -}; - -class SelectorIndexer : public ASTVisitor<SelectorIndexer> { - Program &Prog; - TranslationUnit *TU; - Indexer::SelMapTy ⤅ - -public: - SelectorIndexer(Program &prog, TranslationUnit *tu, Indexer::SelMapTy &map) - : Prog(prog), TU(tu), Map(map) { } - - void VisitObjCMethodDecl(ObjCMethodDecl *D) { - Map[GlobalSelector::get(D->getSelector(), Prog)].insert(TU); - Base::VisitObjCMethodDecl(D); - } - - void VisitObjCMessageExpr(ObjCMessageExpr *Node) { - Map[GlobalSelector::get(Node->getSelector(), Prog)].insert(TU); - Base::VisitObjCMessageExpr(Node); - } -}; - -} // anonymous namespace - -void Indexer::IndexAST(TranslationUnit *TU) { - assert(TU && "Passed null TranslationUnit"); - ASTContext &Ctx = TU->getASTContext(); - CtxTUMap[&Ctx] = TU; - EntityIndexer Idx(TU, Map, DefMap); - Prog.FindEntities(Ctx, Idx); - - SelectorIndexer SelIdx(Prog, TU, SelMap); - SelIdx.Visit(Ctx.getTranslationUnitDecl()); -} - -void Indexer::GetTranslationUnitsFor(Entity Ent, - TranslationUnitHandler &Handler) { - assert(Ent.isValid() && "Expected valid Entity"); - - if (Ent.isInternalToTU()) { - Decl *D = Ent.getInternalDecl(); - CtxTUMapTy::iterator I = CtxTUMap.find(&D->getASTContext()); - if (I != CtxTUMap.end()) - Handler.Handle(I->second); - return; - } - - MapTy::iterator I = Map.find(Ent); - if (I == Map.end()) - return; - - TUSetTy &Set = I->second; - for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I) - Handler.Handle(*I); -} - -void Indexer::GetTranslationUnitsFor(GlobalSelector Sel, - TranslationUnitHandler &Handler) { - assert(Sel.isValid() && "Expected valid GlobalSelector"); - - SelMapTy::iterator I = SelMap.find(Sel); - if (I == SelMap.end()) - return; - - TUSetTy &Set = I->second; - for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I) - Handler.Handle(*I); -} - -std::pair<FunctionDecl *, TranslationUnit *> -Indexer::getDefinitionFor(Entity Ent) { - DefMapTy::iterator I = DefMap.find(Ent); - if (I == DefMap.end()) - return std::make_pair((FunctionDecl *)0, (TranslationUnit *)0); - else - return I->second; -} diff --git a/contrib/llvm/tools/clang/lib/Index/Program.cpp b/contrib/llvm/tools/clang/lib/Index/Program.cpp deleted file mode 100644 index 4efad2c..0000000 --- a/contrib/llvm/tools/clang/lib/Index/Program.cpp +++ /dev/null @@ -1,50 +0,0 @@ -//===--- Program.cpp - Entity originator and misc -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Storage for Entities and utility functions -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/Program.h" -#include "ProgramImpl.h" -#include "clang/Index/Handlers.h" -#include "clang/Index/TranslationUnit.h" -#include "clang/AST/DeclBase.h" -#include "clang/AST/ASTContext.h" -#include "llvm/Support/raw_ostream.h" -using namespace clang; -using namespace idx; - -// Out-of-line to give the virtual tables a home. -TranslationUnit::~TranslationUnit() { } - -Program::Program() : Impl(new ProgramImpl()) { } - -Program::~Program() { - delete static_cast<ProgramImpl *>(Impl); -} - -static void FindEntitiesInDC(DeclContext *DC, Program &Prog, - EntityHandler &Handler) { - for (DeclContext::decl_iterator - I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { - if (I->getLocation().isInvalid()) - continue; - Entity Ent = Entity::get(*I, Prog); - if (Ent.isValid()) - Handler.Handle(Ent); - if (DeclContext *SubDC = dyn_cast<DeclContext>(*I)) - FindEntitiesInDC(SubDC, Prog, Handler); - } -} - -/// \brief Traverses the AST and passes all the entities to the Handler. -void Program::FindEntities(ASTContext &Ctx, EntityHandler &Handler) { - FindEntitiesInDC(Ctx.getTranslationUnitDecl(), *this, Handler); -} diff --git a/contrib/llvm/tools/clang/lib/Index/ProgramImpl.h b/contrib/llvm/tools/clang/lib/Index/ProgramImpl.h deleted file mode 100644 index 57b9ce3..0000000 --- a/contrib/llvm/tools/clang/lib/Index/ProgramImpl.h +++ /dev/null @@ -1,56 +0,0 @@ -//===--- ProgramImpl.h - Internal Program implementation---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Internal implementation for the Program class -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_INDEX_PROGRAMIMPL_H -#define LLVM_CLANG_INDEX_PROGRAMIMPL_H - -#include "EntityImpl.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/LangOptions.h" - -namespace clang { - -namespace idx { - class EntityListener; - -class ProgramImpl { -public: - typedef llvm::FoldingSet<EntityImpl> EntitySetTy; - -private: - EntitySetTy Entities; - llvm::BumpPtrAllocator BumpAlloc; - - IdentifierTable Identifiers; - SelectorTable Selectors; - - ProgramImpl(const ProgramImpl&); // do not implement - ProgramImpl &operator=(const ProgramImpl &); // do not implement - -public: - ProgramImpl() : Identifiers(LangOptions()) { } - - EntitySetTy &getEntities() { return Entities; } - IdentifierTable &getIdents() { return Identifiers; } - SelectorTable &getSelectors() { return Selectors; } - - void *Allocate(unsigned Size, unsigned Align = 8) { - return BumpAlloc.Allocate(Size, Align); - } -}; - -} // namespace idx - -} // namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/lib/Index/SelectorMap.cpp b/contrib/llvm/tools/clang/lib/Index/SelectorMap.cpp deleted file mode 100644 index 0f11e31..0000000 --- a/contrib/llvm/tools/clang/lib/Index/SelectorMap.cpp +++ /dev/null @@ -1,84 +0,0 @@ -//===- SelectorMap.cpp - Maps selectors to methods and messages -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// SelectorMap creates a mapping from selectors to ObjC method declarations -// and ObjC message expressions. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/SelectorMap.h" -#include "ASTVisitor.h" -using namespace clang; -using namespace idx; - -namespace { - -class SelMapper : public ASTVisitor<SelMapper> { - SelectorMap::SelMethMapTy &SelMethMap; - SelectorMap::SelRefMapTy &SelRefMap; - -public: - SelMapper(SelectorMap::SelMethMapTy &MethMap, - SelectorMap::SelRefMapTy &RefMap) - : SelMethMap(MethMap), SelRefMap(RefMap) { } - - void VisitObjCMethodDecl(ObjCMethodDecl *D); - void VisitObjCMessageExpr(ObjCMessageExpr *Node); - void VisitObjCSelectorExpr(ObjCSelectorExpr *Node); -}; - -} // anonymous namespace - -//===----------------------------------------------------------------------===// -// SelMapper Implementation -//===----------------------------------------------------------------------===// - -void SelMapper::VisitObjCMethodDecl(ObjCMethodDecl *D) { - if (D->getCanonicalDecl() == D) - SelMethMap.insert(std::make_pair(D->getSelector(), D)); - Base::VisitObjCMethodDecl(D); -} - -void SelMapper::VisitObjCMessageExpr(ObjCMessageExpr *Node) { - ASTLocation ASTLoc(CurrentDecl, Node); - SelRefMap.insert(std::make_pair(Node->getSelector(), ASTLoc)); -} - -void SelMapper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { - ASTLocation ASTLoc(CurrentDecl, Node); - SelRefMap.insert(std::make_pair(Node->getSelector(), ASTLoc)); -} - -//===----------------------------------------------------------------------===// -// SelectorMap Implementation -//===----------------------------------------------------------------------===// - -SelectorMap::SelectorMap(ASTContext &Ctx) { - SelMapper(SelMethMap, SelRefMap).Visit(Ctx.getTranslationUnitDecl()); -} - -SelectorMap::method_iterator -SelectorMap::methods_begin(Selector Sel) const { - return method_iterator(SelMethMap.lower_bound(Sel)); -} - -SelectorMap::method_iterator -SelectorMap::methods_end(Selector Sel) const { - return method_iterator(SelMethMap.upper_bound(Sel)); -} - -SelectorMap::astlocation_iterator -SelectorMap::refs_begin(Selector Sel) const { - return astlocation_iterator(SelRefMap.lower_bound(Sel)); -} - -SelectorMap::astlocation_iterator -SelectorMap::refs_end(Selector Sel) const { - return astlocation_iterator(SelRefMap.upper_bound(Sel)); -} diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp index c000f69..f04d767 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -59,7 +59,7 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, } } - HandleMemberFunctionDefaultArgs(D, FnD); + HandleMemberFunctionDeclDelays(D, FnD); D.complete(FnD); @@ -348,6 +348,77 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { LM.DefaultArgs[I].Toks = 0; } } + + // Parse a delayed exception-specification, if there is one. + if (CachedTokens *Toks = LM.ExceptionSpecTokens) { + // Save the current token position. + SourceLocation origLoc = Tok.getLocation(); + + // Parse the default argument from its saved token stream. + Toks->push_back(Tok); // So that the current token doesn't get lost + PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false); + + // Consume the previously-pushed token. + ConsumeAnyToken(); + + // C++11 [expr.prim.general]p3: + // If a declaration declares a member function or member function + // template of a class X, the expression this is a prvalue of type + // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq + // and the end of the function-definition, member-declarator, or + // declarator. + CXXMethodDecl *Method; + if (FunctionTemplateDecl *FunTmpl + = dyn_cast<FunctionTemplateDecl>(LM.Method)) + Method = cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); + else + Method = cast<CXXMethodDecl>(LM.Method); + + Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(), + Method->getTypeQualifiers(), + getLangOpts().CPlusPlus0x); + + // Parse the exception-specification. + SourceRange SpecificationRange; + SmallVector<ParsedType, 4> DynamicExceptions; + SmallVector<SourceRange, 4> DynamicExceptionRanges; + ExprResult NoexceptExpr; + CachedTokens *ExceptionSpecTokens; + + ExceptionSpecificationType EST + = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange, + DynamicExceptions, + DynamicExceptionRanges, NoexceptExpr, + ExceptionSpecTokens); + + // Clean up the remaining tokens. + if (Tok.is(tok::cxx_exceptspec_end)) + ConsumeToken(); + else if (EST != EST_None) + Diag(Tok.getLocation(), diag::err_except_spec_unparsed); + + // Attach the exception-specification to the method. + if (EST != EST_None) + Actions.actOnDelayedExceptionSpecification(LM.Method, EST, + SpecificationRange, + DynamicExceptions, + DynamicExceptionRanges, + NoexceptExpr.isUsable()? + NoexceptExpr.get() : 0); + + assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, + Tok.getLocation()) && + "tryParseExceptionSpecification went over the exception tokens!"); + + // There could be leftover tokens (e.g. because of an error). + // Skip through until we reach the original token position. + while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof)) + ConsumeAnyToken(); + + delete LM.ExceptionSpecTokens; + LM.ExceptionSpecTokens = 0; + } + PrototypeScope.Exit(); // Finish the delayed C++ method declaration. @@ -447,9 +518,9 @@ void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { if (HasTemplateScope) Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); - // Set or update the scope flags to include Scope::ThisScope. + // Set or update the scope flags. bool AlreadyHasClassScope = Class.TopLevelClass; - unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope|Scope::ThisScope; + unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); @@ -457,10 +528,20 @@ void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); - for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { - Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers(); + { + // C++11 [expr.prim.general]p4: + // Otherwise, if a member-declarator declares a non-static data member + // (9.2) of a class X, the expression this is a prvalue of type "pointer + // to X" within the optional brace-or-equal-initializer. It shall not + // appear elsewhere in the member-declarator. + Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, + /*TypeQuals=*/(unsigned)0); + + for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { + Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers(); + } } - + if (!AlreadyHasClassScope) Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); @@ -481,6 +562,7 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { ConsumeAnyToken(); SourceLocation EqualLoc; + ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false, EqualLoc); diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp index cf3dca2..932ffb4 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp @@ -729,9 +729,9 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) { if (HasTemplateScope) Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); - // Set or update the scope flags to include Scope::ThisScope. + // Set or update the scope flags. bool AlreadyHasClassScope = Class.TopLevelClass; - unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope|Scope::ThisScope; + unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); @@ -739,11 +739,16 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) { if (!AlreadyHasClassScope) Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); - - for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i) { - Class.LateParsedDeclarations[i]->ParseLexedAttributes(); + { + // Allow 'this' within late-parsed attributes. + Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, + /*TypeQuals=*/0); + + for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ + Class.LateParsedDeclarations[i]->ParseLexedAttributes(); + } } - + if (!AlreadyHasClassScope) Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); @@ -756,6 +761,7 @@ void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { LAs[i]->addDecl(D); ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); + delete LAs[i]; } LAs.clear(); } @@ -958,7 +964,7 @@ void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { /// [C++] namespace-definition /// [C++] using-directive /// [C++] using-declaration -/// [C++0x/C11] static_assert-declaration +/// [C++11/C11] static_assert-declaration /// others... [FIXME] /// Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts, @@ -4191,6 +4197,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, SmallVector<ParsedType, 2> DynamicExceptions; SmallVector<SourceRange, 2> DynamicExceptionRanges; ExprResult NoexceptExpr; + CachedTokens *ExceptionSpecTokens = 0; ParsedAttributes FnAttrs(AttrFactory); ParsedType TrailingReturnType; @@ -4241,11 +4248,34 @@ void Parser::ParseFunctionDeclarator(Declarator &D, EndLoc = RefQualifierLoc; } + // C++11 [expr.prim.general]p3: + // If a declaration declares a member function or member function + // template of a class X, the expression this is a prvalue of type + // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq + // and the end of the function-definition, member-declarator, or + // declarator. + bool IsCXX11MemberFunction = + getLangOpts().CPlusPlus0x && + (D.getContext() == Declarator::MemberContext || + (D.getContext() == Declarator::FileContext && + D.getCXXScopeSpec().isValid() && + Actions.CurContext->isRecord())); + Sema::CXXThisScopeRAII ThisScope(Actions, + dyn_cast<CXXRecordDecl>(Actions.CurContext), + DS.getTypeQualifiers(), + IsCXX11MemberFunction); + // Parse exception-specification[opt]. - ESpecType = MaybeParseExceptionSpecification(ESpecRange, - DynamicExceptions, - DynamicExceptionRanges, - NoexceptExpr); + bool Delayed = (D.getContext() == Declarator::MemberContext && + D.getDeclSpec().getStorageClassSpec() + != DeclSpec::SCS_typedef && + !D.getDeclSpec().isFriendSpecified()); + ESpecType = tryParseExceptionSpecification(Delayed, + ESpecRange, + DynamicExceptions, + DynamicExceptionRanges, + NoexceptExpr, + ExceptionSpecTokens); if (ESpecType != EST_None) EndLoc = ESpecRange.getEnd(); @@ -4280,6 +4310,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, + ExceptionSpecTokens, Tracker.getOpenLocation(), EndLoc, D, TrailingReturnType), @@ -4481,7 +4512,6 @@ void Parser::ParseParameterDeclarationClause( // If we're inside a class definition, cache the tokens // corresponding to the default argument. We'll actually parse // them when we see the end of the class definition. - // FIXME: Templates will require something similar. // FIXME: Can we use a smart pointer for Toks? DefArgToks = new CachedTokens; diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp index b2a65ff..b9b51d7 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp @@ -1534,13 +1534,35 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const { } } -void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo, - Decl *ThisDecl) { +/// \brief If the given declarator has any parts for which parsing has to be +/// delayed, e.g., default arguments or an exception-specification, create a +/// late-parsed method declaration record to handle the parsing at the end of +/// the class definition. +void Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, + Decl *ThisDecl) { // We just declared a member function. If this member function - // has any default arguments, we'll need to parse them later. + // has any default arguments or an exception-specification, we'll need to + // parse them later. LateParsedMethodDeclaration *LateMethod = 0; DeclaratorChunk::FunctionTypeInfo &FTI = DeclaratorInfo.getFunctionTypeInfo(); + + // If there was a delayed exception-specification, hold onto its tokens. + if (FTI.getExceptionSpecType() == EST_Delayed) { + // Push this method onto the stack of late-parsed method + // declarations. + LateMethod = new LateParsedMethodDeclaration(this, ThisDecl); + getCurrentClass().LateParsedDeclarations.push_back(LateMethod); + LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); + + // Stash the exception-specification tokens in the late-pased mthod. + LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens; + FTI.ExceptionSpecTokens = 0; + + // Reserve space for the parameters. + LateMethod->DefaultArgs.reserve(FTI.NumArgs); + } + for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { if (!LateMethod) { @@ -1558,7 +1580,7 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo, LateParsedDefaultArgument(FTI.ArgInfo[I].Param)); } - // Add this parameter to the list of parameters (it or may + // Add this parameter to the list of parameters (it may or may // not have a default argument). LateMethod->DefaultArgs.push_back( LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, @@ -1824,7 +1846,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // Parse the first declarator. ParseDeclarator(DeclaratorInfo); - // Error parsing the declarator? + // Error parsin g the declarator? if (!DeclaratorInfo.hasName()) { // If so, skip until the semi-colon or a }. SkipUntil(tok::r_brace, true, true); @@ -2046,7 +2068,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, if (DeclaratorInfo.isFunctionDeclarator() && DeclaratorInfo.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef) { - HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl); + HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl); } DeclaratorInfo.complete(ThisDecl); @@ -2334,13 +2356,11 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, T.getCloseLocation(), attrs.getList()); - // C++0x [class.mem]p2: Within the class member-specification, the class is - // regarded as complete within function bodies, default arguments, exception- - // specifications, and brace-or-equal-initializers for non-static data - // members (including such things in nested classes). - // - // FIXME: Only function bodies and brace-or-equal-initializers are currently - // handled. Fix the others! + // C++11 [class.mem]p2: + // Within the class member-specification, the class is regarded as complete + // within function bodies, default arguments, exception-specifications, and + // brace-or-equal-initializers for non-static data members (including such + // things in nested classes). if (TagDecl && NonNestedClass) { // We are not inside a nested class. This class and its nested classes // are complete and we can parse the delayed portions of method @@ -2535,12 +2555,63 @@ Parser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { /// 'noexcept' /// 'noexcept' '(' constant-expression ')' ExceptionSpecificationType -Parser::MaybeParseExceptionSpecification(SourceRange &SpecificationRange, +Parser::tryParseExceptionSpecification(bool Delayed, + SourceRange &SpecificationRange, SmallVectorImpl<ParsedType> &DynamicExceptions, SmallVectorImpl<SourceRange> &DynamicExceptionRanges, - ExprResult &NoexceptExpr) { + ExprResult &NoexceptExpr, + CachedTokens *&ExceptionSpecTokens) { ExceptionSpecificationType Result = EST_None; - + ExceptionSpecTokens = 0; + + // Handle delayed parsing of exception-specifications. + if (Delayed) { + if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept)) + return EST_None; + + // Consume and cache the starting token. + bool IsNoexcept = Tok.is(tok::kw_noexcept); + Token StartTok = Tok; + SpecificationRange = SourceRange(ConsumeToken()); + + // Check for a '('. + if (!Tok.is(tok::l_paren)) { + // If this is a bare 'noexcept', we're done. + if (IsNoexcept) { + Diag(Tok, diag::warn_cxx98_compat_noexcept_decl); + NoexceptExpr = 0; + return EST_BasicNoexcept; + } + + Diag(Tok, diag::err_expected_lparen_after) << "throw"; + return EST_DynamicNone; + } + + // Cache the tokens for the exception-specification. + ExceptionSpecTokens = new CachedTokens; + ExceptionSpecTokens->push_back(StartTok); // 'throw' or 'noexcept' + ExceptionSpecTokens->push_back(Tok); // '(' + SpecificationRange.setEnd(ConsumeParen()); // '(' + + if (!ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens, + /*StopAtSemi=*/true, + /*ConsumeFinalToken=*/true)) { + NoexceptExpr = 0; + delete ExceptionSpecTokens; + ExceptionSpecTokens = 0; + return IsNoexcept? EST_BasicNoexcept : EST_DynamicNone; + } + SpecificationRange.setEnd(Tok.getLocation()); + + // Add the 'stop' token. + Token End; + End.startToken(); + End.setKind(tok::cxx_exceptspec_end); + End.setLocation(Tok.getLocation()); + ExceptionSpecTokens->push_back(End); + return EST_Delayed; + } + // See if there's a dynamic specification. if (Tok.is(tok::kw_throw)) { Result = ParseDynamicExceptionSpecification(SpecificationRange, diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp index 7f3a815..b6a027b 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp @@ -1926,11 +1926,9 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // unless they've already reported an error. if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { Diag(Tok, diag::ext_gnu_statement_expr); - Actions.ActOnStartStmtExpr(); - ParsedAttributes attrs(AttrFactory); - StmtResult Stmt(ParseCompoundStatement(attrs, true)); + StmtResult Stmt(ParseCompoundStatement(true)); ExprType = CompoundStmt; // If the substmt parsed correctly, build the AST node. @@ -2394,7 +2392,7 @@ ExprResult Parser::ParseBlockLiteralExpression() { SourceLocation(), EST_None, SourceLocation(), - 0, 0, 0, 0, + 0, 0, 0, 0, 0, CaretLoc, CaretLoc, ParamInfo), attrs, CaretLoc); diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp index 2af7482..ae6ad0b 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp @@ -780,10 +780,13 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( llvm::SmallVector<ParsedType, 2> DynamicExceptions; llvm::SmallVector<SourceRange, 2> DynamicExceptionRanges; ExprResult NoexceptExpr; - ESpecType = MaybeParseExceptionSpecification(ESpecRange, - DynamicExceptions, - DynamicExceptionRanges, - NoexceptExpr); + CachedTokens *ExceptionSpecTokens; + ESpecType = tryParseExceptionSpecification(/*Delayed=*/false, + ESpecRange, + DynamicExceptions, + DynamicExceptionRanges, + NoexceptExpr, + ExceptionSpecTokens); if (ESpecType != EST_None) DeclEndLoc = ESpecRange.getEnd(); @@ -818,6 +821,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, + 0, DeclLoc, DeclEndLoc, D, TrailingReturnType), Attr, DeclEndLoc); @@ -863,6 +867,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( /*ExceptionRanges=*/0, /*NumExceptions=*/0, /*NoexceptExpr=*/0, + /*ExceptionSpecTokens=*/0, DeclLoc, DeclEndLoc, D, TrailingReturnType), Attr, DeclEndLoc); @@ -872,8 +877,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using // it. unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope; - if (getCurScope()->getFlags() & Scope::ThisScope) - ScopeFlags |= Scope::ThisScope; ParseScope BodyScope(this, ScopeFlags); Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope()); @@ -1711,7 +1714,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, // Form a parsed representation of the template-id to be stored in the // UnqualifiedId. TemplateIdAnnotation *TemplateId - = TemplateIdAnnotation::Allocate(TemplateArgs.size()); + = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds); if (Id.getKind() == UnqualifiedId::IK_Identifier) { TemplateId->Name = Id.Identifier; diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp index fdb9788..44320df 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp @@ -78,13 +78,30 @@ using namespace clang; StmtResult Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement, SourceLocation *TrailingElseLoc) { - const char *SemiError = 0; - StmtResult Res; ParenBraceBracketBalancer BalancerRAIIObj(*this); - ParsedAttributesWithRange attrs(AttrFactory); - MaybeParseCXX0XAttributes(attrs, 0, /*MightBeObjCMessageSend*/ true); + ParsedAttributesWithRange Attrs(AttrFactory); + MaybeParseCXX0XAttributes(Attrs, 0, /*MightBeObjCMessageSend*/ true); + + StmtResult Res = ParseStatementOrDeclarationAfterAttributes(Stmts, + OnlyStatement, TrailingElseLoc, Attrs); + + assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) && + "attributes on empty statement"); + + if (Attrs.empty() || Res.isInvalid()) + return Res; + + return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range); +} + +StmtResult +Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts, + bool OnlyStatement, SourceLocation *TrailingElseLoc, + ParsedAttributesWithRange &Attrs) { + const char *SemiError = 0; + StmtResult Res; // Cases in this switch statement should fall through if the parser expects // the token to end in a semicolon (in which case SemiError should be set), @@ -95,6 +112,7 @@ Retry: switch (Kind) { case tok::at: // May be a @try or @throw statement { + ProhibitAttributes(Attrs); // TODO: is it correct? AtLoc = ConsumeToken(); // consume @ return ParseObjCAtStatement(AtLoc); } @@ -108,7 +126,7 @@ Retry: Token Next = NextToken(); if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement // identifier ':' statement - return ParseLabeledStatement(attrs); + return ParseLabeledStatement(Attrs); } if (Next.isNot(tok::coloncolon)) { @@ -210,7 +228,7 @@ Retry: if ((getLangOpts().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) { SourceLocation DeclStart = Tok.getLocation(), DeclEnd; DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext, - DeclEnd, attrs); + DeclEnd, Attrs); return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd); } @@ -219,54 +237,54 @@ Retry: return StmtError(); } - return ParseExprStatement(attrs); + return ParseExprStatement(); } case tok::kw_case: // C99 6.8.1: labeled-statement - return ParseCaseStatement(attrs); + return ParseCaseStatement(); case tok::kw_default: // C99 6.8.1: labeled-statement - return ParseDefaultStatement(attrs); + return ParseDefaultStatement(); case tok::l_brace: // C99 6.8.2: compound-statement - return ParseCompoundStatement(attrs); + return ParseCompoundStatement(); case tok::semi: { // C99 6.8.3p3: expression[opt] ';' bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro(); return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro); } case tok::kw_if: // C99 6.8.4.1: if-statement - return ParseIfStatement(attrs, TrailingElseLoc); + return ParseIfStatement(TrailingElseLoc); case tok::kw_switch: // C99 6.8.4.2: switch-statement - return ParseSwitchStatement(attrs, TrailingElseLoc); + return ParseSwitchStatement(TrailingElseLoc); case tok::kw_while: // C99 6.8.5.1: while-statement - return ParseWhileStatement(attrs, TrailingElseLoc); + return ParseWhileStatement(TrailingElseLoc); case tok::kw_do: // C99 6.8.5.2: do-statement - Res = ParseDoStatement(attrs); + Res = ParseDoStatement(); SemiError = "do/while"; break; case tok::kw_for: // C99 6.8.5.3: for-statement - return ParseForStatement(attrs, TrailingElseLoc); + return ParseForStatement(TrailingElseLoc); case tok::kw_goto: // C99 6.8.6.1: goto-statement - Res = ParseGotoStatement(attrs); + Res = ParseGotoStatement(); SemiError = "goto"; break; case tok::kw_continue: // C99 6.8.6.2: continue-statement - Res = ParseContinueStatement(attrs); + Res = ParseContinueStatement(); SemiError = "continue"; break; case tok::kw_break: // C99 6.8.6.3: break-statement - Res = ParseBreakStatement(attrs); + Res = ParseBreakStatement(); SemiError = "break"; break; case tok::kw_return: // C99 6.8.6.4: return-statement - Res = ParseReturnStatement(attrs); + Res = ParseReturnStatement(); SemiError = "return"; break; case tok::kw_asm: { - ProhibitAttributes(attrs); + ProhibitAttributes(Attrs); bool msAsm = false; Res = ParseAsmStatement(msAsm); Res = Actions.ActOnFinishFullStmt(Res.get()); @@ -276,16 +294,19 @@ Retry: } case tok::kw_try: // C++ 15: try-block - return ParseCXXTryBlock(attrs); + return ParseCXXTryBlock(); case tok::kw___try: - return ParseSEHTryBlock(attrs); + ProhibitAttributes(Attrs); // TODO: is it correct? + return ParseSEHTryBlock(); case tok::annot_pragma_vis: + ProhibitAttributes(Attrs); HandlePragmaVisibility(); return StmtEmpty(); case tok::annot_pragma_pack: + ProhibitAttributes(Attrs); HandlePragmaPack(); return StmtEmpty(); } @@ -306,11 +327,10 @@ Retry: } /// \brief Parse an expression statement. -StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs) { +StmtResult Parser::ParseExprStatement() { // If a case keyword is missing, this is where it should be inserted. Token OldToken = Tok; - // FIXME: Use the attributes // expression[opt] ';' ExprResult Expr(ParseExpression()); if (Expr.isInvalid()) { @@ -331,7 +351,7 @@ StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs) { << FixItHint::CreateInsertion(OldToken.getLocation(), "case "); // Recover parsing as a case statement. - return ParseCaseStatement(Attrs, /*MissingCase=*/true, Expr); + return ParseCaseStatement(/*MissingCase=*/true, Expr); } // Otherwise, eat the semicolon. @@ -339,7 +359,7 @@ StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs) { return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr.get())); } -StmtResult Parser::ParseSEHTryBlock(ParsedAttributes & Attrs) { +StmtResult Parser::ParseSEHTryBlock() { assert(Tok.is(tok::kw___try) && "Expected '__try'"); SourceLocation Loc = ConsumeToken(); return ParseSEHTryBlockCommon(Loc); @@ -358,13 +378,12 @@ StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) { if(Tok.isNot(tok::l_brace)) return StmtError(Diag(Tok,diag::err_expected_lbrace)); - ParsedAttributesWithRange attrs(AttrFactory); - StmtResult TryBlock(ParseCompoundStatement(attrs)); + StmtResult TryBlock(ParseCompoundStatement()); if(TryBlock.isInvalid()) return move(TryBlock); StmtResult Handler; - if (Tok.is(tok::identifier) && + if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == getSEHExceptKeyword()) { SourceLocation Loc = ConsumeToken(); Handler = ParseSEHExceptBlock(Loc); @@ -418,8 +437,7 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) { if(ExpectAndConsume(tok::r_paren,diag::err_expected_rparen)) return StmtError(); - ParsedAttributesWithRange attrs(AttrFactory); - StmtResult Block(ParseCompoundStatement(attrs)); + StmtResult Block(ParseCompoundStatement()); if(Block.isInvalid()) return move(Block); @@ -437,8 +455,7 @@ StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) { raii2(Ident___abnormal_termination, false), raii3(Ident_AbnormalTermination, false); - ParsedAttributesWithRange attrs(AttrFactory); - StmtResult Block(ParseCompoundStatement(attrs)); + StmtResult Block(ParseCompoundStatement()); if(Block.isInvalid()) return move(Block); @@ -451,7 +468,7 @@ StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) { /// identifier ':' statement /// [GNU] identifier ':' attributes[opt] statement /// -StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) { +StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) { assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() && "Not an identifier!"); @@ -463,7 +480,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) { // identifier ':' statement SourceLocation ColonLoc = ConsumeToken(); - // Read label attributes, if present. + // Read label attributes, if present. attrs will contain both C++11 and GNU + // attributes (if present) after this point. MaybeParseGNUAttributes(attrs); StmtResult SubStmt(ParseStatement()); @@ -474,8 +492,10 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) { LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(), IdentTok.getLocation()); - if (AttributeList *Attrs = attrs.getList()) + if (AttributeList *Attrs = attrs.getList()) { Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs); + attrs.clear(); + } return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc, SubStmt.get()); @@ -486,10 +506,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) { /// 'case' constant-expression ':' statement /// [GNU] 'case' constant-expression '...' constant-expression ':' statement /// -StmtResult Parser::ParseCaseStatement(ParsedAttributes &attrs, bool MissingCase, - ExprResult Expr) { +StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) { assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!"); - // FIXME: Use attributes? // It is very very common for code to contain many case statements recursively // nested, as in (but usually without indentation): @@ -625,9 +643,7 @@ StmtResult Parser::ParseCaseStatement(ParsedAttributes &attrs, bool MissingCase, /// 'default' ':' statement /// Note that this does not parse the 'statement' at the end. /// -StmtResult Parser::ParseDefaultStatement(ParsedAttributes &attrs) { - //FIXME: Use attributes? - +StmtResult Parser::ParseDefaultStatement() { assert(Tok.is(tok::kw_default) && "Not a default stmt!"); SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'. @@ -668,9 +684,8 @@ StmtResult Parser::ParseDefaultStatement(ParsedAttributes &attrs) { SubStmt.get(), getCurScope()); } -StmtResult Parser::ParseCompoundStatement(ParsedAttributes &Attr, - bool isStmtExpr) { - return ParseCompoundStatement(Attr, isStmtExpr, Scope::DeclScope); +StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) { + return ParseCompoundStatement(isStmtExpr, Scope::DeclScope); } /// ParseCompoundStatement - Parse a "{}" block. @@ -700,11 +715,8 @@ StmtResult Parser::ParseCompoundStatement(ParsedAttributes &Attr, /// [OMP] barrier-directive /// [OMP] flush-directive /// -StmtResult Parser::ParseCompoundStatement(ParsedAttributes &attrs, - bool isStmtExpr, +StmtResult Parser::ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags) { - //FIXME: Use attributes? - assert(Tok.is(tok::l_brace) && "Not a compount stmt!"); // Enter a scope to hold everything within the compound stmt. Compound @@ -894,10 +906,7 @@ bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult, /// [C++] 'if' '(' condition ')' statement /// [C++] 'if' '(' condition ')' statement 'else' statement /// -StmtResult Parser::ParseIfStatement(ParsedAttributes &attrs, - SourceLocation *TrailingElseLoc) { - // FIXME: Use attributes? - +StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { assert(Tok.is(tok::kw_if) && "Not an if stmt!"); SourceLocation IfLoc = ConsumeToken(); // eat the 'if'. @@ -1028,10 +1037,7 @@ StmtResult Parser::ParseIfStatement(ParsedAttributes &attrs, /// switch-statement: /// 'switch' '(' expression ')' statement /// [C++] 'switch' '(' condition ')' statement -StmtResult Parser::ParseSwitchStatement(ParsedAttributes &attrs, - SourceLocation *TrailingElseLoc) { - // FIXME: Use attributes? - +StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) { assert(Tok.is(tok::kw_switch) && "Not a switch stmt!"); SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'. @@ -1119,10 +1125,7 @@ StmtResult Parser::ParseSwitchStatement(ParsedAttributes &attrs, /// while-statement: [C99 6.8.5.1] /// 'while' '(' expression ')' statement /// [C++] 'while' '(' condition ')' statement -StmtResult Parser::ParseWhileStatement(ParsedAttributes &attrs, - SourceLocation *TrailingElseLoc) { - // FIXME: Use attributes? - +StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) { assert(Tok.is(tok::kw_while) && "Not a while stmt!"); SourceLocation WhileLoc = Tok.getLocation(); ConsumeToken(); // eat the 'while'. @@ -1194,9 +1197,7 @@ StmtResult Parser::ParseWhileStatement(ParsedAttributes &attrs, /// do-statement: [C99 6.8.5.2] /// 'do' statement 'while' '(' expression ')' ';' /// Note: this lets the caller parse the end ';'. -StmtResult Parser::ParseDoStatement(ParsedAttributes &attrs) { - // FIXME: Use attributes? - +StmtResult Parser::ParseDoStatement() { assert(Tok.is(tok::kw_do) && "Not a do stmt!"); SourceLocation DoLoc = ConsumeToken(); // eat the 'do'. @@ -1277,10 +1278,7 @@ StmtResult Parser::ParseDoStatement(ParsedAttributes &attrs) { /// [C++0x] for-range-initializer: /// [C++0x] expression /// [C++0x] braced-init-list [TODO] -StmtResult Parser::ParseForStatement(ParsedAttributes &attrs, - SourceLocation *TrailingElseLoc) { - // FIXME: Use attributes? - +StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { assert(Tok.is(tok::kw_for) && "Not a for stmt!"); SourceLocation ForLoc = ConsumeToken(); // eat the 'for'. @@ -1535,9 +1533,7 @@ StmtResult Parser::ParseForStatement(ParsedAttributes &attrs, /// /// Note: this lets the caller parse the end ';'. /// -StmtResult Parser::ParseGotoStatement(ParsedAttributes &attrs) { - // FIXME: Use attributes? - +StmtResult Parser::ParseGotoStatement() { assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. @@ -1571,9 +1567,7 @@ StmtResult Parser::ParseGotoStatement(ParsedAttributes &attrs) { /// /// Note: this lets the caller parse the end ';'. /// -StmtResult Parser::ParseContinueStatement(ParsedAttributes &attrs) { - // FIXME: Use attributes? - +StmtResult Parser::ParseContinueStatement() { SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'. return Actions.ActOnContinueStmt(ContinueLoc, getCurScope()); } @@ -1584,9 +1578,7 @@ StmtResult Parser::ParseContinueStatement(ParsedAttributes &attrs) { /// /// Note: this lets the caller parse the end ';'. /// -StmtResult Parser::ParseBreakStatement(ParsedAttributes &attrs) { - // FIXME: Use attributes? - +StmtResult Parser::ParseBreakStatement() { SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'. return Actions.ActOnBreakStmt(BreakLoc, getCurScope()); } @@ -1594,9 +1586,7 @@ StmtResult Parser::ParseBreakStatement(ParsedAttributes &attrs) { /// ParseReturnStatement /// jump-statement: /// 'return' expression[opt] ';' -StmtResult Parser::ParseReturnStatement(ParsedAttributes &attrs) { - // FIXME: Use attributes? - +StmtResult Parser::ParseReturnStatement() { assert(Tok.is(tok::kw_return) && "Not a return stmt!"); SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'. @@ -2043,9 +2033,7 @@ bool Parser::trySkippingFunctionBody() { /// try-block: /// 'try' compound-statement handler-seq /// -StmtResult Parser::ParseCXXTryBlock(ParsedAttributes &attrs) { - // FIXME: Add attributes? - +StmtResult Parser::ParseCXXTryBlock() { assert(Tok.is(tok::kw_try) && "Expected 'try'"); SourceLocation TryLoc = ConsumeToken(); @@ -2072,17 +2060,17 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) { if (Tok.isNot(tok::l_brace)) return StmtError(Diag(Tok, diag::err_expected_lbrace)); // FIXME: Possible draft standard bug: attribute-specifier should be allowed? - ParsedAttributesWithRange attrs(AttrFactory); - StmtResult TryBlock(ParseCompoundStatement(attrs, /*isStmtExpr=*/false, + + StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, Scope::DeclScope|Scope::TryScope)); if (TryBlock.isInvalid()) return move(TryBlock); // Borland allows SEH-handlers with 'try' - if((Tok.is(tok::identifier) && - Tok.getIdentifierInfo() == getSEHExceptKeyword()) || - Tok.is(tok::kw___finally)) { + if ((Tok.is(tok::identifier) && + Tok.getIdentifierInfo() == getSEHExceptKeyword()) || + Tok.is(tok::kw___finally)) { // TODO: Factor into common return ParseSEHHandlerCommon(...) StmtResult Handler; if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) { @@ -2103,6 +2091,7 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) { } else { StmtVector Handlers(Actions); + ParsedAttributesWithRange attrs(AttrFactory); MaybeParseCXX0XAttributes(attrs); ProhibitAttributes(attrs); @@ -2168,8 +2157,7 @@ StmtResult Parser::ParseCXXCatchBlock() { return StmtError(Diag(Tok, diag::err_expected_lbrace)); // FIXME: Possible draft standard bug: attribute-specifier should be allowed? - ParsedAttributes attrs(AttrFactory); - StmtResult Block(ParseCompoundStatement(attrs)); + StmtResult Block(ParseCompoundStatement()); if (Block.isInvalid()) return move(Block); @@ -2188,24 +2176,23 @@ void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) { if (Result.Behavior == IEB_Dependent) { if (!Tok.is(tok::l_brace)) { Diag(Tok, diag::err_expected_lbrace); - return; + return; } - - ParsedAttributes Attrs(AttrFactory); - StmtResult Compound = ParseCompoundStatement(Attrs); + + StmtResult Compound = ParseCompoundStatement(); if (Compound.isInvalid()) return; - + StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc, Result.IsIfExists, - Result.SS, + Result.SS, Result.Name, Compound.get()); if (DepResult.isUsable()) Stmts.push_back(DepResult.get()); return; } - + BalancedDelimiterTracker Braces(*this, tok::l_brace); if (Braces.consumeOpen()) { Diag(Tok, diag::err_expected_lbrace); diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp index 61cd9f2..5c3e2ba 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp @@ -652,6 +652,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { // end of the template-parameter-list rather than a greater-than // operator. GreaterThanIsOperatorScope G(GreaterThanIsOperator, false); + EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); DefaultArg = ParseAssignmentExpression(); if (DefaultArg.isInvalid()) @@ -838,7 +839,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, // later. Tok.setKind(tok::annot_template_id); TemplateIdAnnotation *TemplateId - = TemplateIdAnnotation::Allocate(TemplateArgs.size()); + = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds); TemplateId->TemplateNameLoc = TemplateNameLoc; if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) { TemplateId->Name = TemplateName.Identifier; diff --git a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp index 054a8fd..f1b99fb 100644 --- a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp @@ -397,6 +397,8 @@ Parser::~Parser() { PP.RemovePragmaHandler("STDC", FPContractHandler.get()); FPContractHandler.reset(); PP.clearCodeCompletionHandler(); + + assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?"); } /// Initialize - Warm up the parser. @@ -470,10 +472,30 @@ void Parser::Initialize() { } } +namespace { + /// \brief RAIIObject to destroy the contents of a SmallVector of + /// TemplateIdAnnotation pointers and clear the vector. + class DestroyTemplateIdAnnotationsRAIIObj { + SmallVectorImpl<TemplateIdAnnotation *> &Container; + public: + DestroyTemplateIdAnnotationsRAIIObj(SmallVectorImpl<TemplateIdAnnotation *> + &Container) + : Container(Container) {} + + ~DestroyTemplateIdAnnotationsRAIIObj() { + for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I = + Container.begin(), E = Container.end(); + I != E; ++I) + (*I)->Destroy(); + Container.clear(); + } + }; +} + /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the /// action tells us to. This returns true if the EOF was encountered. bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) { - DelayedCleanupPoint CleanupRAII(TopLevelDeclCleanupPool); + DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); // Skip over the EOF token, flagging end of previous input for incremental // processing @@ -543,7 +565,7 @@ void Parser::ParseTranslationUnit() { Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, ParsingDeclSpec *DS) { - DelayedCleanupPoint CleanupRAII(TopLevelDeclCleanupPool); + DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); ParenBraceBracketBalancer BalancerRAIIObj(*this); if (PP.isCodeCompletionReached()) { @@ -1201,8 +1223,6 @@ TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) { assert(tok.is(tok::annot_template_id) && "Expected template-id token"); TemplateIdAnnotation * Id = static_cast<TemplateIdAnnotation *>(tok.getAnnotationValue()); - TopLevelDeclCleanupPool.delayMemberFunc< TemplateIdAnnotation, - &TemplateIdAnnotation::Destroy>(Id); return Id; } diff --git a/contrib/llvm/tools/clang/lib/Rewrite/RewriteModernObjC.cpp b/contrib/llvm/tools/clang/lib/Rewrite/RewriteModernObjC.cpp index 57109de..94fba64 100644 --- a/contrib/llvm/tools/clang/lib/Rewrite/RewriteModernObjC.cpp +++ b/contrib/llvm/tools/clang/lib/Rewrite/RewriteModernObjC.cpp @@ -304,7 +304,6 @@ namespace { void RewriteFunctionDecl(FunctionDecl *FD); void RewriteBlockPointerType(std::string& Str, QualType Type); void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD); - void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); void RewriteTypeOfDecl(VarDecl *VD); void RewriteObjCQualifiedInterfaceTypes(Expr *E); @@ -2246,31 +2245,7 @@ void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str, } } - -void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { - SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); - const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); - const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType); - if (!proto) - return; - QualType Type = proto->getResultType(); - std::string FdStr = Type.getAsString(Context->getPrintingPolicy()); - FdStr += " "; - FdStr += FD->getName(); - FdStr += "("; - unsigned numArgs = proto->getNumArgs(); - for (unsigned i = 0; i < numArgs; i++) { - QualType ArgType = proto->getArgType(i); - RewriteBlockPointerType(FdStr, ArgType); - if (i+1 < numArgs) - FdStr += ", "; - } - FdStr += ");\n"; - InsertText(FunLocStart, FdStr); - CurFunctionDeclToDeclareForBlock = 0; -} - -// SynthSuperContructorFunctionDecl - id objc_super(id obj, id super); +// SynthSuperContructorFunctionDecl - id __rw_objc_super(id obj, id super); void RewriteModernObjC::SynthSuperContructorFunctionDecl() { if (SuperContructorFunctionDecl) return; @@ -2311,21 +2286,13 @@ void RewriteModernObjC::SynthMsgSendFunctionDecl() { SC_None, false); } -// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...); +// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void); void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() { IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); - SmallVector<QualType, 16> ArgTys; - RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("objc_super")); - QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); - assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); + SmallVector<QualType, 2> ArgTys; + ArgTys.push_back(Context->VoidTy); QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - &ArgTys[0], ArgTys.size(), + &ArgTys[0], 1, true /*isVariadic*/); MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), @@ -2357,22 +2324,14 @@ void RewriteModernObjC::SynthMsgSendStretFunctionDecl() { } // SynthMsgSendSuperStretFunctionDecl - -// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...); +// id objc_msgSendSuper_stret(void); void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() { IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper_stret"); - SmallVector<QualType, 16> ArgTys; - RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("objc_super")); - QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); - assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); + SmallVector<QualType, 2> ArgTys; + ArgTys.push_back(Context->VoidTy); QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - &ArgTys[0], ArgTys.size(), + &ArgTys[0], 1, true /*isVariadic*/); MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), @@ -2925,18 +2884,20 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral return CE; } -// struct objc_super { struct objc_object *receiver; struct objc_class *super; }; +// struct __rw_objc_super { +// struct objc_object *object; struct objc_object *superClass; +// }; QualType RewriteModernObjC::getSuperStructType() { if (!SuperStructDecl) { SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), SourceLocation(), - &Context->Idents.get("objc_super")); + &Context->Idents.get("__rw_objc_super")); QualType FieldTypes[2]; - // struct objc_object *receiver; + // struct objc_object *object; FieldTypes[0] = Context->getObjCIdType(); - // struct objc_class *super; - FieldTypes[1] = Context->getObjCClassType(); + // struct objc_object *superClass; + FieldTypes[1] = Context->getObjCIdType(); // Create fields for (unsigned i = 0; i < 2; ++i) { @@ -3073,7 +3034,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), CK_BitCast, Cls)); - // struct objc_super + // struct __rw_objc_super QualType superType = getSuperStructType(); Expr *SuperRep; @@ -3091,7 +3052,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // the structure definition in the header. The rewriter has it's own // internal definition (__rw_objc_super) that is uses. This is why // we need the cast below. For example: - // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) + // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), @@ -3101,7 +3062,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, Context->getPointerType(superType), CK_BitCast, SuperRep); } else { - // (struct objc_super) { <exprs from above> } + // (struct __rw_objc_super) { <exprs from above> } InitListExpr *ILE = new (Context) InitListExpr(*Context, SourceLocation(), &InitExprs[0], InitExprs.size(), @@ -3111,7 +3072,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, superType, VK_LValue, ILE, false); - // struct objc_super * + // struct __rw_objc_super * SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, @@ -3183,7 +3144,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // set 'super class', using class_getSuperclass(). NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), CK_BitCast, Cls)); - // struct objc_super + // struct __rw_objc_super QualType superType = getSuperStructType(); Expr *SuperRep; @@ -3200,7 +3161,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // the structure definition in the header. The rewriter has it's own // internal definition (__rw_objc_super) that is uses. This is why // we need the cast below. For example: - // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) + // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), @@ -3210,7 +3171,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, Context->getPointerType(superType), CK_BitCast, SuperRep); } else { - // (struct objc_super) { <exprs from above> } + // (struct __rw_objc_super) { <exprs from above> } InitListExpr *ILE = new (Context) InitListExpr(*Context, SourceLocation(), &InitExprs[0], InitExprs.size(), @@ -4022,11 +3983,25 @@ std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, return S; } +/// getFunctionSourceLocation - returns start location of a function +/// definition. Complication arises when function has declared as +/// extern "C" or extern "C" {...} +static SourceLocation getFunctionSourceLocation (FunctionDecl *FD) { + if (!FD->isExternC() || FD->isMain()) + return FD->getTypeSpecStartLoc(); + const DeclContext *DC = FD->getDeclContext(); + if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC)) { + SourceLocation BodyRBrace = LSD->getRBraceLoc(); + // if it is extern "C" {...}, return function decl's own location. + if (BodyRBrace.isValid()) + return FD->getTypeSpecStartLoc(); + return LSD->getExternLoc(); + } + return FD->getTypeSpecStartLoc(); +} + void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, StringRef FunName) { - // Insert declaration for the function in which block literal is used. - if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) - RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); bool RewriteSC = (GlobalVarDecl && !Blocks.empty() && GlobalVarDecl->getStorageClass() == SC_Static && @@ -4135,7 +4110,7 @@ void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, } void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { - SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); + SourceLocation FunLocStart = getFunctionSourceLocation(FD); StringRef FuncName = FD->getName(); SynthesizeBlockLiterals(FunLocStart, FuncName); @@ -4170,11 +4145,15 @@ void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) { GetBlockDeclRefExprs(*CI); } // Handle specific things. - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) - if (DRE->refersToEnclosingLocal() && - HasLocalVariableExternalStorage(DRE->getDecl())) { - BlockDeclRefs.push_back(DRE); + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { + if (DRE->refersToEnclosingLocal()) { + // FIXME: Handle enums. + if (!isa<FunctionDecl>(DRE->getDecl())) + BlockDeclRefs.push_back(DRE); + if (HasLocalVariableExternalStorage(DRE->getDecl())) + BlockDeclRefs.push_back(DRE); } + } return; } @@ -4474,19 +4453,18 @@ void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) { void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) { CastKind CastKind = IC->getCastKind(); + if (CastKind != CK_BlockPointerToObjCPointerCast && + CastKind != CK_AnyPointerToBlockPointerCast) + return; - if (CastKind == CK_BlockPointerToObjCPointerCast) { - CStyleCastExpr * CastExpr = - NoTypeInfoCStyleCastExpr(Context, IC->getType(), CK_BitCast, IC); - ReplaceStmt(IC, CastExpr); - } - else if (CastKind == CK_AnyPointerToBlockPointerCast) { - QualType BlockT = IC->getType(); - (void)convertBlockPointerToFunctionPointer(BlockT); - CStyleCastExpr * CastExpr = - NoTypeInfoCStyleCastExpr(Context, BlockT, CK_BitCast, IC); - ReplaceStmt(IC, CastExpr); - } + QualType QT = IC->getType(); + (void)convertBlockPointerToFunctionPointer(QT); + std::string TypeString(QT.getAsString(Context->getPrintingPolicy())); + std::string Str = "("; + Str += TypeString; + Str += ")"; + InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size()); + return; } @@ -4742,10 +4720,6 @@ std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, /// /// void RewriteModernObjC::RewriteByRefVar(VarDecl *ND) { - // Insert declaration for the function in which block literal is - // used. - if (CurFunctionDeclToDeclareForBlock) - RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); int flag = 0; int isa = 0; SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); @@ -4784,7 +4758,7 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND) { // Insert this type in global scope. It is needed by helper function. SourceLocation FunLocStart; if (CurFunctionDef) - FunLocStart = CurFunctionDef->getTypeSpecStartLoc(); + FunLocStart = getFunctionSourceLocation(CurFunctionDef); else { assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); FunLocStart = CurMethodDef->getLocStart(); @@ -5375,6 +5349,7 @@ Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { RewriteImplicitCastObjCExpr(ICE); } #if 0 + if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), ICE->getSubExpr(), @@ -5627,13 +5602,11 @@ void RewriteModernObjC::Initialize(ASTContext &context) { // These are currently generated. Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n"; Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n"; - Preamble += "#pragma section(\".objc_protolist$B\", long, read, write)\n"; Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n"; Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n"; Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n"; Preamble += "#pragma section(\".objc_protorefs$B\", long, read, write)\n"; // These are generated but not necessary for functionality. - Preamble += "#pragma section(\".datacoal_nt$B\", long, read, write)\n"; Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n"; Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n"; Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n"; @@ -6604,7 +6577,7 @@ void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, // Writer out root metadata for current protocol: struct _protocol_t Result += "\n"; if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".datacoal_nt$B\")) "; + Result += "static "; Result += "struct _protocol_t _OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n"; @@ -6662,11 +6635,8 @@ void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, else Result += "\t0\n};\n"; - // Use this protocol meta-data to build protocol list table in section - // .objc_protolist$B - // Unspecified visibility means 'private extern'. if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".objc_protolist$B\")) "; + Result += "static "; Result += "struct _protocol_t *"; Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString(); Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); diff --git a/contrib/llvm/tools/clang/lib/Rewrite/RewriteRope.cpp b/contrib/llvm/tools/clang/lib/Rewrite/RewriteRope.cpp index 6c211b2..cc8de1b 100644 --- a/contrib/llvm/tools/clang/lib/Rewrite/RewriteRope.cpp +++ b/contrib/llvm/tools/clang/lib/Rewrite/RewriteRope.cpp @@ -407,6 +407,11 @@ namespace { Size = LHS->size() + RHS->size(); } + ~RopePieceBTreeInterior() { + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + Children[i]->Destroy(); + } + bool isFull() const { return NumChildren == 2*WidthFactor; } unsigned getNumChildren() const { return NumChildren; } diff --git a/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp b/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp index b531acc..fe63e35 100644 --- a/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp @@ -162,6 +162,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, + CachedTokens *ExceptionSpecTokens, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, @@ -226,6 +227,10 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, case EST_ComputedNoexcept: I.Fun.NoexceptExpr = NoexceptExpr; break; + + case EST_Delayed: + I.Fun.ExceptionSpecTokens = ExceptionSpecTokens; + break; } return I; } diff --git a/contrib/llvm/tools/clang/lib/Sema/Sema.cpp b/contrib/llvm/tools/clang/lib/Sema/Sema.cpp index fcdfcac..30a9cd7 100644 --- a/contrib/llvm/tools/clang/lib/Sema/Sema.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/Sema.cpp @@ -103,6 +103,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, AnalysisWarnings(*this) { TUScope = 0; + LoadedExternalKnownNamespaces = false; for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I) NSNumberLiteralMethods[I] = 0; diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp index dea5e76..01c141e 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp @@ -779,6 +779,13 @@ static AccessResult HasAccess(Sema &S, // that the naming class has to be derived from the effective // context. + // Emulate a MSVC bug where the creation of pointer-to-member + // to protected member of base class is allowed but only from + // a static function member functions. + if (S.getLangOpts().MicrosoftMode && !EC.Functions.empty()) + if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front())) + if (MD->isStatic()) return AR_accessible; + // Despite the standard's confident wording, there is a case // where you can have an instance member that's neither in a // pointer-to-member expression nor in a member access: when diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp index 8b314b5..1550993 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp @@ -4471,6 +4471,11 @@ static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier, return false; } +static bool hasDelayedExceptionSpec(CXXMethodDecl *Method) { + const FunctionProtoType *Proto =Method->getType()->getAs<FunctionProtoType>(); + return Proto && Proto->getExceptionSpecType() == EST_Delayed; +} + /// AddOverriddenMethods - See if a method overrides any in the base classes, /// and if so, check that it's a valid override and remember it. bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { @@ -4486,7 +4491,8 @@ bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) { MD->addOverriddenMethod(OldMD->getCanonicalDecl()); if (!CheckOverridingFunctionReturnType(MD, OldMD) && - !CheckOverridingFunctionExceptionSpec(MD, OldMD) && + (hasDelayedExceptionSpec(MD) || + !CheckOverridingFunctionExceptionSpec(MD, OldMD)) && !CheckIfOverriddenFunctionIsMarkedFinal(MD, OldMD)) { AddedAny = true; } @@ -5834,6 +5840,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } } } + + if (Method->isStatic()) + checkThisInStaticMemberFunctionType(Method); } // Extra checking for C++ overloaded operators (C++ [over.oper]). @@ -7176,8 +7185,7 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, } } -Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, - Declarator &D) { +Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { assert(getCurFunctionDecl() == 0 && "Function parsing confused"); assert(D.isFunctionDeclarator() && "Not a function declarator!"); Scope *ParentScope = FnBodyScope->getParent(); @@ -7350,6 +7358,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { } } + // Ensure that the function's exception specification is instantiated. + if (const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>()) + ResolveExceptionSpec(D->getLocation(), FPT); + // Checking attributes of current function definition // dllimport attribute. DLLImportAttr *DA = FD->getAttr<DLLImportAttr>(); @@ -7554,7 +7566,11 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D, // Always attach attributes to the underlying decl. if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) D = TD->getTemplatedDecl(); - ProcessDeclAttributeList(S, D, Attrs.getList()); + ProcessDeclAttributeList(S, D, Attrs.getList()); + + if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(D)) + if (Method->isStatic()) + checkThisInStaticMemberFunctionAttributes(Method); } @@ -7619,7 +7635,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, SourceLocation(), SourceLocation(), SourceLocation(), EST_None, SourceLocation(), - 0, 0, 0, 0, Loc, Loc, D), + 0, 0, 0, 0, 0, Loc, Loc, D), DS.getAttributes(), SourceLocation()); D.SetIdentifier(&II, Loc); diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp index 847f03c..1d251b9 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp @@ -25,6 +25,7 @@ #include "clang/AST/DeclVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/RecordLayout.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeOrdering.h" @@ -124,14 +125,17 @@ namespace { } } -void Sema::ImplicitExceptionSpecification::CalledDecl(CXXMethodDecl *Method) { - assert(Context && "ImplicitExceptionSpecification without an ASTContext"); +void Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc, + CXXMethodDecl *Method) { // If we have an MSAny or unknown spec already, don't bother. if (!Method || ComputedEST == EST_MSAny || ComputedEST == EST_Delayed) return; const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>(); + Proto = Self->ResolveExceptionSpec(CallLoc, Proto); + if (!Proto) + return; ExceptionSpecificationType EST = Proto->getExceptionSpecType(); @@ -163,7 +167,8 @@ void Sema::ImplicitExceptionSpecification::CalledDecl(CXXMethodDecl *Method) { // Check out noexcept specs. if (EST == EST_ComputedNoexcept) { - FunctionProtoType::NoexceptResult NR = Proto->getNoexceptSpec(*Context); + FunctionProtoType::NoexceptResult NR = + Proto->getNoexceptSpec(Self->Context); assert(NR != FunctionProtoType::NR_NoNoexcept && "Must have noexcept result for EST_ComputedNoexcept."); assert(NR != FunctionProtoType::NR_Dependent && @@ -187,7 +192,7 @@ void Sema::ImplicitExceptionSpecification::CalledDecl(CXXMethodDecl *Method) { for (FunctionProtoType::exception_iterator E = Proto->exception_begin(), EEnd = Proto->exception_end(); E != EEnd; ++E) - if (ExceptionsSeen.insert(Context->getCanonicalType(*E))) + if (ExceptionsSeen.insert(Self->Context.getCanonicalType(*E))) Exceptions.push_back(*E); } @@ -216,7 +221,7 @@ void Sema::ImplicitExceptionSpecification::CalledExpr(Expr *E) { // implicit definition. For now, we assume that any non-nothrow expression can // throw any exception. - if (E->CanThrow(*Context)) + if (Self->canThrow(E)) ComputedEST = EST_None; } @@ -3921,7 +3926,7 @@ void Sema::CheckExplicitlyDefaultedCopyConstructor(CXXConstructorDecl *CD) { HadError = true; } - ImplicitExceptionSpecification Spec(Context); + ImplicitExceptionSpecification Spec(*this); bool Const; llvm::tie(Spec, Const) = ComputeDefaultedCopyCtorExceptionSpecAndConst(CD->getParent()); @@ -4030,7 +4035,7 @@ void Sema::CheckExplicitlyDefaultedCopyAssignment(CXXMethodDecl *MD) { HadError = true; } - ImplicitExceptionSpecification Spec(Context); + ImplicitExceptionSpecification Spec(*this); bool Const; llvm::tie(Spec, Const) = ComputeDefaultedCopyCtorExceptionSpecAndConst(MD->getParent()); @@ -5920,10 +5925,12 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S, case UnqualifiedId::IK_ConstructorName: case UnqualifiedId::IK_ConstructorTemplateId: - // C++0x inherited constructors. + // C++11 inheriting constructors. Diag(Name.getLocStart(), getLangOpts().CPlusPlus0x ? - diag::warn_cxx98_compat_using_decl_constructor : + // FIXME: Produce warn_cxx98_compat_using_decl_constructor + // instead once inheriting constructors work. + diag::err_using_decl_constructor_unsupported : diag::err_using_decl_constructor) << SS.getRange(); @@ -6813,7 +6820,7 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // C++ [except.spec]p14: // An implicitly declared special member function (Clause 12) shall have an // exception-specification. [...] - ImplicitExceptionSpecification ExceptSpec(Context); + ImplicitExceptionSpecification ExceptSpec(*this); if (ClassDecl->isInvalidDecl()) return ExceptSpec; @@ -6830,7 +6837,7 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // If this is a deleted function, add it anyway. This might be conformant // with the standard. This might not. I'm not sure. It might not matter. if (Constructor) - ExceptSpec.CalledDecl(Constructor); + ExceptSpec.CalledDecl(B->getLocStart(), Constructor); } } @@ -6844,7 +6851,7 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // If this is a deleted function, add it anyway. This might be conformant // with the standard. This might not. I'm not sure. It might not matter. if (Constructor) - ExceptSpec.CalledDecl(Constructor); + ExceptSpec.CalledDecl(B->getLocStart(), Constructor); } } @@ -6867,7 +6874,7 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // might just be ill-formed because this function attempts to refer to // a deleted function here. if (Constructor) - ExceptSpec.CalledDecl(Constructor); + ExceptSpec.CalledDecl(F->getLocation(), Constructor); } } @@ -6989,6 +6996,7 @@ void Sema::ActOnFinishDelayedMemberInitializers(Decl *D) { const FunctionProtoType *CtorTy = CtorDecl->getType()->castAs<FunctionProtoType>(); if (CtorTy->getExceptionSpecType() == EST_Delayed) { + // FIXME: Don't do this unless the exception spec is needed. ImplicitExceptionSpecification Spec = ComputeDefaultedDefaultCtorExceptionSpec(ClassDecl); FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI(); @@ -7189,7 +7197,7 @@ Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) { // C++ [except.spec]p14: // An implicitly declared special member function (Clause 12) shall have // an exception-specification. - ImplicitExceptionSpecification ExceptSpec(Context); + ImplicitExceptionSpecification ExceptSpec(*this); if (ClassDecl->isInvalidDecl()) return ExceptSpec; @@ -7201,7 +7209,7 @@ Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) { continue; if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) - ExceptSpec.CalledDecl( + ExceptSpec.CalledDecl(B->getLocStart(), LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl()))); } @@ -7210,7 +7218,7 @@ Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) { BEnd = ClassDecl->vbases_end(); B != BEnd; ++B) { if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) - ExceptSpec.CalledDecl( + ExceptSpec.CalledDecl(B->getLocStart(), LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl()))); } @@ -7220,7 +7228,7 @@ Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) { F != FEnd; ++F) { if (const RecordType *RecordTy = Context.getBaseElementType(F->getType())->getAs<RecordType>()) - ExceptSpec.CalledDecl( + ExceptSpec.CalledDecl(F->getLocation(), LookupDestructor(cast<CXXRecordDecl>(RecordTy->getDecl()))); } @@ -7545,7 +7553,7 @@ std::pair<Sema::ImplicitExceptionSpecification, bool> Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst( CXXRecordDecl *ClassDecl) { if (ClassDecl->isInvalidDecl()) - return std::make_pair(ImplicitExceptionSpecification(Context), false); + return std::make_pair(ImplicitExceptionSpecification(*this), false); // C++ [class.copy]p10: // If the class definition does not explicitly declare a copy @@ -7618,7 +7626,7 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst( // Based on a similar decision made for constness in C++0x, we're erring on // the side of assuming such calls to be made regardless of whether they // actually happen. - ImplicitExceptionSpecification ExceptSpec(Context); + ImplicitExceptionSpecification ExceptSpec(*this); unsigned ArgQuals = HasConstCopyAssignment ? Qualifiers::Const : 0; for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), BaseEnd = ClassDecl->bases_end(); @@ -7630,7 +7638,7 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst( = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl, ArgQuals, false, 0)) - ExceptSpec.CalledDecl(CopyAssign); + ExceptSpec.CalledDecl(Base->getLocStart(), CopyAssign); } for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), @@ -7640,7 +7648,7 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst( = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl, ArgQuals, false, 0)) - ExceptSpec.CalledDecl(CopyAssign); + ExceptSpec.CalledDecl(Base->getLocStart(), CopyAssign); } for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), @@ -7651,7 +7659,7 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst( if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) { if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(FieldClassDecl, ArgQuals, false, 0)) - ExceptSpec.CalledDecl(CopyAssign); + ExceptSpec.CalledDecl(Field->getLocation(), CopyAssign); } } @@ -7664,7 +7672,7 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) { // for determining the argument type of the operator. Note also that // operators taking an object instead of a reference are allowed. - ImplicitExceptionSpecification Spec(Context); + ImplicitExceptionSpecification Spec(*this); bool Const; llvm::tie(Spec, Const) = ComputeDefaultedCopyAssignmentExceptionSpecAndConst(ClassDecl); @@ -8031,7 +8039,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, Sema::ImplicitExceptionSpecification Sema::ComputeDefaultedMoveAssignmentExceptionSpec(CXXRecordDecl *ClassDecl) { - ImplicitExceptionSpecification ExceptSpec(Context); + ImplicitExceptionSpecification ExceptSpec(*this); if (ClassDecl->isInvalidDecl()) return ExceptSpec; @@ -8058,7 +8066,7 @@ Sema::ComputeDefaultedMoveAssignmentExceptionSpec(CXXRecordDecl *ClassDecl) { = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(BaseClassDecl, false, 0)) - ExceptSpec.CalledDecl(MoveAssign); + ExceptSpec.CalledDecl(Base->getLocStart(), MoveAssign); } for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), @@ -8068,7 +8076,7 @@ Sema::ComputeDefaultedMoveAssignmentExceptionSpec(CXXRecordDecl *ClassDecl) { = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(BaseClassDecl, false, 0)) - ExceptSpec.CalledDecl(MoveAssign); + ExceptSpec.CalledDecl(Base->getLocStart(), MoveAssign); } for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), @@ -8079,7 +8087,7 @@ Sema::ComputeDefaultedMoveAssignmentExceptionSpec(CXXRecordDecl *ClassDecl) { if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) { if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(FieldClassDecl, false, 0)) - ExceptSpec.CalledDecl(MoveAssign); + ExceptSpec.CalledDecl(Field->getLocation(), MoveAssign); } } @@ -8577,7 +8585,7 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, std::pair<Sema::ImplicitExceptionSpecification, bool> Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) { if (ClassDecl->isInvalidDecl()) - return std::make_pair(ImplicitExceptionSpecification(Context), false); + return std::make_pair(ImplicitExceptionSpecification(*this), false); // C++ [class.copy]p5: // The implicitly-declared copy constructor for a class X will @@ -8638,7 +8646,7 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) { // C++ [except.spec]p14: // An implicitly declared special member function (Clause 12) shall have an // exception-specification. [...] - ImplicitExceptionSpecification ExceptSpec(Context); + ImplicitExceptionSpecification ExceptSpec(*this); unsigned Quals = HasConstCopyConstructor? Qualifiers::Const : 0; for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), BaseEnd = ClassDecl->bases_end(); @@ -8652,7 +8660,7 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) { = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); if (CXXConstructorDecl *CopyConstructor = LookupCopyingConstructor(BaseClassDecl, Quals)) - ExceptSpec.CalledDecl(CopyConstructor); + ExceptSpec.CalledDecl(Base->getLocStart(), CopyConstructor); } for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), BaseEnd = ClassDecl->vbases_end(); @@ -8662,7 +8670,7 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) { = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); if (CXXConstructorDecl *CopyConstructor = LookupCopyingConstructor(BaseClassDecl, Quals)) - ExceptSpec.CalledDecl(CopyConstructor); + ExceptSpec.CalledDecl(Base->getLocStart(), CopyConstructor); } for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), FieldEnd = ClassDecl->field_end(); @@ -8672,7 +8680,7 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) { if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) { if (CXXConstructorDecl *CopyConstructor = LookupCopyingConstructor(FieldClassDecl, Quals)) - ExceptSpec.CalledDecl(CopyConstructor); + ExceptSpec.CalledDecl(Field->getLocation(), CopyConstructor); } } @@ -8685,7 +8693,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( // If the class definition does not explicitly declare a copy // constructor, one is declared implicitly. - ImplicitExceptionSpecification Spec(Context); + ImplicitExceptionSpecification Spec(*this); bool Const; llvm::tie(Spec, Const) = ComputeDefaultedCopyCtorExceptionSpecAndConst(ClassDecl); @@ -8783,7 +8791,7 @@ Sema::ComputeDefaultedMoveCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // C++ [except.spec]p14: // An implicitly declared special member function (Clause 12) shall have an // exception-specification. [...] - ImplicitExceptionSpecification ExceptSpec(Context); + ImplicitExceptionSpecification ExceptSpec(*this); if (ClassDecl->isInvalidDecl()) return ExceptSpec; @@ -8800,7 +8808,7 @@ Sema::ComputeDefaultedMoveCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // If this is a deleted function, add it anyway. This might be conformant // with the standard. This might not. I'm not sure. It might not matter. if (Constructor) - ExceptSpec.CalledDecl(Constructor); + ExceptSpec.CalledDecl(B->getLocStart(), Constructor); } } @@ -8814,7 +8822,7 @@ Sema::ComputeDefaultedMoveCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // If this is a deleted function, add it anyway. This might be conformant // with the standard. This might not. I'm not sure. It might not matter. if (Constructor) - ExceptSpec.CalledDecl(Constructor); + ExceptSpec.CalledDecl(B->getLocStart(), Constructor); } } @@ -8832,7 +8840,7 @@ Sema::ComputeDefaultedMoveCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // might just be ill-formed because this function attempts to refer to // a deleted function here. if (Constructor) - ExceptSpec.CalledDecl(Constructor); + ExceptSpec.CalledDecl(F->getLocation(), Constructor); } } @@ -11053,6 +11061,265 @@ void Sema::CheckDelegatingCtorCycles() { (*CI)->setInvalidDecl(); } +namespace { + /// \brief AST visitor that finds references to the 'this' expression. + class FindCXXThisExpr : public RecursiveASTVisitor<FindCXXThisExpr> { + Sema &S; + + public: + explicit FindCXXThisExpr(Sema &S) : S(S) { } + + bool VisitCXXThisExpr(CXXThisExpr *E) { + S.Diag(E->getLocation(), diag::err_this_static_member_func) + << E->isImplicit(); + return false; + } + }; +} + +bool Sema::checkThisInStaticMemberFunctionType(CXXMethodDecl *Method) { + TypeSourceInfo *TSInfo = Method->getTypeSourceInfo(); + if (!TSInfo) + return false; + + TypeLoc TL = TSInfo->getTypeLoc(); + FunctionProtoTypeLoc *ProtoTL = dyn_cast<FunctionProtoTypeLoc>(&TL); + if (!ProtoTL) + return false; + + // C++11 [expr.prim.general]p3: + // [The expression this] shall not appear before the optional + // cv-qualifier-seq and it shall not appear within the declaration of a + // static member function (although its type and value category are defined + // within a static member function as they are within a non-static member + // function). [ Note: this is because declaration matching does not occur + // until the complete declarator is known. - end note ] + const FunctionProtoType *Proto = ProtoTL->getTypePtr(); + FindCXXThisExpr Finder(*this); + + // If the return type came after the cv-qualifier-seq, check it now. + if (Proto->hasTrailingReturn() && + !Finder.TraverseTypeLoc(ProtoTL->getResultLoc())) + return true; + + // Check the exception specification. + if (checkThisInStaticMemberFunctionExceptionSpec(Method)) + return true; + + return checkThisInStaticMemberFunctionAttributes(Method); +} + +bool Sema::checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method) { + TypeSourceInfo *TSInfo = Method->getTypeSourceInfo(); + if (!TSInfo) + return false; + + TypeLoc TL = TSInfo->getTypeLoc(); + FunctionProtoTypeLoc *ProtoTL = dyn_cast<FunctionProtoTypeLoc>(&TL); + if (!ProtoTL) + return false; + + const FunctionProtoType *Proto = ProtoTL->getTypePtr(); + FindCXXThisExpr Finder(*this); + + switch (Proto->getExceptionSpecType()) { + case EST_Uninstantiated: + case EST_BasicNoexcept: + case EST_Delayed: + case EST_DynamicNone: + case EST_MSAny: + case EST_None: + break; + + case EST_ComputedNoexcept: + if (!Finder.TraverseStmt(Proto->getNoexceptExpr())) + return true; + + case EST_Dynamic: + for (FunctionProtoType::exception_iterator E = Proto->exception_begin(), + EEnd = Proto->exception_end(); + E != EEnd; ++E) { + if (!Finder.TraverseType(*E)) + return true; + } + break; + } + + return false; +} + +bool Sema::checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method) { + FindCXXThisExpr Finder(*this); + + // Check attributes. + for (Decl::attr_iterator A = Method->attr_begin(), AEnd = Method->attr_end(); + A != AEnd; ++A) { + // FIXME: This should be emitted by tblgen. + Expr *Arg = 0; + ArrayRef<Expr *> Args; + if (GuardedByAttr *G = dyn_cast<GuardedByAttr>(*A)) + Arg = G->getArg(); + else if (PtGuardedByAttr *G = dyn_cast<PtGuardedByAttr>(*A)) + Arg = G->getArg(); + else if (AcquiredAfterAttr *AA = dyn_cast<AcquiredAfterAttr>(*A)) + Args = ArrayRef<Expr *>(AA->args_begin(), AA->args_size()); + else if (AcquiredBeforeAttr *AB = dyn_cast<AcquiredBeforeAttr>(*A)) + Args = ArrayRef<Expr *>(AB->args_begin(), AB->args_size()); + else if (ExclusiveLockFunctionAttr *ELF + = dyn_cast<ExclusiveLockFunctionAttr>(*A)) + Args = ArrayRef<Expr *>(ELF->args_begin(), ELF->args_size()); + else if (SharedLockFunctionAttr *SLF + = dyn_cast<SharedLockFunctionAttr>(*A)) + Args = ArrayRef<Expr *>(SLF->args_begin(), SLF->args_size()); + else if (ExclusiveTrylockFunctionAttr *ETLF + = dyn_cast<ExclusiveTrylockFunctionAttr>(*A)) { + Arg = ETLF->getSuccessValue(); + Args = ArrayRef<Expr *>(ETLF->args_begin(), ETLF->args_size()); + } else if (SharedTrylockFunctionAttr *STLF + = dyn_cast<SharedTrylockFunctionAttr>(*A)) { + Arg = STLF->getSuccessValue(); + Args = ArrayRef<Expr *>(STLF->args_begin(), STLF->args_size()); + } else if (UnlockFunctionAttr *UF = dyn_cast<UnlockFunctionAttr>(*A)) + Args = ArrayRef<Expr *>(UF->args_begin(), UF->args_size()); + else if (LockReturnedAttr *LR = dyn_cast<LockReturnedAttr>(*A)) + Arg = LR->getArg(); + else if (LocksExcludedAttr *LE = dyn_cast<LocksExcludedAttr>(*A)) + Args = ArrayRef<Expr *>(LE->args_begin(), LE->args_size()); + else if (ExclusiveLocksRequiredAttr *ELR + = dyn_cast<ExclusiveLocksRequiredAttr>(*A)) + Args = ArrayRef<Expr *>(ELR->args_begin(), ELR->args_size()); + else if (SharedLocksRequiredAttr *SLR + = dyn_cast<SharedLocksRequiredAttr>(*A)) + Args = ArrayRef<Expr *>(SLR->args_begin(), SLR->args_size()); + + if (Arg && !Finder.TraverseStmt(Arg)) + return true; + + for (unsigned I = 0, N = Args.size(); I != N; ++I) { + if (!Finder.TraverseStmt(Args[I])) + return true; + } + } + + return false; +} + +void +Sema::checkExceptionSpecification(ExceptionSpecificationType EST, + ArrayRef<ParsedType> DynamicExceptions, + ArrayRef<SourceRange> DynamicExceptionRanges, + Expr *NoexceptExpr, + llvm::SmallVectorImpl<QualType> &Exceptions, + FunctionProtoType::ExtProtoInfo &EPI) { + Exceptions.clear(); + EPI.ExceptionSpecType = EST; + if (EST == EST_Dynamic) { + Exceptions.reserve(DynamicExceptions.size()); + for (unsigned ei = 0, ee = DynamicExceptions.size(); ei != ee; ++ei) { + // FIXME: Preserve type source info. + QualType ET = GetTypeFromParser(DynamicExceptions[ei]); + + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + collectUnexpandedParameterPacks(ET, Unexpanded); + if (!Unexpanded.empty()) { + DiagnoseUnexpandedParameterPacks(DynamicExceptionRanges[ei].getBegin(), + UPPC_ExceptionType, + Unexpanded); + continue; + } + + // Check that the type is valid for an exception spec, and + // drop it if not. + if (!CheckSpecifiedExceptionType(ET, DynamicExceptionRanges[ei])) + Exceptions.push_back(ET); + } + EPI.NumExceptions = Exceptions.size(); + EPI.Exceptions = Exceptions.data(); + return; + } + + if (EST == EST_ComputedNoexcept) { + // If an error occurred, there's no expression here. + if (NoexceptExpr) { + assert((NoexceptExpr->isTypeDependent() || + NoexceptExpr->getType()->getCanonicalTypeUnqualified() == + Context.BoolTy) && + "Parser should have made sure that the expression is boolean"); + if (NoexceptExpr && DiagnoseUnexpandedParameterPack(NoexceptExpr)) { + EPI.ExceptionSpecType = EST_BasicNoexcept; + return; + } + + if (!NoexceptExpr->isValueDependent()) + NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, 0, + PDiag(diag::err_noexcept_needs_constant_expression), + /*AllowFold*/ false).take(); + EPI.NoexceptExpr = NoexceptExpr; + } + return; + } +} + +void Sema::actOnDelayedExceptionSpecification(Decl *MethodD, + ExceptionSpecificationType EST, + SourceRange SpecificationRange, + ArrayRef<ParsedType> DynamicExceptions, + ArrayRef<SourceRange> DynamicExceptionRanges, + Expr *NoexceptExpr) { + if (!MethodD) + return; + + // Dig out the method we're referring to. + CXXMethodDecl *Method = 0; + if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(MethodD)) + Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); + else + Method = dyn_cast<CXXMethodDecl>(MethodD); + + if (!Method) + return; + + // Dig out the prototype. This should never fail. + const FunctionProtoType *Proto + = dyn_cast<FunctionProtoType>(Method->getType()); + if (!Proto) + return; + + // Check the exception specification. + llvm::SmallVector<QualType, 4> Exceptions; + FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); + checkExceptionSpecification(EST, DynamicExceptions, DynamicExceptionRanges, + NoexceptExpr, Exceptions, EPI); + + // Rebuild the function type. + QualType T = Context.getFunctionType(Proto->getResultType(), + Proto->arg_type_begin(), + Proto->getNumArgs(), + EPI); + if (TypeSourceInfo *TSInfo = Method->getTypeSourceInfo()) { + // FIXME: When we get proper type location information for exceptions, + // we'll also have to rebuild the TypeSourceInfo. For now, we just patch + // up the TypeSourceInfo; + assert(TypeLoc::getFullDataSizeForType(T) + == TypeLoc::getFullDataSizeForType(Method->getType()) && + "TypeLoc size mismatch with delayed exception specification"); + TSInfo->overrideType(T); + } + + Method->setType(T); + + if (Method->isStatic()) + checkThisInStaticMemberFunctionExceptionSpec(Method); + + if (Method->isVirtual()) { + // Check overrides, which we previously had to delay. + for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(), + OEnd = Method->end_overridden_methods(); + O != OEnd; ++O) + CheckOverridingFunctionExceptionSpec(Method, *O); + } +} + /// IdentifyCUDATarget - Determine the CUDA compilation target for this function Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) { // Implicitly declared functions (e.g. copy constructors) are diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp index 42221f8..14b2434 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp @@ -96,6 +96,26 @@ bool Sema::CheckDistantExceptionSpec(QualType T) { return FnT->hasExceptionSpec(); } +const FunctionProtoType * +Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) { + // FIXME: If FD is a special member, we should delay computing its exception + // specification until this point. + if (FPT->getExceptionSpecType() != EST_Uninstantiated) + return FPT; + + FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl(); + const FunctionProtoType *SourceFPT = + SourceDecl->getType()->castAs<FunctionProtoType>(); + + if (SourceFPT->getExceptionSpecType() != EST_Uninstantiated) + return SourceFPT; + + // Instantiate the exception specification now. + InstantiateExceptionSpec(Loc, SourceDecl); + + return SourceDecl->getType()->castAs<FunctionProtoType>(); +} + bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator(); bool IsOperatorNew = OO == OO_New || OO == OO_Array_New; @@ -104,7 +124,7 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { unsigned DiagID = diag::err_mismatched_exception_spec; if (getLangOpts().MicrosoftExt) DiagID = diag::warn_mismatched_exception_spec; - + if (!CheckEquivalentExceptionSpec(PDiag(DiagID), PDiag(diag::note_previous_declaration), Old->getType()->getAs<FunctionProtoType>(), @@ -295,6 +315,13 @@ bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, if (MissingEmptyExceptionSpecification) *MissingEmptyExceptionSpecification = false; + Old = ResolveExceptionSpec(NewLoc, Old); + if (!Old) + return false; + New = ResolveExceptionSpec(NewLoc, New); + if (!New) + return false; + // C++0x [except.spec]p3: Two exception-specifications are compatible if: // - both are non-throwing, regardless of their form, // - both have the form noexcept(constant-expression) and the constant- @@ -318,6 +345,7 @@ bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, ExceptionSpecificationType NewEST = New->getExceptionSpecType(); assert(OldEST != EST_Delayed && NewEST != EST_Delayed && + OldEST != EST_Uninstantiated && NewEST != EST_Uninstantiated && "Shouldn't see unknown exception specifications here"); // Shortcut the case where both have no spec. @@ -483,6 +511,14 @@ bool Sema::CheckExceptionSpecSubset( if (!SubLoc.isValid()) SubLoc = SuperLoc; + // Resolve the exception specifications, if needed. + Superset = ResolveExceptionSpec(SuperLoc, Superset); + if (!Superset) + return false; + Subset = ResolveExceptionSpec(SubLoc, Subset); + if (!Subset) + return false; + ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType(); // If superset contains everything, we're done. @@ -507,6 +543,7 @@ bool Sema::CheckExceptionSpecSubset( ExceptionSpecificationType SubEST = Subset->getExceptionSpecType(); assert(SuperEST != EST_Delayed && SubEST != EST_Delayed && + SuperEST != EST_Uninstantiated && SubEST != EST_Uninstantiated && "Shouldn't see unknown exception specifications here"); // It does not. If the subset contains everything, we've failed. @@ -726,4 +763,324 @@ bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, New->getLocation()); } +static CanThrowResult canSubExprsThrow(Sema &S, const Expr *CE) { + Expr *E = const_cast<Expr*>(CE); + CanThrowResult R = CT_Cannot; + for (Expr::child_range I = E->children(); I && R != CT_Can; ++I) + R = mergeCanThrow(R, S.canThrow(cast<Expr>(*I))); + return R; +} + +static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, + const Decl *D, + bool NullThrows = true) { + if (!D) + return NullThrows ? CT_Can : CT_Cannot; + + // See if we can get a function type from the decl somehow. + const ValueDecl *VD = dyn_cast<ValueDecl>(D); + if (!VD) // If we have no clue what we're calling, assume the worst. + return CT_Can; + + // As an extension, we assume that __attribute__((nothrow)) functions don't + // throw. + if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) + return CT_Cannot; + + QualType T = VD->getType(); + const FunctionProtoType *FT; + if ((FT = T->getAs<FunctionProtoType>())) { + } else if (const PointerType *PT = T->getAs<PointerType>()) + FT = PT->getPointeeType()->getAs<FunctionProtoType>(); + else if (const ReferenceType *RT = T->getAs<ReferenceType>()) + FT = RT->getPointeeType()->getAs<FunctionProtoType>(); + else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) + FT = MT->getPointeeType()->getAs<FunctionProtoType>(); + else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) + FT = BT->getPointeeType()->getAs<FunctionProtoType>(); + + if (!FT) + return CT_Can; + + FT = S.ResolveExceptionSpec(E->getLocStart(), FT); + if (!FT) + return CT_Can; + + if (FT->getExceptionSpecType() == EST_Delayed) { + // FIXME: Try to resolve a delayed exception spec in ResolveExceptionSpec. + assert(isa<CXXConstructorDecl>(D) && + "only constructor exception specs can be unknown"); + S.Diag(E->getLocStart(), diag::err_exception_spec_unknown) + << E->getSourceRange(); + return CT_Can; + } + + return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can; +} + +static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { + if (DC->isTypeDependent()) + return CT_Dependent; + + if (!DC->getTypeAsWritten()->isReferenceType()) + return CT_Cannot; + + if (DC->getSubExpr()->isTypeDependent()) + return CT_Dependent; + + return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot; +} + +static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { + if (DC->isTypeOperand()) + return CT_Cannot; + + Expr *Op = DC->getExprOperand(); + if (Op->isTypeDependent()) + return CT_Dependent; + + const RecordType *RT = Op->getType()->getAs<RecordType>(); + if (!RT) + return CT_Cannot; + + if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) + return CT_Cannot; + + if (Op->Classify(S.Context).isPRValue()) + return CT_Cannot; + + return CT_Can; +} + +CanThrowResult Sema::canThrow(const Expr *E) { + // C++ [expr.unary.noexcept]p3: + // [Can throw] if in a potentially-evaluated context the expression would + // contain: + switch (E->getStmtClass()) { + case Expr::CXXThrowExprClass: + // - a potentially evaluated throw-expression + return CT_Can; + + case Expr::CXXDynamicCastExprClass: { + // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), + // where T is a reference type, that requires a run-time check + CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E)); + if (CT == CT_Can) + return CT; + return mergeCanThrow(CT, canSubExprsThrow(*this, E)); + } + + case Expr::CXXTypeidExprClass: + // - a potentially evaluated typeid expression applied to a glvalue + // expression whose type is a polymorphic class type + return canTypeidThrow(*this, cast<CXXTypeidExpr>(E)); + + // - a potentially evaluated call to a function, member function, function + // pointer, or member function pointer that does not have a non-throwing + // exception-specification + case Expr::CallExprClass: + case Expr::CXXMemberCallExprClass: + case Expr::CXXOperatorCallExprClass: + case Expr::UserDefinedLiteralClass: { + const CallExpr *CE = cast<CallExpr>(E); + CanThrowResult CT; + if (E->isTypeDependent()) + CT = CT_Dependent; + else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) + CT = CT_Cannot; + else + CT = canCalleeThrow(*this, E, CE->getCalleeDecl()); + if (CT == CT_Can) + return CT; + return mergeCanThrow(CT, canSubExprsThrow(*this, E)); + } + + case Expr::CXXConstructExprClass: + case Expr::CXXTemporaryObjectExprClass: { + CanThrowResult CT = canCalleeThrow(*this, E, + cast<CXXConstructExpr>(E)->getConstructor()); + if (CT == CT_Can) + return CT; + return mergeCanThrow(CT, canSubExprsThrow(*this, E)); + } + + case Expr::LambdaExprClass: { + const LambdaExpr *Lambda = cast<LambdaExpr>(E); + CanThrowResult CT = CT_Cannot; + for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(), + CapEnd = Lambda->capture_init_end(); + Cap != CapEnd; ++Cap) + CT = mergeCanThrow(CT, canThrow(*Cap)); + return CT; + } + + case Expr::CXXNewExprClass: { + CanThrowResult CT; + if (E->isTypeDependent()) + CT = CT_Dependent; + else + CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew()); + if (CT == CT_Can) + return CT; + return mergeCanThrow(CT, canSubExprsThrow(*this, E)); + } + + case Expr::CXXDeleteExprClass: { + CanThrowResult CT; + QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType(); + if (DTy.isNull() || DTy->isDependentType()) { + CT = CT_Dependent; + } else { + CT = canCalleeThrow(*this, E, + cast<CXXDeleteExpr>(E)->getOperatorDelete()); + if (const RecordType *RT = DTy->getAs<RecordType>()) { + const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); + CT = mergeCanThrow(CT, canCalleeThrow(*this, E, RD->getDestructor())); + } + if (CT == CT_Can) + return CT; + } + return mergeCanThrow(CT, canSubExprsThrow(*this, E)); + } + + case Expr::CXXBindTemporaryExprClass: { + // The bound temporary has to be destroyed again, which might throw. + CanThrowResult CT = canCalleeThrow(*this, E, + cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor()); + if (CT == CT_Can) + return CT; + return mergeCanThrow(CT, canSubExprsThrow(*this, E)); + } + + // ObjC message sends are like function calls, but never have exception + // specs. + case Expr::ObjCMessageExprClass: + case Expr::ObjCPropertyRefExprClass: + case Expr::ObjCSubscriptRefExprClass: + return CT_Can; + + // All the ObjC literals that are implemented as calls are + // potentially throwing unless we decide to close off that + // possibility. + case Expr::ObjCArrayLiteralClass: + case Expr::ObjCDictionaryLiteralClass: + case Expr::ObjCNumericLiteralClass: + return CT_Can; + + // Many other things have subexpressions, so we have to test those. + // Some are simple: + case Expr::ConditionalOperatorClass: + case Expr::CompoundLiteralExprClass: + case Expr::CXXConstCastExprClass: + case Expr::CXXDefaultArgExprClass: + case Expr::CXXReinterpretCastExprClass: + case Expr::DesignatedInitExprClass: + case Expr::ExprWithCleanupsClass: + case Expr::ExtVectorElementExprClass: + case Expr::InitListExprClass: + case Expr::MemberExprClass: + case Expr::ObjCIsaExprClass: + case Expr::ObjCIvarRefExprClass: + case Expr::ParenExprClass: + case Expr::ParenListExprClass: + case Expr::ShuffleVectorExprClass: + case Expr::VAArgExprClass: + return canSubExprsThrow(*this, E); + + // Some might be dependent for other reasons. + case Expr::ArraySubscriptExprClass: + case Expr::BinaryOperatorClass: + case Expr::CompoundAssignOperatorClass: + case Expr::CStyleCastExprClass: + case Expr::CXXStaticCastExprClass: + case Expr::CXXFunctionalCastExprClass: + case Expr::ImplicitCastExprClass: + case Expr::MaterializeTemporaryExprClass: + case Expr::UnaryOperatorClass: { + CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot; + return mergeCanThrow(CT, canSubExprsThrow(*this, E)); + } + + // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms. + case Expr::StmtExprClass: + return CT_Can; + + case Expr::ChooseExprClass: + if (E->isTypeDependent() || E->isValueDependent()) + return CT_Dependent; + return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr(Context)); + + case Expr::GenericSelectionExprClass: + if (cast<GenericSelectionExpr>(E)->isResultDependent()) + return CT_Dependent; + return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr()); + + // Some expressions are always dependent. + case Expr::CXXDependentScopeMemberExprClass: + case Expr::CXXUnresolvedConstructExprClass: + case Expr::DependentScopeDeclRefExprClass: + return CT_Dependent; + + case Expr::AsTypeExprClass: + case Expr::BinaryConditionalOperatorClass: + case Expr::BlockExprClass: + case Expr::CUDAKernelCallExprClass: + case Expr::DeclRefExprClass: + case Expr::ObjCBridgedCastExprClass: + case Expr::ObjCIndirectCopyRestoreExprClass: + case Expr::ObjCProtocolExprClass: + case Expr::ObjCSelectorExprClass: + case Expr::OffsetOfExprClass: + case Expr::PackExpansionExprClass: + case Expr::PseudoObjectExprClass: + case Expr::SubstNonTypeTemplateParmExprClass: + case Expr::SubstNonTypeTemplateParmPackExprClass: + case Expr::UnaryExprOrTypeTraitExprClass: + case Expr::UnresolvedLookupExprClass: + case Expr::UnresolvedMemberExprClass: + // FIXME: Can any of the above throw? If so, when? + return CT_Cannot; + + case Expr::AddrLabelExprClass: + case Expr::ArrayTypeTraitExprClass: + case Expr::AtomicExprClass: + case Expr::BinaryTypeTraitExprClass: + case Expr::TypeTraitExprClass: + case Expr::CXXBoolLiteralExprClass: + case Expr::CXXNoexceptExprClass: + case Expr::CXXNullPtrLiteralExprClass: + case Expr::CXXPseudoDestructorExprClass: + case Expr::CXXScalarValueInitExprClass: + case Expr::CXXThisExprClass: + case Expr::CXXUuidofExprClass: + case Expr::CharacterLiteralClass: + case Expr::ExpressionTraitExprClass: + case Expr::FloatingLiteralClass: + case Expr::GNUNullExprClass: + case Expr::ImaginaryLiteralClass: + case Expr::ImplicitValueInitExprClass: + case Expr::IntegerLiteralClass: + case Expr::ObjCEncodeExprClass: + case Expr::ObjCStringLiteralClass: + case Expr::ObjCBoolLiteralExprClass: + case Expr::OpaqueValueExprClass: + case Expr::PredefinedExprClass: + case Expr::SizeOfPackExprClass: + case Expr::StringLiteralClass: + case Expr::UnaryTypeTraitExprClass: + // These expressions can never throw. + return CT_Cannot; + +#define STMT(CLASS, PARENT) case Expr::CLASS##Class: +#define STMT_RANGE(Base, First, Last) +#define LAST_STMT_RANGE(BASE, FIRST, LAST) +#define EXPR(CLASS, PARENT) +#define ABSTRACT_STMT(STMT) +#include "clang/AST/StmtNodes.inc" + case Expr::NoStmtClass: + llvm_unreachable("Invalid class for expression"); + } + llvm_unreachable("Bogus StmtClass"); +} + } // end namespace clang diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp index 0d0f2f5..d2e0e6b 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp @@ -9438,10 +9438,11 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, PDiag(diag::err_expr_not_ice) << LangOpts.CPlusPlus); } -ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, - PartialDiagnostic NotIceDiag, - bool AllowFold, - PartialDiagnostic FoldDiag) { +ExprResult +Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, + const PartialDiagnostic &NotIceDiag, + bool AllowFold, + const PartialDiagnostic &FoldDiag) { SourceLocation DiagLoc = E->getLocStart(); if (getLangOpts().CPlusPlus0x) { @@ -9773,6 +9774,12 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { // FIXME: Is this really right? if (CurContext == Func) return; + // Instantiate the exception specification for any function which is + // used: CodeGen will need it. + const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>(); + if (FPT && FPT->getExceptionSpecType() == EST_Uninstantiated) + InstantiateExceptionSpec(Loc, Func); + // Implicit instantiation of function templates and member functions of // class templates. if (Func->isImplicitlyInstantiable()) { @@ -11268,22 +11275,6 @@ ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) && "Unknown Objective-C Boolean value!"); - QualType ObjCBoolLiteralQT = Context.ObjCBuiltinBoolTy; - // signed char is the default type for boolean literals. Use 'BOOL' - // instead, if BOOL typedef is visible in its scope instead. - Decl *TD = - LookupSingleName(TUScope, &Context.Idents.get("BOOL"), - SourceLocation(), LookupOrdinaryName); - if (TypedefDecl *BoolTD = dyn_cast_or_null<TypedefDecl>(TD)) { - QualType QT = BoolTD->getUnderlyingType(); - if (!QT->isIntegralOrUnscopedEnumerationType()) { - Diag(OpLoc, diag::warn_bool_for_boolean_literal) << QT; - Diag(BoolTD->getLocation(), diag::note_previous_declaration); - } - else - ObjCBoolLiteralQT = QT; - } - return Owned(new (Context) ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, - ObjCBoolLiteralQT, OpLoc)); + Context.ObjCBuiltinBoolTy, OpLoc)); } diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp index 31a8115..af86cb2 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp @@ -654,23 +654,44 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, QualType Sema::getCurrentThisType() { DeclContext *DC = getFunctionLevelDeclContext(); - QualType ThisTy; + QualType ThisTy = CXXThisTypeOverride; if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) { if (method && method->isInstance()) ThisTy = method->getThisType(Context); - } else if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) { - // C++0x [expr.prim]p4: - // Otherwise, if a member-declarator declares a non-static data member - // of a class X, the expression this is a prvalue of type "pointer to X" - // within the optional brace-or-equal-initializer. - Scope *S = getScopeForContext(DC); - if (!S || S->getFlags() & Scope::ThisScope) - ThisTy = Context.getPointerType(Context.getRecordType(RD)); } - + return ThisTy; } +Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S, + Decl *ContextDecl, + unsigned CXXThisTypeQuals, + bool Enabled) + : S(S), OldCXXThisTypeOverride(S.CXXThisTypeOverride), Enabled(false) +{ + if (!Enabled || !ContextDecl) + return; + + CXXRecordDecl *Record = 0; + if (ClassTemplateDecl *Template = dyn_cast<ClassTemplateDecl>(ContextDecl)) + Record = Template->getTemplatedDecl(); + else + Record = cast<CXXRecordDecl>(ContextDecl); + + S.CXXThisTypeOverride + = S.Context.getPointerType( + S.Context.getRecordType(Record).withCVRQualifiers(CXXThisTypeQuals)); + + this->Enabled = true; +} + + +Sema::CXXThisScopeRAII::~CXXThisScopeRAII() { + if (Enabled) { + S.CXXThisTypeOverride = OldCXXThisTypeOverride; + } +} + void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) { // We don't need to capture this in an unevaluated context. if (ExprEvalContexts.back().Context == Unevaluated && !Explicit) @@ -739,6 +760,18 @@ ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { return Owned(new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false)); } +bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) { + // If we're outside the body of a member function, then we'll have a specified + // type for 'this'. + if (CXXThisTypeOverride.isNull()) + return false; + + // Determine whether we're looking into a class that's currently being + // defined. + CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl(); + return Class && Class->isBeingDefined(); +} + ExprResult Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep, SourceLocation LParenLoc, @@ -3102,6 +3135,9 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, FoundAssign = true; const FunctionProtoType *CPT = Operator->getType()->getAs<FunctionProtoType>(); + CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); + if (!CPT) + return false; if (CPT->getExceptionSpecType() == EST_Delayed) return false; if (!CPT->isNothrow(Self.Context)) @@ -3141,6 +3177,9 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, FoundConstructor = true; const FunctionProtoType *CPT = Constructor->getType()->getAs<FunctionProtoType>(); + CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); + if (!CPT) + return false; if (CPT->getExceptionSpecType() == EST_Delayed) return false; // FIXME: check whether evaluating default arguments can throw. @@ -3176,6 +3215,9 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, if (Constructor->isDefaultConstructor()) { const FunctionProtoType *CPT = Constructor->getType()->getAs<FunctionProtoType>(); + CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); + if (!CPT) + return false; if (CPT->getExceptionSpecType() == EST_Delayed) return false; // TODO: check whether evaluating default arguments can throw. @@ -4784,8 +4826,13 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, return Owned(Base); } - // The object type must be complete (or dependent). + // The object type must be complete (or dependent), or + // C++11 [expr.prim.general]p3: + // Unlike the object expression in other contexts, *this is not required to + // be of complete type for purposes of class member access (5.2.5) outside + // the member function body. if (!BaseType->isDependentType() && + !isThisOutsideMemberFunctionBody(BaseType) && RequireCompleteType(OpLoc, BaseType, PDiag(diag::err_incomplete_member_access))) return ExprError(); @@ -5165,9 +5212,9 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, SourceLocation RParen) { + CanThrowResult CanThrow = canThrow(Operand); return Owned(new (Context) CXXNoexceptExpr(Context.BoolTy, Operand, - Operand->CanThrow(Context), - KeyLoc, RParen)); + CanThrow, KeyLoc, RParen)); } ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation, diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp index 26b88a2..6c84caa 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp @@ -101,16 +101,8 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, DeclContext *DC = SemaRef.getFunctionLevelDeclContext(); - bool isStaticContext = - (!isa<CXXMethodDecl>(DC) || - cast<CXXMethodDecl>(DC)->isStatic()); - - // C++0x [expr.prim]p4: - // Otherwise, if a member-declarator declares a non-static data member - // of a class X, the expression this is a prvalue of type "pointer to X" - // within the optional brace-or-equal-initializer. - if (CurScope->getFlags() & Scope::ThisScope) - isStaticContext = false; + bool isStaticContext = SemaRef.CXXThisTypeOverride.isNull() && + (!isa<CXXMethodDecl>(DC) || cast<CXXMethodDecl>(DC)->isStatic()); if (R.isUnresolvableResult()) return isStaticContext ? IMA_Unresolved_StaticContext : IMA_Unresolved; @@ -549,12 +541,13 @@ class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback { } static bool -LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, +LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, SourceRange BaseRange, const RecordType *RTy, SourceLocation OpLoc, CXXScopeSpec &SS, bool HasTemplateArgs) { RecordDecl *RDecl = RTy->getDecl(); - if (SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0), + if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) && + SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0), SemaRef.PDiag(diag::err_typecheck_incomplete_tag) << BaseRange)) return true; diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp index 966eb90..f003bdd 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp @@ -3165,7 +3165,7 @@ LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc, namespace { typedef llvm::StringMap<TypoCorrection, llvm::BumpPtrAllocator> TypoResultsMap; -typedef std::map<unsigned, TypoResultsMap *> TypoEditDistanceMap; +typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap; static const unsigned MaxTypoDistanceResultSets = 5; @@ -3187,14 +3187,6 @@ public: : Typo(Typo->getName()), SemaRef(SemaRef) { } - ~TypoCorrectionConsumer() { - for (TypoEditDistanceMap::iterator I = BestResults.begin(), - IEnd = BestResults.end(); - I != IEnd; - ++I) - delete I->second; - } - virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, bool InBaseClass); void FoundName(StringRef Name); @@ -3212,7 +3204,7 @@ public: bool empty() const { return BestResults.empty(); } TypoCorrection &operator[](StringRef Name) { - return (*BestResults.begin()->second)[Name]; + return BestResults.begin()->second[Name]; } unsigned getBestEditDistance(bool Normalized) { @@ -3276,11 +3268,9 @@ void TypoCorrectionConsumer::addName(StringRef Name, void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) { StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName(); - TypoResultsMap *& Map = BestResults[Correction.getEditDistance(false)]; - if (!Map) - Map = new TypoResultsMap; + TypoResultsMap &Map = BestResults[Correction.getEditDistance(false)]; - TypoCorrection &CurrentCorrection = (*Map)[Name]; + TypoCorrection &CurrentCorrection = Map[Name]; if (!CurrentCorrection || // FIXME: The following should be rolled up into an operator< on // TypoCorrection with a more principled definition. @@ -3289,12 +3279,8 @@ void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) { CurrentCorrection.getAsString(SemaRef.getLangOpts())) CurrentCorrection = Correction; - while (BestResults.size() > MaxTypoDistanceResultSets) { - TypoEditDistanceMap::iterator Last = BestResults.end(); - --Last; - delete Last->second; - BestResults.erase(Last); - } + while (BestResults.size() > MaxTypoDistanceResultSets) + erase(llvm::prior(BestResults.end())); } // Fill the supplied vector with the IdentifierInfo pointers for each piece of @@ -3882,8 +3868,8 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, while (!Consumer.empty()) { TypoCorrectionConsumer::distance_iterator DI = Consumer.begin(); unsigned ED = DI->first; - for (TypoCorrectionConsumer::result_iterator I = DI->second->begin(), - IEnd = DI->second->end(); + for (TypoCorrectionConsumer::result_iterator I = DI->second.begin(), + IEnd = DI->second.end(); I != IEnd; /* Increment in loop. */) { // If the item already has been looked up or is a keyword, keep it. // If a validator callback object was given, drop the correction @@ -3892,7 +3878,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, TypoCorrectionConsumer::result_iterator Prev = I; ++I; if (!isCandidateViable(CCC, Prev->second)) - DI->second->erase(Prev); + DI->second.erase(Prev); continue; } @@ -3911,7 +3897,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, { TypoCorrectionConsumer::result_iterator Next = I; ++Next; - DI->second->erase(I); + DI->second.erase(I); I = Next; } break; @@ -3929,7 +3915,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, I->second.addCorrectionDecl(*TRD); ++I; if (!isCandidateViable(CCC, Prev->second)) - DI->second->erase(Prev); + DI->second.erase(Prev); break; } @@ -3938,14 +3924,14 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, I->second.setCorrectionDecl(TmpRes.getAsSingle<NamedDecl>()); ++I; if (!isCandidateViable(CCC, Prev->second)) - DI->second->erase(Prev); + DI->second.erase(Prev); break; } } } - if (DI->second->empty()) + if (DI->second.empty()) Consumer.erase(DI); else if (!getLangOpts().CPlusPlus || QualifiedResults.empty() || !ED) // If there are results in the closest possible bucket, stop @@ -4009,7 +3995,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, // No corrections remain... if (Consumer.empty()) return TypoCorrection(); - TypoResultsMap &BestResults = *Consumer.begin()->second; + TypoResultsMap &BestResults = Consumer.begin()->second; ED = TypoCorrection::NormalizeEditDistance(Consumer.begin()->first); if (ED > 0 && Typo->getName().size() / ED < 3) { @@ -4083,7 +4069,8 @@ std::string TypoCorrection::getAsString(const LangOptions &LO) const { std::string tmpBuffer; llvm::raw_string_ostream PrefixOStream(tmpBuffer); CorrectionNameSpec->print(PrefixOStream, PrintingPolicy(LO)); - return PrefixOStream.str() + CorrectionName.getAsString(); + CorrectionName.printName(PrefixOStream); + return PrefixOStream.str(); } return CorrectionName.getAsString(); diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp index 284c8de..50230f0 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp @@ -11150,6 +11150,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, VK_LValue, Found.getDecl(), TemplateArgs); + MarkDeclRefReferenced(DRE); DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1); return DRE; } @@ -11178,6 +11179,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, VK_LValue, Found.getDecl(), TemplateArgs); + MarkDeclRefReferenced(DRE); DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1); return DRE; } else { diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp index d52c912..0e66329 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp @@ -214,6 +214,7 @@ namespace { ObjCMethodDecl *Setter; Selector SetterSelector; + Selector GetterSelector; public: ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) : @@ -475,8 +476,24 @@ bool ObjCPropertyOpBuilder::findGetter() { // For implicit properties, just trust the lookup we already did. if (RefExpr->isImplicitProperty()) { - Getter = RefExpr->getImplicitPropertyGetter(); - return (Getter != 0); + if ((Getter = RefExpr->getImplicitPropertyGetter())) { + GetterSelector = Getter->getSelector(); + return true; + } + else { + // Must build the getter selector the hard way. + ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter(); + assert(setter && "both setter and getter are null - cannot happen"); + IdentifierInfo *setterName = + setter->getSelector().getIdentifierInfoForSlot(0); + const char *compStr = setterName->getNameStart(); + compStr += 3; + IdentifierInfo *getterName = &S.Context.Idents.get(compStr); + GetterSelector = + S.PP.getSelectorTable().getNullarySelector(getterName); + return false; + + } } ObjCPropertyDecl *prop = RefExpr->getExplicitProperty(); @@ -776,7 +793,7 @@ ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, assert(RefExpr->isImplicitProperty()); S.Diag(opcLoc, diag::err_nogetter_property_incdec) << unsigned(UnaryOperator::isDecrementOp(opcode)) - << RefExpr->getImplicitPropertyGetter()->getSelector() // FIXME! + << GetterSelector << op->getSourceRange(); return ExprError(); } @@ -1300,6 +1317,11 @@ static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) { Expr *opaqueRef = E->IgnoreParens(); if (ObjCPropertyRefExpr *refExpr = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { + // Class and super property references don't have opaque values in them. + if (refExpr->isClassReceiver() || refExpr->isSuperReceiver()) + return E; + + assert(refExpr->isObjectReceiver() && "Unknown receiver kind?"); OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase()); return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E); } else if (ObjCSubscriptRefExpr *refExpr diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp index 97c8eb0..9052278 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp @@ -345,7 +345,6 @@ Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, StmtResult Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt) { - // If the label was multiply defined, reject it now. if (TheDecl->getStmt()) { Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName(); @@ -361,6 +360,16 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, return Owned(LS); } +StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc, + const AttrVec &Attrs, + Stmt *SubStmt) { + // Fill in the declaration and return it. Variable length will require to + // change this to AttributedStmt::Create(Context, ....); + // and probably using ArrayRef + AttributedStmt *LS = new (Context) AttributedStmt(AttrLoc, Attrs, SubStmt); + return Owned(LS); +} + StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar, Stmt *thenStmt, SourceLocation ElseLoc, diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp new file mode 100644 index 0000000..21c3297 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp @@ -0,0 +1,48 @@ +//===--- SemaStmtAttr.cpp - Statement Attribute Handling ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements stmt-related attribute processing. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaInternal.h" +#include "TargetAttributesSema.h" +#include "clang/AST/ASTContext.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Sema/DelayedDiagnostic.h" +#include "clang/Sema/Lookup.h" +#include "llvm/ADT/StringExtras.h" +using namespace clang; +using namespace sema; + + +static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A) { + switch (A.getKind()) { + default: + // if we're here, then we parsed an attribute, but didn't recognize it as a + // statement attribute => it is declaration attribute + S.Diag(A.getRange().getBegin(), diag::warn_attribute_invalid_on_stmt) << + A.getName()->getName(); + return 0; + } +} + +StmtResult Sema::ProcessStmtAttributes(Stmt *S, AttributeList *AttrList, + SourceRange Range) { + AttrVec Attrs; + for (const AttributeList* l = AttrList; l; l = l->getNext()) { + if (Attr *a = ProcessStmtAttribute(*this, S, *l)) + Attrs.push_back(a); + } + + if (Attrs.empty()) + return S; + + return ActOnAttributedStmt(Range.getBegin(), Attrs, S); +} diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp index ff8c4da..51ce2a1 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp @@ -2496,6 +2496,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef, Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); + Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext()); ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs, Param->getDefaultArgumentLoc(), Param->getDeclName()); @@ -2544,6 +2545,8 @@ SubstDefaultTemplateArgument(Sema &SemaRef, Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); + Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext()); + EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); return SemaRef.SubstExpr(Param->getDefaultArgument(), AllTemplateArgs); } @@ -2591,6 +2594,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef, Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); + Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext()); // Substitute into the nested-name-specifier first, QualifierLoc = Param->getDefaultArgument().getTemplateQualifierLoc(); if (QualifierLoc) { diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp index 2ea1e6f..d68e464 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2310,23 +2310,42 @@ Sema::SubstituteExplicitTemplateArguments( // explicitly-specified template arguments. If the function has a trailing // return type, substitute it after the arguments to ensure we substitute // in lexical order. - if (Proto->hasTrailingReturn() && - SubstParmTypes(Function->getLocation(), - Function->param_begin(), Function->getNumParams(), - MultiLevelTemplateArgumentList(*ExplicitArgumentList), - ParamTypes)) - return TDK_SubstitutionFailure; - + if (Proto->hasTrailingReturn()) { + if (SubstParmTypes(Function->getLocation(), + Function->param_begin(), Function->getNumParams(), + MultiLevelTemplateArgumentList(*ExplicitArgumentList), + ParamTypes)) + return TDK_SubstitutionFailure; + } + // Instantiate the return type. // FIXME: exception-specifications? - QualType ResultType - = SubstType(Proto->getResultType(), - MultiLevelTemplateArgumentList(*ExplicitArgumentList), - Function->getTypeSpecStartLoc(), - Function->getDeclName()); - if (ResultType.isNull() || Trap.hasErrorOccurred()) - return TDK_SubstitutionFailure; - + QualType ResultType; + { + // C++11 [expr.prim.general]p3: + // If a declaration declares a member function or member function + // template of a class X, the expression this is a prvalue of type + // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq + // and the end of the function-definition, member-declarator, or + // declarator. + unsigned ThisTypeQuals = 0; + CXXRecordDecl *ThisContext = 0; + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) { + ThisContext = Method->getParent(); + ThisTypeQuals = Method->getTypeQualifiers(); + } + + CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals, + getLangOpts().CPlusPlus0x); + + ResultType = SubstType(Proto->getResultType(), + MultiLevelTemplateArgumentList(*ExplicitArgumentList), + Function->getTypeSpecStartLoc(), + Function->getDeclName()); + if (ResultType.isNull() || Trap.hasErrorOccurred()) + return TDK_SubstitutionFailure; + } + // Instantiate the types of each of the function parameters given the // explicitly-specified template arguments if we didn't do so earlier. if (!Proto->hasTrailingReturn() && diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp index 4740145..128dc2f 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -153,6 +153,7 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D, bool Sema::ActiveTemplateInstantiation::isInstantiationRecord() const { switch (Kind) { case TemplateInstantiation: + case ExceptionSpecInstantiation: case DefaultTemplateArgumentInstantiation: case DefaultFunctionArgumentInstantiation: return true; @@ -190,6 +191,29 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, } } +Sema::InstantiatingTemplate:: +InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + FunctionDecl *Entity, ExceptionSpecification, + SourceRange InstantiationRange) + : SemaRef(SemaRef), + SavedInNonInstantiationSFINAEContext( + SemaRef.InNonInstantiationSFINAEContext) +{ + Invalid = CheckInstantiationDepth(PointOfInstantiation, + InstantiationRange); + if (!Invalid) { + ActiveTemplateInstantiation Inst; + Inst.Kind = ActiveTemplateInstantiation::ExceptionSpecInstantiation; + Inst.PointOfInstantiation = PointOfInstantiation; + Inst.Entity = reinterpret_cast<uintptr_t>(Entity); + Inst.TemplateArgs = 0; + Inst.NumTemplateArgs = 0; + Inst.InstantiationRange = InstantiationRange; + SemaRef.InNonInstantiationSFINAEContext = false; + SemaRef.ActiveTemplateInstantiations.push_back(Inst); + } +} + Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template, @@ -592,6 +616,13 @@ void Sema::PrintInstantiationStack() { << Active->InstantiationRange; break; } + + case ActiveTemplateInstantiation::ExceptionSpecInstantiation: + Diags.Report(Active->PointOfInstantiation, + diag::note_template_exception_spec_instantiation_here) + << cast<FunctionDecl>((Decl *)Active->Entity) + << Active->InstantiationRange; + break; } } } @@ -609,6 +640,7 @@ llvm::Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { switch(Active->Kind) { case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation: case ActiveTemplateInstantiation::TemplateInstantiation: + case ActiveTemplateInstantiation::ExceptionSpecInstantiation: // This is a template instantiation, so there is no SFINAE. return llvm::Optional<TemplateDeductionInfo *>(); @@ -789,6 +821,11 @@ namespace { QualType TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL); + QualType TransformFunctionProtoType(TypeLocBuilder &TLB, + FunctionProtoTypeLoc TL, + CXXRecordDecl *ThisContext, + unsigned ThisTypeQuals); + ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment, llvm::Optional<unsigned> NumExpansions, @@ -1211,6 +1248,16 @@ QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, return inherited::TransformFunctionProtoType(TLB, TL); } +QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, + FunctionProtoTypeLoc TL, + CXXRecordDecl *ThisContext, + unsigned ThisTypeQuals) { + // We need a local instantiation scope for this function prototype. + LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); + return inherited::TransformFunctionProtoType(TLB, TL, ThisContext, + ThisTypeQuals); +} + ParmVarDecl * TemplateInstantiator::TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment, @@ -1446,7 +1493,9 @@ static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) { TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &Args, SourceLocation Loc, - DeclarationName Entity) { + DeclarationName Entity, + CXXRecordDecl *ThisContext, + unsigned ThisTypeQuals) { assert(!ActiveTemplateInstantiations.empty() && "Cannot perform an instantiation without some context on the " "instantiation stack"); @@ -1461,7 +1510,14 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T, TypeLoc TL = T->getTypeLoc(); TLB.reserve(TL.getFullDataSize()); - QualType Result = Instantiator.TransformType(TLB, TL); + QualType Result; + + if (FunctionProtoTypeLoc *Proto = dyn_cast<FunctionProtoTypeLoc>(&TL)) { + Result = Instantiator.TransformFunctionProtoType(TLB, *Proto, ThisContext, + ThisTypeQuals); + } else { + Result = Instantiator.TransformType(TLB, TL); + } if (Result.isNull()) return 0; @@ -1878,24 +1934,33 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, CheckCompletedCXXClass(Instantiation); // Attach any in-class member initializers now the class is complete. - for (unsigned I = 0, N = FieldsWithMemberInitializers.size(); I != N; ++I) { - FieldDecl *OldField = FieldsWithMemberInitializers[I].first; - FieldDecl *NewField = FieldsWithMemberInitializers[I].second; - Expr *OldInit = OldField->getInClassInitializer(); - - ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs, - /*CXXDirectInit=*/false); - if (NewInit.isInvalid()) - NewField->setInvalidDecl(); - else { - Expr *Init = NewInit.take(); - assert(Init && "no-argument initializer in class"); - assert(!isa<ParenListExpr>(Init) && "call-style init in class"); - ActOnCXXInClassMemberInitializer(NewField, - Init->getSourceRange().getBegin(), Init); + { + // C++11 [expr.prim.general]p4: + // Otherwise, if a member-declarator declares a non-static data member + // (9.2) of a class X, the expression this is a prvalue of type "pointer + // to X" within the optional brace-or-equal-initializer. It shall not + // appear elsewhere in the member-declarator. + CXXThisScopeRAII ThisScope(*this, Instantiation, (unsigned)0); + + for (unsigned I = 0, N = FieldsWithMemberInitializers.size(); I != N; ++I) { + FieldDecl *OldField = FieldsWithMemberInitializers[I].first; + FieldDecl *NewField = FieldsWithMemberInitializers[I].second; + Expr *OldInit = OldField->getInClassInitializer(); + + ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs, + /*CXXDirectInit=*/false); + if (NewInit.isInvalid()) + NewField->setInvalidDecl(); + else { + Expr *Init = NewInit.take(); + assert(Init && "no-argument initializer in class"); + assert(!isa<ParenListExpr>(Init) && "call-style init in class"); + ActOnCXXInClassMemberInitializer(NewField, + Init->getSourceRange().getBegin(), + Init); + } } } - // Instantiate late parsed attributes, and attach them to their decls. // See Sema::InstantiateAttrs for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(), diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8afe7ac..c7bd99c 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2141,10 +2141,19 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, TypeSourceInfo *OldTInfo = D->getTypeSourceInfo(); assert(OldTInfo && "substituting function without type source info"); assert(Params.empty() && "parameter vector is non-empty at start"); + + CXXRecordDecl *ThisContext = 0; + unsigned ThisTypeQuals = 0; + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { + ThisContext = Method->getParent(); + ThisTypeQuals = Method->getTypeQualifiers(); + } + TypeSourceInfo *NewTInfo = SemaRef.SubstFunctionDeclType(OldTInfo, TemplateArgs, D->getTypeSpecStartLoc(), - D->getDeclName()); + D->getDeclName(), + ThisContext, ThisTypeQuals); if (!NewTInfo) return 0; @@ -2206,6 +2215,195 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, return NewTInfo; } +/// Introduce the instantiated function parameters into the local +/// instantiation scope, and set the parameter names to those used +/// in the template. +static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function, + const FunctionDecl *PatternDecl, + LocalInstantiationScope &Scope, + const MultiLevelTemplateArgumentList &TemplateArgs) { + unsigned FParamIdx = 0; + for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) { + const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I); + if (!PatternParam->isParameterPack()) { + // Simple case: not a parameter pack. + assert(FParamIdx < Function->getNumParams()); + ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); + FunctionParam->setDeclName(PatternParam->getDeclName()); + Scope.InstantiatedLocal(PatternParam, FunctionParam); + ++FParamIdx; + continue; + } + + // Expand the parameter pack. + Scope.MakeInstantiatedLocalArgPack(PatternParam); + unsigned NumArgumentsInExpansion + = S.getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs); + for (unsigned Arg = 0; Arg < NumArgumentsInExpansion; ++Arg) { + ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); + FunctionParam->setDeclName(PatternParam->getDeclName()); + Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam); + ++FParamIdx; + } + } +} + +static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, + const FunctionProtoType *Proto, + const MultiLevelTemplateArgumentList &TemplateArgs) { + assert(Proto->getExceptionSpecType() != EST_Uninstantiated); + + // C++11 [expr.prim.general]p3: + // If a declaration declares a member function or member function + // template of a class X, the expression this is a prvalue of type + // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq + // and the end of the function-definition, member-declarator, or + // declarator. + CXXRecordDecl *ThisContext = 0; + unsigned ThisTypeQuals = 0; + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(New)) { + ThisContext = Method->getParent(); + ThisTypeQuals = Method->getTypeQualifiers(); + } + Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals, + SemaRef.getLangOpts().CPlusPlus0x); + + // The function has an exception specification or a "noreturn" + // attribute. Substitute into each of the exception types. + SmallVector<QualType, 4> Exceptions; + for (unsigned I = 0, N = Proto->getNumExceptions(); I != N; ++I) { + // FIXME: Poor location information! + if (const PackExpansionType *PackExpansion + = Proto->getExceptionType(I)->getAs<PackExpansionType>()) { + // We have a pack expansion. Instantiate it. + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), + Unexpanded); + assert(!Unexpanded.empty() && + "Pack expansion without parameter packs?"); + + bool Expand = false; + bool RetainExpansion = false; + llvm::Optional<unsigned> NumExpansions + = PackExpansion->getNumExpansions(); + if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(), + SourceRange(), + Unexpanded, + TemplateArgs, + Expand, + RetainExpansion, + NumExpansions)) + break; + + if (!Expand) { + // We can't expand this pack expansion into separate arguments yet; + // just substitute into the pattern and create a new pack expansion + // type. + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); + QualType T = SemaRef.SubstType(PackExpansion->getPattern(), + TemplateArgs, + New->getLocation(), New->getDeclName()); + if (T.isNull()) + break; + + T = SemaRef.Context.getPackExpansionType(T, NumExpansions); + Exceptions.push_back(T); + continue; + } + + // Substitute into the pack expansion pattern for each template + bool Invalid = false; + for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx); + + QualType T = SemaRef.SubstType(PackExpansion->getPattern(), + TemplateArgs, + New->getLocation(), New->getDeclName()); + if (T.isNull()) { + Invalid = true; + break; + } + + Exceptions.push_back(T); + } + + if (Invalid) + break; + + continue; + } + + QualType T + = SemaRef.SubstType(Proto->getExceptionType(I), TemplateArgs, + New->getLocation(), New->getDeclName()); + if (T.isNull() || + SemaRef.CheckSpecifiedExceptionType(T, New->getLocation())) + continue; + + Exceptions.push_back(T); + } + Expr *NoexceptExpr = 0; + if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr()) { + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); + ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs); + if (E.isUsable()) + E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart()); + + if (E.isUsable()) { + NoexceptExpr = E.take(); + if (!NoexceptExpr->isTypeDependent() && + !NoexceptExpr->isValueDependent()) + NoexceptExpr = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr, + 0, SemaRef.PDiag(diag::err_noexcept_needs_constant_expression), + /*AllowFold*/ false).take(); + } + } + + // Rebuild the function type + const FunctionProtoType *NewProto + = New->getType()->getAs<FunctionProtoType>(); + assert(NewProto && "Template instantiation without function prototype?"); + + FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); + EPI.ExceptionSpecType = Proto->getExceptionSpecType(); + EPI.NumExceptions = Exceptions.size(); + EPI.Exceptions = Exceptions.data(); + EPI.NoexceptExpr = NoexceptExpr; + + New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), + NewProto->arg_type_begin(), + NewProto->getNumArgs(), + EPI)); +} + +void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, + FunctionDecl *Decl) { + const FunctionProtoType *Proto = Decl->getType()->castAs<FunctionProtoType>(); + if (Proto->getExceptionSpecType() != EST_Uninstantiated) + return; + + InstantiatingTemplate Inst(*this, PointOfInstantiation, Decl, + InstantiatingTemplate::ExceptionSpecification()); + if (Inst) + return; + + // Enter the scope of this instantiation. We don't use + // PushDeclContext because we don't have a scope. + Sema::ContextRAII savedContext(*this, Decl); + LocalInstantiationScope Scope(*this); + + MultiLevelTemplateArgumentList TemplateArgs = + getTemplateInstantiationArgs(Decl, 0, /*RelativeToPrimary*/true); + + FunctionDecl *Template = Proto->getExceptionSpecTemplate(); + addInstantiatedParametersToScope(*this, Decl, Template, Scope, TemplateArgs); + + ::InstantiateExceptionSpec(*this, Decl, + Template->getType()->castAs<FunctionProtoType>(), + TemplateArgs); +} + /// \brief Initializes the common fields of an instantiation function /// declaration (New) from the corresponding fields of its template (Tmpl). /// @@ -2243,119 +2441,37 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, assert(Proto && "Function template without prototype?"); if (Proto->hasExceptionSpec() || Proto->getNoReturnAttr()) { - // The function has an exception specification or a "noreturn" - // attribute. Substitute into each of the exception types. - SmallVector<QualType, 4> Exceptions; - for (unsigned I = 0, N = Proto->getNumExceptions(); I != N; ++I) { - // FIXME: Poor location information! - if (const PackExpansionType *PackExpansion - = Proto->getExceptionType(I)->getAs<PackExpansionType>()) { - // We have a pack expansion. Instantiate it. - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), - Unexpanded); - assert(!Unexpanded.empty() && - "Pack expansion without parameter packs?"); - - bool Expand = false; - bool RetainExpansion = false; - llvm::Optional<unsigned> NumExpansions - = PackExpansion->getNumExpansions(); - if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(), - SourceRange(), - Unexpanded, - TemplateArgs, - Expand, - RetainExpansion, - NumExpansions)) - break; - - if (!Expand) { - // We can't expand this pack expansion into separate arguments yet; - // just substitute into the pattern and create a new pack expansion - // type. - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); - QualType T = SemaRef.SubstType(PackExpansion->getPattern(), - TemplateArgs, - New->getLocation(), New->getDeclName()); - if (T.isNull()) - break; - - T = SemaRef.Context.getPackExpansionType(T, NumExpansions); - Exceptions.push_back(T); - continue; - } - - // Substitute into the pack expansion pattern for each template - bool Invalid = false; - for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx); - - QualType T = SemaRef.SubstType(PackExpansion->getPattern(), - TemplateArgs, - New->getLocation(), New->getDeclName()); - if (T.isNull()) { - Invalid = true; - break; - } - - Exceptions.push_back(T); - } - - if (Invalid) - break; - - continue; - } - - QualType T - = SemaRef.SubstType(Proto->getExceptionType(I), TemplateArgs, - New->getLocation(), New->getDeclName()); - if (T.isNull() || - SemaRef.CheckSpecifiedExceptionType(T, New->getLocation())) - continue; - - Exceptions.push_back(T); - } - Expr *NoexceptExpr = 0; - if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr()) { - EnterExpressionEvaluationContext Unevaluated(SemaRef, - Sema::ConstantEvaluated); - ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs); - if (E.isUsable()) - E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart()); - - if (E.isUsable()) { - NoexceptExpr = E.take(); - if (!NoexceptExpr->isTypeDependent() && - !NoexceptExpr->isValueDependent()) - NoexceptExpr = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr, - 0, SemaRef.PDiag(diag::err_noexcept_needs_constant_expression), - /*AllowFold*/ false).take(); - } - } - - // Rebuild the function type - FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); - EPI.ExceptionSpecType = Proto->getExceptionSpecType(); - EPI.NumExceptions = Exceptions.size(); - EPI.Exceptions = Exceptions.data(); - EPI.NoexceptExpr = NoexceptExpr; - EPI.ExtInfo = Proto->getExtInfo(); - const FunctionProtoType *NewProto - = New->getType()->getAs<FunctionProtoType>(); - assert(NewProto && "Template instantiation without function prototype?"); - New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), - NewProto->arg_type_begin(), - NewProto->getNumArgs(), - EPI)); + // DR1330: In C++11, defer instantiation of a non-trivial + // exception specification. + if (SemaRef.getLangOpts().CPlusPlus0x && + EPI.ExceptionSpecType != EST_None && + EPI.ExceptionSpecType != EST_DynamicNone && + EPI.ExceptionSpecType != EST_BasicNoexcept) { + FunctionDecl *ExceptionSpecTemplate = Tmpl; + if (EPI.ExceptionSpecType == EST_Uninstantiated) + ExceptionSpecTemplate = EPI.ExceptionSpecTemplate; + + // Mark the function has having an uninstantiated exception specification. + const FunctionProtoType *NewProto + = New->getType()->getAs<FunctionProtoType>(); + assert(NewProto && "Template instantiation without function prototype?"); + EPI = NewProto->getExtProtoInfo(); + EPI.ExceptionSpecType = EST_Uninstantiated; + EPI.ExceptionSpecDecl = New; + EPI.ExceptionSpecTemplate = ExceptionSpecTemplate; + New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), + NewProto->arg_type_begin(), + NewProto->getNumArgs(), + EPI)); + } else { + ::InstantiateExceptionSpec(SemaRef, New, Proto, TemplateArgs); + } } - const FunctionDecl* Definition = Tmpl; - // Get the definition. Leaves the variable unchanged if undefined. + const FunctionDecl *Definition = Tmpl; Tmpl->isDefined(Definition); SemaRef.InstantiateAttrs(TemplateArgs, Definition, New, @@ -2513,33 +2629,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(Function, 0, false, PatternDecl); - // Introduce the instantiated function parameters into the local - // instantiation scope, and set the parameter names to those used - // in the template. - unsigned FParamIdx = 0; - for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) { - const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I); - if (!PatternParam->isParameterPack()) { - // Simple case: not a parameter pack. - assert(FParamIdx < Function->getNumParams()); - ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); - FunctionParam->setDeclName(PatternParam->getDeclName()); - Scope.InstantiatedLocal(PatternParam, FunctionParam); - ++FParamIdx; - continue; - } - - // Expand the parameter pack. - Scope.MakeInstantiatedLocalArgPack(PatternParam); - unsigned NumArgumentsInExpansion - = getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs); - for (unsigned Arg = 0; Arg < NumArgumentsInExpansion; ++Arg) { - ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); - FunctionParam->setDeclName(PatternParam->getDeclName()); - Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam); - ++FParamIdx; - } - } + addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope, + TemplateArgs); if (PatternDecl->isDefaulted()) { ActOnFinishFunctionBody(Function, 0, /*IsInstantiation=*/true); diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp index c41df82..d0906de 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp @@ -561,7 +561,7 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state, /*const qualifier*/SourceLocation(), /*volatile qualifier*/SourceLocation(), /*mutable qualifier*/SourceLocation(), - /*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0, + /*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0, 0, /*parens*/ loc, loc, declarator)); @@ -2371,34 +2371,33 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, EPI.ConsumedArguments = ConsumedArguments.data(); SmallVector<QualType, 4> Exceptions; - EPI.ExceptionSpecType = FTI.getExceptionSpecType(); + SmallVector<ParsedType, 2> DynamicExceptions; + SmallVector<SourceRange, 2> DynamicExceptionRanges; + Expr *NoexceptExpr = 0; + if (FTI.getExceptionSpecType() == EST_Dynamic) { - Exceptions.reserve(FTI.NumExceptions); - for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) { - // FIXME: Preserve type source info. - QualType ET = S.GetTypeFromParser(FTI.Exceptions[ei].Ty); - // Check that the type is valid for an exception spec, and - // drop it if not. - if (!S.CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range)) - Exceptions.push_back(ET); + // FIXME: It's rather inefficient to have to split into two vectors + // here. + unsigned N = FTI.NumExceptions; + DynamicExceptions.reserve(N); + DynamicExceptionRanges.reserve(N); + for (unsigned I = 0; I != N; ++I) { + DynamicExceptions.push_back(FTI.Exceptions[I].Ty); + DynamicExceptionRanges.push_back(FTI.Exceptions[I].Range); } - EPI.NumExceptions = Exceptions.size(); - EPI.Exceptions = Exceptions.data(); } else if (FTI.getExceptionSpecType() == EST_ComputedNoexcept) { - // If an error occurred, there's no expression here. - if (Expr *NoexceptExpr = FTI.NoexceptExpr) { - assert((NoexceptExpr->isTypeDependent() || - NoexceptExpr->getType()->getCanonicalTypeUnqualified() == - Context.BoolTy) && - "Parser should have made sure that the expression is boolean"); - if (!NoexceptExpr->isValueDependent()) - NoexceptExpr = S.VerifyIntegerConstantExpression(NoexceptExpr, 0, - S.PDiag(diag::err_noexcept_needs_constant_expression), - /*AllowFold*/ false).take(); - EPI.NoexceptExpr = NoexceptExpr; - } - } else if (FTI.getExceptionSpecType() == EST_None && - ImplicitlyNoexcept && chunkIndex == 0) { + NoexceptExpr = FTI.NoexceptExpr; + } + + S.checkExceptionSpecification(FTI.getExceptionSpecType(), + DynamicExceptions, + DynamicExceptionRanges, + NoexceptExpr, + Exceptions, + EPI); + + if (FTI.getExceptionSpecType() == EST_None && + ImplicitlyNoexcept && chunkIndex == 0) { // Only the outermost chunk is marked noexcept, of course. EPI.ExceptionSpecType = EST_BasicNoexcept; } diff --git a/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h b/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h index fdb861e..a66378e 100644 --- a/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h +++ b/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h @@ -522,6 +522,11 @@ public: QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T); #include "clang/AST/TypeLocNodes.def" + QualType TransformFunctionProtoType(TypeLocBuilder &TLB, + FunctionProtoTypeLoc TL, + CXXRecordDecl *ThisContext, + unsigned ThisTypeQuals); + StmtResult TransformSEHHandler(Stmt *Handler); @@ -1044,6 +1049,15 @@ public: return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt); } + /// \brief Build a new label statement. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, const AttrVec &Attrs, + Stmt *SubStmt) { + return SemaRef.ActOnAttributedStmt(AttrLoc, Attrs, SubStmt); + } + /// \brief Build a new "if" statement. /// /// By default, performs semantic analysis to build the new statement. @@ -4156,12 +4170,18 @@ template<typename Derived> QualType TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL) { + return getDerived().TransformFunctionProtoType(TLB, TL, 0, 0); +} + +template<typename Derived> +QualType +TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, + FunctionProtoTypeLoc TL, + CXXRecordDecl *ThisContext, + unsigned ThisTypeQuals) { // Transform the parameters and return type. // - // We instantiate in source order, with the return type first followed by - // the parameters, because users tend to expect this (even if they shouldn't - // rely on it!). - // + // We are required to instantiate the params and return type in source order. // When the function has a trailing return type, we instantiate the // parameters before the return type, since the return type can then refer // to the parameters themselves (via decltype, sizeof, etc.). @@ -4180,9 +4200,19 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, ParamTypes, &ParamDecls)) return QualType(); - ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); - if (ResultType.isNull()) - return QualType(); + { + // C++11 [expr.prim.general]p3: + // If a declaration declares a member function or member function + // template of a class X, the expression this is a prvalue of type + // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq + // and the end of the function-definition, member-declarator, or + // declarator. + Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals); + + ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); + if (ResultType.isNull()) + return QualType(); + } } else { ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); @@ -4197,6 +4227,8 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, return QualType(); } + // FIXME: Need to transform the exception-specification too. + QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || ResultType != T->getResultType() || @@ -5154,8 +5186,8 @@ TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) { S->getDecl()); if (!LD) return StmtError(); - - + + // FIXME: Pass the real colon location in. return getDerived().RebuildLabelStmt(S->getIdentLoc(), cast<LabelDecl>(LD), SourceLocation(), @@ -5164,6 +5196,22 @@ TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) { template<typename Derived> StmtResult +TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S) { + StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); + if (SubStmt.isInvalid()) + return StmtError(); + + // TODO: transform attributes + if (SubStmt.get() == S->getSubStmt() /* && attrs are the same */) + return S; + + return getDerived().RebuildAttributedStmt(S->getAttrLoc(), + S->getAttrs(), + SubStmt.get()); +} + +template<typename Derived> +StmtResult TreeTransform<Derived>::TransformIfStmt(IfStmt *S) { // Transform the condition ExprResult Cond; diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp index f91b66c..06b42f3 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp @@ -27,7 +27,6 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLocVisitor.h" -#include "llvm/Support/SaveAndRestore.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Lex/Preprocessor.h" @@ -46,6 +45,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/system_error.h" #include <algorithm> #include <iterator> @@ -664,46 +664,6 @@ ASTDeclContextNameLookupTrait::GetInternalKey( return Key; } -ASTDeclContextNameLookupTrait::external_key_type -ASTDeclContextNameLookupTrait::GetExternalKey( - const internal_key_type& Key) const { - ASTContext &Context = Reader.getContext(); - switch (Key.Kind) { - case DeclarationName::Identifier: - return DeclarationName((IdentifierInfo*)Key.Data); - - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - return DeclarationName(Selector(Key.Data)); - - case DeclarationName::CXXConstructorName: - return Context.DeclarationNames.getCXXConstructorName( - Context.getCanonicalType(Reader.getLocalType(F, Key.Data))); - - case DeclarationName::CXXDestructorName: - return Context.DeclarationNames.getCXXDestructorName( - Context.getCanonicalType(Reader.getLocalType(F, Key.Data))); - - case DeclarationName::CXXConversionFunctionName: - return Context.DeclarationNames.getCXXConversionFunctionName( - Context.getCanonicalType(Reader.getLocalType(F, Key.Data))); - - case DeclarationName::CXXOperatorName: - return Context.DeclarationNames.getCXXOperatorName( - (OverloadedOperatorKind)Key.Data); - - case DeclarationName::CXXLiteralOperatorName: - return Context.DeclarationNames.getCXXLiteralOperatorName( - (IdentifierInfo*)Key.Data); - - case DeclarationName::CXXUsingDirective: - return DeclarationName::getUsingDirectiveName(); - } - - llvm_unreachable("Invalid Name Kind ?"); -} - std::pair<unsigned, unsigned> ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) { using namespace clang::io; @@ -749,7 +709,7 @@ ASTDeclContextNameLookupTrait::ReadKey(const unsigned char* d, unsigned) { ASTDeclContextNameLookupTrait::data_type ASTDeclContextNameLookupTrait::ReadData(internal_key_type, const unsigned char* d, - unsigned DataLen) { + unsigned DataLen) { using namespace clang::io; unsigned NumDecls = ReadUnalignedLE16(d); LE32DeclID *Start = (LE32DeclID *)d; @@ -1911,7 +1871,8 @@ ASTReader::ReadASTBlock(ModuleFile &F) { case UPDATE_VISIBLE: { unsigned Idx = 0; serialization::DeclID ID = ReadDeclID(F, Record, Idx); - void *Table = ASTDeclContextNameLookupTable::Create( + ASTDeclContextNameLookupTable *Table = + ASTDeclContextNameLookupTable::Create( (const unsigned char *)BlobStart + Record[Idx++], (const unsigned char *)BlobStart, ASTDeclContextNameLookupTrait(*this, F)); @@ -4908,7 +4869,7 @@ namespace { // Look for this name within this module. ASTDeclContextNameLookupTable *LookupTable = - (ASTDeclContextNameLookupTable*)Info->second.NameLookupTableData; + Info->second.NameLookupTableData; ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(This->Name); if (Pos == LookupTable->end()) @@ -4972,48 +4933,95 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, } namespace { - /// \brief ModuleFile visitor used to complete the visible decls map of a + /// \brief ModuleFile visitor used to retrieve all visible names in a /// declaration context. - class DeclContextVisibleDeclMapVisitor { + class DeclContextAllNamesVisitor { ASTReader &Reader; - DeclContext *DC; + llvm::SmallVectorImpl<const DeclContext *> &Contexts; + const DeclContext *DC; + llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > &Decls; public: - DeclContextVisibleDeclMapVisitor(ASTReader &Reader, DeclContext *DC) - : Reader(Reader), DC(DC) { } + DeclContextAllNamesVisitor(ASTReader &Reader, + SmallVectorImpl<const DeclContext *> &Contexts, + llvm::DenseMap<DeclarationName, + SmallVector<NamedDecl *, 8> > &Decls) + : Reader(Reader), Contexts(Contexts), Decls(Decls) { } static bool visit(ModuleFile &M, void *UserData) { - return static_cast<DeclContextVisibleDeclMapVisitor*>(UserData)->visit(M); - } + DeclContextAllNamesVisitor *This + = static_cast<DeclContextAllNamesVisitor *>(UserData); - bool visit(ModuleFile &M) { // Check whether we have any visible declaration information for // this context in this module. - ModuleFile::DeclContextInfosMap::iterator - Info = M.DeclContextInfos.find(DC); - if (Info == M.DeclContextInfos.end() || - !Info->second.NameLookupTableData) + ModuleFile::DeclContextInfosMap::iterator Info; + bool FoundInfo = false; + for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) { + Info = M.DeclContextInfos.find(This->Contexts[I]); + if (Info != M.DeclContextInfos.end() && + Info->second.NameLookupTableData) { + FoundInfo = true; + break; + } + } + + if (!FoundInfo) return false; - - // Look for this name within this module. + ASTDeclContextNameLookupTable *LookupTable = - (ASTDeclContextNameLookupTable*)Info->second.NameLookupTableData; - for (ASTDeclContextNameLookupTable::key_iterator - I = LookupTable->key_begin(), - E = LookupTable->key_end(); I != E; ++I) { - DC->lookup(*I); // Force loading of the visible decls for the decl name. + Info->second.NameLookupTableData; + bool FoundAnything = false; + for (ASTDeclContextNameLookupTable::data_iterator + I = LookupTable->data_begin(), E = LookupTable->data_end(); + I != E; ++I) { + ASTDeclContextNameLookupTrait::data_type Data = *I; + for (; Data.first != Data.second; ++Data.first) { + NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M, + *Data.first); + if (!ND) + continue; + + // Record this declaration. + FoundAnything = true; + This->Decls[ND->getDeclName()].push_back(ND); + } } - return false; + return FoundAnything; } }; } -void ASTReader::completeVisibleDeclsMap(DeclContext *DC) { +void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) { if (!DC->hasExternalVisibleStorage()) return; - DeclContextVisibleDeclMapVisitor Visitor(*this, DC); - ModuleMgr.visit(&DeclContextVisibleDeclMapVisitor::visit, &Visitor); + llvm::DenseMap<DeclarationName, llvm::SmallVector<NamedDecl*, 8> > Decls; + + // Compute the declaration contexts we need to look into. Multiple such + // declaration contexts occur when two declaration contexts from disjoint + // modules get merged, e.g., when two namespaces with the same name are + // independently defined in separate modules. + SmallVector<const DeclContext *, 2> Contexts; + Contexts.push_back(DC); + + if (DC->isNamespace()) { + MergedDeclsMap::iterator Merged + = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC))); + if (Merged != MergedDecls.end()) { + for (unsigned I = 0, N = Merged->second.size(); I != N; ++I) + Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I]))); + } + } + + DeclContextAllNamesVisitor Visitor(*this, Contexts, Decls); + ModuleMgr.visit(&DeclContextAllNamesVisitor::visit, &Visitor); + ++NumVisibleDeclContextsRead; + + for (llvm::DenseMap<DeclarationName, + llvm::SmallVector<NamedDecl*, 8> >::iterator + I = Decls.begin(), E = Decls.end(); I != E; ++I) { + SetExternalVisibleDeclsForName(DC, I->first, I->second); + } } /// \brief Under non-PCH compilation the consumer receives the objc methods @@ -6364,6 +6372,6 @@ ASTReader::~ASTReader() { for (DeclContextVisibleUpdates::iterator J = I->second.begin(), F = I->second.end(); J != F; ++J) - delete static_cast<ASTDeclContextNameLookupTable*>(J->first); + delete J->first; } } diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp index 5db5f92..8dd53ee 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "ASTCommon.h" +#include "ASTReaderInternals.h" #include "clang/Serialization/ASTReader.h" #include "clang/Sema/IdentifierResolver.h" #include "clang/Sema/Sema.h" @@ -955,6 +956,10 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx)); BD->setParams(Params); + BD->setIsVariadic(Record[Idx++]); + BD->setBlockMissingReturnType(Record[Idx++]); + BD->setIsConversionFromLambda(Record[Idx++]); + bool capturesCXXThis = Record[Idx++]; unsigned numCaptures = Record[Idx++]; SmallVector<BlockDecl::Capture, 16> captures; @@ -2100,7 +2105,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { DeclContextVisibleUpdates &U = I->second; for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end(); UI != UE; ++UI) { - UI->second->DeclContextInfos[DC].NameLookupTableData = UI->first; + DeclContextInfo &Info = UI->second->DeclContextInfos[DC]; + delete Info.NameLookupTableData; + Info.NameLookupTableData = UI->first; } PendingVisibleUpdates.erase(I); } diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h index 3a1dfcf..e5159e9 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h @@ -57,8 +57,7 @@ public: typedef DeclarationName external_key_type; typedef DeclNameKey internal_key_type; - explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, - ModuleFile &F) + explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F) : Reader(Reader), F(F) { } static bool EqualKey(const internal_key_type& a, @@ -68,9 +67,8 @@ public: unsigned ComputeHash(const DeclNameKey &Key) const; internal_key_type GetInternalKey(const external_key_type& Name) const; - external_key_type GetExternalKey(const internal_key_type& Key) const; - static std::pair<unsigned, unsigned> + static std::pair<unsigned, unsigned> ReadKeyDataLength(const unsigned char*& d); internal_key_type ReadKey(const unsigned char* d, unsigned); @@ -79,10 +77,6 @@ public: unsigned DataLen); }; -/// \brief The on-disk hash table used for the DeclContext's Name lookup table. -typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait> - ASTDeclContextNameLookupTable; - /// \brief Class that performs lookup for an identifier stored in an AST file. class ASTIdentifierLookupTrait { ASTReader &Reader; diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp index 2eeb090..007ecee 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp @@ -159,9 +159,18 @@ void ASTStmtReader::VisitLabelStmt(LabelStmt *S) { S->setIdentLoc(ReadSourceLocation(Record, Idx)); } +void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) { + VisitStmt(S); + AttrVec Attrs; + Reader.ReadAttributes(F, Attrs, Record, Idx); + S->Attrs = Attrs; + S->SubStmt = Reader.ReadSubStmt(); + S->AttrLoc = ReadSourceLocation(Record, Idx); +} + void ASTStmtReader::VisitIfStmt(IfStmt *S) { VisitStmt(S); - S->setConditionVariable(Reader.getContext(), + S->setConditionVariable(Reader.getContext(), ReadDeclAs<VarDecl>(Record, Idx)); S->setCond(Reader.ReadSubExpr()); S->setThen(Reader.ReadSubStmt()); @@ -1630,6 +1639,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) LabelStmt(Empty); break; + case STMT_ATTRIBUTED: + S = new (Context) AttributedStmt(Empty); + break; + case STMT_IF: S = new (Context) IfStmt(Empty); break; diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp index a4301b5..81c0a9d 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp @@ -651,6 +651,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(STMT_CASE); RECORD(STMT_DEFAULT); RECORD(STMT_LABEL); + RECORD(STMT_ATTRIBUTED); RECORD(STMT_IF); RECORD(STMT_SWITCH); RECORD(STMT_WHILE); diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp index 7a4ef63..1ee3ac4 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp @@ -775,6 +775,9 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) { for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end(); P != PEnd; ++P) Writer.AddDeclRef(*P, Record); + Record.push_back(D->isVariadic()); + Record.push_back(D->blockMissingReturnType()); + Record.push_back(D->isConversionFromLambda()); Record.push_back(D->capturesCXXThis()); Record.push_back(D->getNumCaptures()); for (BlockDecl::capture_iterator diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp index 827caa0..1e31211 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp @@ -106,6 +106,14 @@ void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) { Code = serialization::STMT_LABEL; } +void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) { + VisitStmt(S); + Writer.WriteAttributes(S->getAttrs(), Record); + Writer.AddStmt(S->getSubStmt()); + Writer.AddSourceLocation(S->getAttrLoc(), Record); + Code = serialization::STMT_ATTRIBUTED; +} + void ASTStmtWriter::VisitIfStmt(IfStmt *S) { VisitStmt(S); Writer.AddDeclRef(S->getConditionVariable(), Record); diff --git a/contrib/llvm/tools/clang/lib/Serialization/Module.cpp b/contrib/llvm/tools/clang/lib/Serialization/Module.cpp index 16b95e2..ff241d3 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/Module.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/Module.cpp @@ -45,8 +45,7 @@ ModuleFile::~ModuleFile() { E = DeclContextInfos.end(); I != E; ++I) { if (I->second.NameLookupTableData) - delete static_cast<ASTDeclContextNameLookupTable*>( - I->second.NameLookupTableData); + delete I->second.NameLookupTableData; } delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable); diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp index d15c8ba..97b58cf 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp @@ -183,9 +183,6 @@ static void checkForInvalidSelf(const Expr *E, CheckerContext &C, void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg, CheckerContext &C) const { - CallOrObjCMessage MsgWrapper(msg, C.getState(), C.getLocationContext()); - checkPostStmt(MsgWrapper, C); - // When encountering a message that does initialization (init rule), // tag the return value so that we know later on that if self has this value // then it is properly initialized. @@ -209,6 +206,9 @@ void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg, return; } + CallOrObjCMessage MsgWrapper(msg, C.getState(), C.getLocationContext()); + checkPostStmt(MsgWrapper, C); + // We don't check for an invalid 'self' in an obj-c message expression to cut // down false positives where logging functions get information from self // (like its class) or doing "invalidation" on self when the initialization @@ -277,6 +277,11 @@ void ObjCSelfInitChecker::checkPreStmt(const CallOrObjCMessage &CE, CheckerContext &C) const { ProgramStateRef state = C.getState(); unsigned NumArgs = CE.getNumArgs(); + // If we passed 'self' as and argument to the call, record it in the state + // to be propagated after the call. + // Note, we could have just given up, but try to be more optimistic here and + // assume that the functions are going to continue initialization or will not + // modify self. for (unsigned i = 0; i < NumArgs; ++i) { SVal argV = CE.getArgSVal(i); if (isSelfVar(argV, C)) { @@ -298,14 +303,24 @@ void ObjCSelfInitChecker::checkPostStmt(const CallOrObjCMessage &CE, for (unsigned i = 0; i < NumArgs; ++i) { SVal argV = CE.getArgSVal(i); if (isSelfVar(argV, C)) { + // If the address of 'self' is being passed to the call, assume that the + // 'self' after the call will have the same flags. + // EX: log(&self) SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>(); state = state->remove<PreCallSelfFlags>(); addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C); return; } else if (hasSelfFlag(argV, SelfFlag_Self, C)) { + // If 'self' is passed to the call by value, assume that the function + // returns 'self'. So assign the flags, which were set on 'self' to the + // return value. + // EX: self = performMoreInitialization(self) SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>(); state = state->remove<PreCallSelfFlags>(); - addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C); + const Expr *CallExpr = CE.getOriginExpr(); + if (CallExpr) + addSelfFlag(state, state->getSVal(CallExpr, C.getLocationContext()), + prevFlags, C); return; } } @@ -358,7 +373,7 @@ static bool isSelfVar(SVal location, CheckerContext &C) { return false; loc::MemRegionVal MRV = cast<loc::MemRegionVal>(location); - if (const DeclRegion *DR = dyn_cast<DeclRegion>(MRV.getRegion())) + if (const DeclRegion *DR = dyn_cast<DeclRegion>(MRV.stripCasts())) return (DR->getDecl() == analCtx->getSelfDecl()); return false; diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp index 82ac8bd..eeaed2d 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp @@ -8,8 +8,6 @@ //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" -#include "clang/Index/Entity.h" -#include "clang/Index/Indexer.h" using namespace clang; using namespace ento; @@ -22,7 +20,6 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, - idx::Indexer *idxer, unsigned maxnodes, unsigned maxvisit, bool vizdot, bool vizubi, AnalysisPurgeMode purge, @@ -38,7 +35,7 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, : AnaCtxMgr(useUnoptimizedCFG, addImplicitDtors, addInitializers), Ctx(ctx), Diags(diags), LangOpts(lang), PD(pd), CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), - CheckerMgr(checkerMgr), Idxer(idxer), + CheckerMgr(checkerMgr), AScope(ScopeDecl), MaxNodes(maxnodes), MaxVisit(maxvisit), VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim), @@ -62,7 +59,6 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, CreateStoreMgr(ParentAM.CreateStoreMgr), CreateConstraintMgr(ParentAM.CreateConstraintMgr), CheckerMgr(ParentAM.CheckerMgr), - Idxer(ParentAM.Idxer), AScope(ScopeDecl), MaxNodes(ParentAM.MaxNodes), MaxVisit(ParentAM.MaxVisit), @@ -80,21 +76,3 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, { AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd(); } - - -AnalysisDeclContext * -AnalysisManager::getAnalysisDeclContextInAnotherTU(const Decl *D) { - idx::Entity Ent = idx::Entity::get(const_cast<Decl *>(D), - Idxer->getProgram()); - FunctionDecl *FuncDef; - idx::TranslationUnit *TU; - llvm::tie(FuncDef, TU) = Idxer->getDefinitionFor(Ent); - - if (FuncDef == 0) - return 0; - - // This AnalysisDeclContext wraps function definition in another translation unit. - // But it is still owned by the AnalysisManager associated with the current - // translation unit. - return AnaCtxMgr.getContext(FuncDef, TU); -} diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index eb986af..ca662c7 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -17,7 +17,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" -#include "clang/Index/TranslationUnit.h" #include "clang/AST/Expr.h" #include "clang/AST/StmtCXX.h" #include "llvm/Support/Casting.h" diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index d2da9aa..1fd9068 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -536,6 +536,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::IfStmtClass: case Stmt::IndirectGotoStmtClass: case Stmt::LabelStmtClass: + case Stmt::AttributedStmtClass: case Stmt::NoStmtClass: case Stmt::NullStmtClass: case Stmt::SwitchStmtClass: diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index b99bd54..b9f4e15 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -134,6 +134,11 @@ bool ExprEngine::shouldInlineDecl(const FunctionDecl *FD, ExplodedNode *Pred) { AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(FD); const CFG *CalleeCFG = CalleeADC->getCFG(); + // It is possible that the CFG cannot be constructed. + // Be safe, and check if the CalleeCFG is valid. + if (!CalleeCFG) + return false; + if (getNumberStackFrames(Pred->getLocationContext()) == AMgr.InlineMaxStackDepth) return false; diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index c19ebcb..008f744 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -207,7 +207,6 @@ public: PP.getLangOpts(), PD, CreateStoreMgr, CreateConstraintMgr, checkerMgr.get(), - /* Indexer */ 0, Opts.MaxNodes, Opts.MaxLoop, Opts.VisualizeEGDot, Opts.VisualizeEGUbi, Opts.AnalysisPurgeOpt, Opts.EagerlyAssume, diff --git a/contrib/llvm/tools/clang/lib/Tooling/CompilationDatabase.cpp b/contrib/llvm/tools/clang/lib/Tooling/CompilationDatabase.cpp index eea1055..dd9ccc0 100644 --- a/contrib/llvm/tools/clang/lib/Tooling/CompilationDatabase.cpp +++ b/contrib/llvm/tools/clang/lib/Tooling/CompilationDatabase.cpp @@ -13,7 +13,7 @@ #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Support/JSONParser.h" +#include "llvm/Support/YAMLParser.h" #include "llvm/Support/Path.h" #include "llvm/Support/system_error.h" @@ -22,10 +22,10 @@ namespace tooling { namespace { -/// \brief A parser for JSON escaped strings of command line arguments. +/// \brief A parser for escaped strings of command line arguments. /// /// Assumes \-escaping for quoted arguments (see the documentation of -/// unescapeJSONCommandLine(...)). +/// unescapeCommandLine(...)). class CommandLineArgumentParser { public: CommandLineArgumentParser(StringRef CommandLine) @@ -90,9 +90,6 @@ class CommandLineArgumentParser { bool next() { ++Position; - if (Position == Input.end()) return false; - // Remove the JSON escaping first. This is done unconditionally. - if (*Position == '\\') ++Position; return Position != Input.end(); } @@ -101,9 +98,9 @@ class CommandLineArgumentParser { std::vector<std::string> CommandLine; }; -std::vector<std::string> unescapeJSONCommandLine( - StringRef JSONEscapedCommandLine) { - CommandLineArgumentParser parser(JSONEscapedCommandLine); +std::vector<std::string> unescapeCommandLine( + StringRef EscapedCommandLine) { + CommandLineArgumentParser parser(EscapedCommandLine); return parser.parse(); } @@ -124,6 +121,33 @@ CompilationDatabase::loadFromDirectory(StringRef BuildDirectory, return Database.take(); } +FixedCompilationDatabase * +FixedCompilationDatabase::loadFromCommandLine(int &Argc, + const char **Argv, + Twine Directory) { + const char **DoubleDash = std::find(Argv, Argv + Argc, StringRef("--")); + if (DoubleDash == Argv + Argc) + return NULL; + std::vector<std::string> CommandLine(DoubleDash + 1, Argv + Argc); + Argc = DoubleDash - Argv; + return new FixedCompilationDatabase(Directory, CommandLine); +} + +FixedCompilationDatabase:: +FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine) { + std::vector<std::string> ToolCommandLine(1, "clang-tool"); + ToolCommandLine.insert(ToolCommandLine.end(), + CommandLine.begin(), CommandLine.end()); + CompileCommands.push_back(CompileCommand(Directory, ToolCommandLine)); +} + +std::vector<CompileCommand> +FixedCompilationDatabase::getCompileCommands(StringRef FilePath) const { + std::vector<CompileCommand> Result(CompileCommands); + Result[0].CommandLine.push_back(FilePath); + return Result; +} + JSONCompilationDatabase * JSONCompilationDatabase::loadFromFile(StringRef FilePath, std::string &ErrorMessage) { @@ -162,65 +186,77 @@ JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const { const std::vector<CompileCommandRef> &CommandsRef = CommandsRefI->getValue(); std::vector<CompileCommand> Commands; for (int I = 0, E = CommandsRef.size(); I != E; ++I) { + llvm::SmallString<8> DirectoryStorage; + llvm::SmallString<1024> CommandStorage; Commands.push_back(CompileCommand( // FIXME: Escape correctly: - CommandsRef[I].first, - unescapeJSONCommandLine(CommandsRef[I].second))); + CommandsRef[I].first->getValue(DirectoryStorage), + unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage)))); } return Commands; } bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { - llvm::SourceMgr SM; - llvm::JSONParser Parser(Database->getBuffer(), &SM); - llvm::JSONValue *Root = Parser.parseRoot(); + llvm::yaml::document_iterator I = YAMLStream.begin(); + if (I == YAMLStream.end()) { + ErrorMessage = "Error while parsing YAML."; + return false; + } + llvm::yaml::Node *Root = I->getRoot(); if (Root == NULL) { - ErrorMessage = "Error while parsing JSON."; + ErrorMessage = "Error while parsing YAML."; return false; } - llvm::JSONArray *Array = dyn_cast<llvm::JSONArray>(Root); + llvm::yaml::SequenceNode *Array = + llvm::dyn_cast<llvm::yaml::SequenceNode>(Root); if (Array == NULL) { ErrorMessage = "Expected array."; return false; } - for (llvm::JSONArray::const_iterator AI = Array->begin(), AE = Array->end(); + for (llvm::yaml::SequenceNode::iterator AI = Array->begin(), + AE = Array->end(); AI != AE; ++AI) { - const llvm::JSONObject *Object = dyn_cast<llvm::JSONObject>(*AI); + llvm::yaml::MappingNode *Object = + llvm::dyn_cast<llvm::yaml::MappingNode>(&*AI); if (Object == NULL) { ErrorMessage = "Expected object."; return false; } - StringRef EntryDirectory; - StringRef EntryFile; - StringRef EntryCommand; - for (llvm::JSONObject::const_iterator KVI = Object->begin(), - KVE = Object->end(); + llvm::yaml::ScalarNode *Directory; + llvm::yaml::ScalarNode *Command; + llvm::SmallString<8> FileStorage; + llvm::StringRef File; + for (llvm::yaml::MappingNode::iterator KVI = Object->begin(), + KVE = Object->end(); KVI != KVE; ++KVI) { - const llvm::JSONValue *Value = (*KVI)->Value; + llvm::yaml::Node *Value = (*KVI).getValue(); if (Value == NULL) { ErrorMessage = "Expected value."; return false; } - const llvm::JSONString *ValueString = - dyn_cast<llvm::JSONString>(Value); + llvm::yaml::ScalarNode *ValueString = + llvm::dyn_cast<llvm::yaml::ScalarNode>(Value); if (ValueString == NULL) { ErrorMessage = "Expected string as value."; return false; } - if ((*KVI)->Key->getRawText() == "directory") { - EntryDirectory = ValueString->getRawText(); - } else if ((*KVI)->Key->getRawText() == "file") { - EntryFile = ValueString->getRawText(); - } else if ((*KVI)->Key->getRawText() == "command") { - EntryCommand = ValueString->getRawText(); + llvm::yaml::ScalarNode *KeyString = + llvm::dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey()); + llvm::SmallString<8> KeyStorage; + if (KeyString->getValue(KeyStorage) == "directory") { + Directory = ValueString; + } else if (KeyString->getValue(KeyStorage) == "command") { + Command = ValueString; + } else if (KeyString->getValue(KeyStorage) == "file") { + File = ValueString->getValue(FileStorage); } else { - ErrorMessage = (Twine("Unknown key: \"") + - (*KVI)->Key->getRawText() + "\"").str(); + ErrorMessage = ("Unknown key: \"" + + KeyString->getRawValue() + "\"").str(); return false; } } - IndexByFile[EntryFile].push_back( - CompileCommandRef(EntryDirectory, EntryCommand)); + IndexByFile[File].push_back( + CompileCommandRef(Directory, Command)); } return true; } diff --git a/contrib/llvm/tools/llc/llc.cpp b/contrib/llvm/tools/llc/llc.cpp index 9e30ac1..ceff8a6 100644 --- a/contrib/llvm/tools/llc/llc.cpp +++ b/contrib/llvm/tools/llc/llc.cpp @@ -210,29 +210,6 @@ DontPlaceZerosInBSS("nozero-initialized-in-bss", cl::init(false)); static cl::opt<bool> -EnableJITExceptionHandling("jit-enable-eh", - cl::desc("Emit exception handling information"), - cl::init(false)); - -// In debug builds, make this default to true. -#ifdef NDEBUG -#define EMIT_DEBUG false -#else -#define EMIT_DEBUG true -#endif -static cl::opt<bool> -EmitJitDebugInfo("jit-emit-debug", - cl::desc("Emit debug information to debugger"), - cl::init(EMIT_DEBUG)); -#undef EMIT_DEBUG - -static cl::opt<bool> -EmitJitDebugInfoToDisk("jit-emit-debug-to-disk", - cl::Hidden, - cl::desc("Emit debug info objfiles to disk"), - cl::init(false)); - -static cl::opt<bool> EnableGuaranteedTailCallOpt("tailcallopt", cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."), cl::init(false)); @@ -463,9 +440,6 @@ int main(int argc, char **argv) { if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; Options.NoZerosInBSS = DontPlaceZerosInBSS; - Options.JITExceptionHandling = EnableJITExceptionHandling; - Options.JITEmitDebugInfo = EmitJitDebugInfo; - Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk; Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; Options.DisableTailCalls = DisableTailCalls; Options.StackAlignmentOverride = OverrideStackAlignment; diff --git a/contrib/llvm/tools/lli/lli.cpp b/contrib/llvm/tools/lli/lli.cpp index efcc1f5..2e2bf7d 100644 --- a/contrib/llvm/tools/lli/lli.cpp +++ b/contrib/llvm/tools/lli/lli.cpp @@ -141,6 +141,28 @@ namespace { "Large code model"), clEnumValEnd)); + cl::opt<bool> + EnableJITExceptionHandling("jit-enable-eh", + cl::desc("Emit exception handling information"), + cl::init(false)); + + cl::opt<bool> +// In debug builds, make this default to true. +#ifdef NDEBUG +#define EMIT_DEBUG false +#else +#define EMIT_DEBUG true +#endif + EmitJitDebugInfo("jit-emit-debug", + cl::desc("Emit debug information to debugger"), + cl::init(EMIT_DEBUG)); +#undef EMIT_DEBUG + + static cl::opt<bool> + EmitJitDebugInfoToDisk("jit-emit-debug-to-disk", + cl::Hidden, + cl::desc("Emit debug info objfiles to disk"), + cl::init(false)); } static ExecutionEngine *EE = 0; @@ -229,6 +251,12 @@ int main(int argc, char **argv, char * const *envp) { } builder.setOptLevel(OLvl); + TargetOptions Options; + Options.JITExceptionHandling = EnableJITExceptionHandling; + Options.JITEmitDebugInfo = EmitJitDebugInfo; + Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk; + builder.setTargetOptions(Options); + EE = builder.create(); if (!EE) { if (!ErrorMsg.empty()) diff --git a/contrib/llvm/tools/llvm-mc/Disassembler.cpp b/contrib/llvm/tools/llvm-mc/Disassembler.cpp index a8cd7c1..5f2fdb8 100644 --- a/contrib/llvm/tools/llvm-mc/Disassembler.cpp +++ b/contrib/llvm/tools/llvm-mc/Disassembler.cpp @@ -17,21 +17,18 @@ #include "../../lib/MC/MCDisassembler/EDInst.h" #include "../../lib/MC/MCDisassembler/EDOperand.h" #include "../../lib/MC/MCDisassembler/EDToken.h" -#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstPrinter.h" -#include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Triple.h" -#include "llvm/ADT/Twine.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryObject.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" + using namespace llvm; typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy; @@ -56,8 +53,9 @@ public: } static bool PrintInsts(const MCDisassembler &DisAsm, - MCInstPrinter &Printer, const ByteArrayTy &Bytes, - SourceMgr &SM, raw_ostream &Out) { + const ByteArrayTy &Bytes, + SourceMgr &SM, raw_ostream &Out, + MCStreamer &Streamer) { // Wrap the vector in a MemoryObject. VectorMemoryObject memoryObject(Bytes); @@ -87,8 +85,7 @@ static bool PrintInsts(const MCDisassembler &DisAsm, // Fall through case MCDisassembler::Success: - Printer.printInst(&Inst, Out, ""); - Out << "\n"; + Streamer.EmitInstruction(Inst); break; } } @@ -145,56 +142,22 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray, int Disassembler::disassemble(const Target &T, const std::string &Triple, - const std::string &Cpu, - const std::string &FeaturesStr, + MCSubtargetInfo &STI, + MCStreamer &Streamer, MemoryBuffer &Buffer, + SourceMgr &SM, raw_ostream &Out) { - // Set up disassembler. - OwningPtr<const MCAsmInfo> AsmInfo(T.createMCAsmInfo(Triple)); - - if (!AsmInfo) { - errs() << "error: no assembly info for target " << Triple << "\n"; - return -1; - } - - OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu, - FeaturesStr)); - if (!STI) { - errs() << "error: no subtarget info for target " << Triple << "\n"; - return -1; - } - - OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(*STI)); + OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(STI)); if (!DisAsm) { errs() << "error: no disassembler for target " << Triple << "\n"; return -1; } - OwningPtr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple)); - if (!MRI) { - errs() << "error: no register info for target " << Triple << "\n"; - return -1; - } - - OwningPtr<const MCInstrInfo> MII(T.createMCInstrInfo()); - if (!MII) { - errs() << "error: no instruction info for target " << Triple << "\n"; - return -1; - } - - int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); - OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant, *AsmInfo, - *MII, *MRI, *STI)); - if (!IP) { - errs() << "error: no instruction printer for target " << Triple << '\n'; - return -1; - } + // Set up initial section manually here + Streamer.InitSections(); bool ErrorOccurred = false; - SourceMgr SM; - SM.AddNewSourceBuffer(&Buffer, SMLoc()); - // Convert the input to a vector for disassembly. ByteArrayTy ByteArray; StringRef Str = Buffer.getBuffer(); @@ -202,7 +165,7 @@ int Disassembler::disassemble(const Target &T, ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM); if (!ByteArray.empty()) - ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM, Out); + ErrorOccurred |= PrintInsts(*DisAsm, ByteArray, SM, Out, Streamer); return ErrorOccurred; } @@ -236,12 +199,10 @@ static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) { int Disassembler::disassembleEnhanced(const std::string &TS, MemoryBuffer &Buffer, + SourceMgr &SM, raw_ostream &Out) { ByteArrayTy ByteArray; StringRef Str = Buffer.getBuffer(); - SourceMgr SM; - - SM.AddNewSourceBuffer(&Buffer, SMLoc()); if (ByteArrayFromString(ByteArray, Str, SM)) { return -1; diff --git a/contrib/llvm/tools/llvm-mc/Disassembler.h b/contrib/llvm/tools/llvm-mc/Disassembler.h index e8cd92d..17d622f 100644 --- a/contrib/llvm/tools/llvm-mc/Disassembler.h +++ b/contrib/llvm/tools/llvm-mc/Disassembler.h @@ -22,18 +22,23 @@ namespace llvm { class MemoryBuffer; class Target; class raw_ostream; +class SourceMgr; +class MCSubtargetInfo; +class MCStreamer; class Disassembler { public: - static int disassemble(const Target &target, - const std::string &tripleString, - const std::string &Cpu, - const std::string &FeaturesStr, - MemoryBuffer &buffer, + static int disassemble(const Target &T, + const std::string &Triple, + MCSubtargetInfo &STI, + MCStreamer &Streamer, + MemoryBuffer &Buffer, + SourceMgr &SM, raw_ostream &Out); static int disassembleEnhanced(const std::string &tripleString, MemoryBuffer &buffer, + SourceMgr &SM, raw_ostream &Out); }; diff --git a/contrib/llvm/tools/llvm-mc/llvm-mc.cpp b/contrib/llvm/tools/llvm-mc/llvm-mc.cpp index d882e01..36a482e 100644 --- a/contrib/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/contrib/llvm/tools/llvm-mc/llvm-mc.cpp @@ -15,6 +15,7 @@ #include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCInstPrinter.h" @@ -242,37 +243,11 @@ static void setDwarfDebugFlags(int argc, char **argv) { } } -static int AsLexInput(const char *ProgName) { - OwningPtr<MemoryBuffer> BufferPtr; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) { - errs() << ProgName << ": " << ec.message() << '\n'; - return 1; - } - MemoryBuffer *Buffer = BufferPtr.take(); - - SourceMgr SrcMgr; - - // Tell SrcMgr about this buffer, which is what TGParser will pick up. - SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); - - // Record the location of the include directories so that the lexer can find - // it later. - SrcMgr.setIncludeDirs(IncludeDirs); - - const Target *TheTarget = GetTarget(ProgName); - if (!TheTarget) - return 1; - - llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName)); - assert(MAI && "Unable to create target asm info!"); +static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) { - AsmLexer Lexer(*MAI); + AsmLexer Lexer(MAI); Lexer.setBuffer(SrcMgr.getMemoryBuffer(0)); - OwningPtr<tool_output_file> Out(GetOutputStream()); - if (!Out) - return 1; - bool Error = false; while (Lexer.Lex().isNot(AsmToken::Eof)) { AsmToken Tok = Lexer.getTok(); @@ -346,13 +321,49 @@ static int AsLexInput(const char *ProgName) { Out->os() << "\")\n"; } - // Keep output if no errors. - if (Error == 0) Out->keep(); - return Error; } -static int AssembleInput(const char *ProgName) { +static int AssembleInput(const char *ProgName, const Target *TheTarget, + SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str, + MCAsmInfo &MAI, MCSubtargetInfo &STI) { + OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, + Str, MAI)); + OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(STI, *Parser)); + if (!TAP) { + errs() << ProgName + << ": error: this target does not support assembly parsing.\n"; + return 1; + } + + Parser->setShowParsedOperands(ShowInstOperands); + Parser->setTargetParser(*TAP.get()); + + int Res = Parser->Run(NoInitialTextSection); + + return Res; +} + +int main(int argc, char **argv) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + // Initialize targets and assembly printers/parsers. + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmParsers(); + llvm::InitializeAllDisassemblers(); + + // Register the target printer for --version. + cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); + + cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); + TripleName = Triple::normalize(TripleName); + setDwarfDebugFlags(argc, argv); + + const char *ProgName = argv[0]; const Target *TheTarget = GetTarget(ProgName); if (!TheTarget) return 1; @@ -413,7 +424,6 @@ static int AssembleInput(const char *ProgName) { OwningPtr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); - // FIXME: There is a bit of code duplication with addPassesToEmitFile. if (FileType == OFT_AssemblyFile) { MCInstPrinter *IP = TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI); @@ -440,93 +450,24 @@ static int AssembleInput(const char *ProgName) { NoExecStack)); } - OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, - *Str.get(), *MAI)); - OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser)); - if (!TAP) { - errs() << ProgName - << ": error: this target does not support assembly parsing.\n"; - return 1; - } - - Parser->setShowParsedOperands(ShowInstOperands); - Parser->setTargetParser(*TAP.get()); - - int Res = Parser->Run(NoInitialTextSection); - - // Keep output if no errors. - if (Res == 0) Out->keep(); - - return Res; -} - -static int DisassembleInput(const char *ProgName, bool Enhanced) { - const Target *TheTarget = GetTarget(ProgName); - if (!TheTarget) - return 0; - - OwningPtr<MemoryBuffer> Buffer; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, Buffer)) { - errs() << ProgName << ": " << ec.message() << '\n'; - return 1; - } - - OwningPtr<tool_output_file> Out(GetOutputStream()); - if (!Out) - return 1; - - int Res; - if (Enhanced) { - Res = - Disassembler::disassembleEnhanced(TripleName, *Buffer.take(), Out->os()); - } else { - // Package up features to be passed to target/subtarget - std::string FeaturesStr; - if (MAttrs.size()) { - SubtargetFeatures Features; - for (unsigned i = 0; i != MAttrs.size(); ++i) - Features.AddFeature(MAttrs[i]); - FeaturesStr = Features.getString(); - } - - Res = Disassembler::disassemble(*TheTarget, TripleName, MCPU, FeaturesStr, - *Buffer.take(), Out->os()); - } - - // Keep output if no errors. - if (Res == 0) Out->keep(); - - return Res; -} - - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // Initialize targets and assembly printers/parsers. - llvm::InitializeAllTargetInfos(); - llvm::InitializeAllTargetMCs(); - llvm::InitializeAllAsmParsers(); - llvm::InitializeAllDisassemblers(); - - // Register the target printer for --version. - cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); - - cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); - TripleName = Triple::normalize(TripleName); - setDwarfDebugFlags(argc, argv); - + int Res = 1; switch (Action) { case AC_AsLex: - return AsLexInput(argv[0]); + Res = AsLexInput(SrcMgr, *MAI, Out.get()); + break; case AC_Assemble: - return AssembleInput(argv[0]); + Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI); + break; case AC_Disassemble: - return DisassembleInput(argv[0], false); + Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, + *Buffer, SrcMgr, Out->os()); + break; case AC_EDisassemble: - return DisassembleInput(argv[0], true); + Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, SrcMgr, Out->os()); + break; } + + // Keep output if no errors. + if (Res == 0) Out->keep(); + return Res; } diff --git a/contrib/llvm/tools/llvm-stress/llvm-stress.cpp b/contrib/llvm/tools/llvm-stress/llvm-stress.cpp index d284ea5..fb05a58 100644 --- a/contrib/llvm/tools/llvm-stress/llvm-stress.cpp +++ b/contrib/llvm/tools/llvm-stress/llvm-stress.cpp @@ -412,7 +412,7 @@ struct ExtractElementModifier: public Modifier { Value *Val0 = getRandomVectorValue(); Value *V = ExtractElementInst::Create(Val0, ConstantInt::get(Type::getInt32Ty(BB->getContext()), - Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), + Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), "E", BB->getTerminator()); return PT->push_back(V); } @@ -476,7 +476,7 @@ struct CastModifier: public Modifier { DestTy = pickVectorType(VecTy->getNumElements()); } - // no need to casr. + // no need to cast. if (VTy == DestTy) return; // Pointers: @@ -487,9 +487,11 @@ struct CastModifier: public Modifier { new BitCastInst(V, DestTy, "PC", BB->getTerminator())); } + unsigned VSize = VTy->getScalarType()->getPrimitiveSizeInBits(); + unsigned DestSize = DestTy->getScalarType()->getPrimitiveSizeInBits(); + // Generate lots of bitcasts. - if ((Ran->Rand() & 1) && - VTy->getPrimitiveSizeInBits() == DestTy->getPrimitiveSizeInBits()) { + if ((Ran->Rand() & 1) && VSize == DestSize) { return PT->push_back( new BitCastInst(V, DestTy, "BC", BB->getTerminator())); } @@ -497,11 +499,11 @@ struct CastModifier: public Modifier { // Both types are integers: if (VTy->getScalarType()->isIntegerTy() && DestTy->getScalarType()->isIntegerTy()) { - if (VTy->getScalarType()->getPrimitiveSizeInBits() > - DestTy->getScalarType()->getPrimitiveSizeInBits()) { + if (VSize > DestSize) { return PT->push_back( new TruncInst(V, DestTy, "Tr", BB->getTerminator())); } else { + assert(VSize < DestSize && "Different int types with the same size?"); if (Ran->Rand() & 1) return PT->push_back( new ZExtInst(V, DestTy, "ZE", BB->getTerminator())); @@ -531,14 +533,15 @@ struct CastModifier: public Modifier { // Both floats. if (VTy->getScalarType()->isFloatingPointTy() && DestTy->getScalarType()->isFloatingPointTy()) { - if (VTy->getScalarType()->getPrimitiveSizeInBits() > - DestTy->getScalarType()->getPrimitiveSizeInBits()) { + if (VSize > DestSize) { return PT->push_back( new FPTruncInst(V, DestTy, "Tr", BB->getTerminator())); - } else { + } else if (VSize < DestSize) { return PT->push_back( new FPExtInst(V, DestTy, "ZE", BB->getTerminator())); } + // If VSize == DestSize, then the two types must be fp128 and ppc_fp128, + // for which there is no defined conversion. So do nothing. } } diff --git a/contrib/llvm/tools/opt/opt.cpp b/contrib/llvm/tools/opt/opt.cpp index 30da863..a5b0511 100644 --- a/contrib/llvm/tools/opt/opt.cpp +++ b/contrib/llvm/tools/opt/opt.cpp @@ -114,6 +114,9 @@ static cl::opt<bool> OptLevelO3("O3", cl::desc("Optimization level 3. Similar to llvm-gcc -O3")); +static cl::opt<std::string> +TargetTriple("mtriple", cl::desc("Override target triple for module")); + static cl::opt<bool> UnitAtATime("funit-at-a-time", cl::desc("Enable IPO. This is same as llvm-gcc's -funit-at-a-time"), @@ -512,6 +515,10 @@ int main(int argc, char **argv) { return 1; } + // If we are supposed to override the target triple, do so now. + if (!TargetTriple.empty()) + M->setTargetTriple(Triple::normalize(TargetTriple)); + // Figure out what stream we are supposed to write to... OwningPtr<tool_output_file> Out; if (NoOutput) { diff --git a/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp index 39a3c25..dc92a6c 100644 --- a/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -1181,7 +1181,8 @@ void AsmMatcherInfo::BuildInfo() { unsigned VariantCount = Target.getAsmParserVariantCount(); for (unsigned VC = 0; VC != VariantCount; ++VC) { Record *AsmVariant = Target.getAsmParserVariant(VC); - std::string CommentDelimiter = AsmVariant->getValueAsString("CommentDelimiter"); + std::string CommentDelimiter = + AsmVariant->getValueAsString("CommentDelimiter"); std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); @@ -1208,11 +1209,11 @@ void AsmMatcherInfo::BuildInfo() { // reject it. We reject aliases and ignore instructions for now. if (OI.MINumOperands != 1) { // FIXME: Should reject these. The ARM backend hits this with $lane - // in a bunch of instructions. It is unclear what the right answer is. + // in a bunch of instructions. The right answer is unclear. DEBUG({ errs() << "warning: '" << CGI.TheDef->getName() << "': " - << "ignoring instruction with multi-operand tied operand '" - << OI.Name << "'\n"; + << "ignoring instruction with multi-operand tied operand '" + << OI.Name << "'\n"; }); continue; } @@ -1248,8 +1249,8 @@ void AsmMatcherInfo::BuildInfo() { // If the tblgen -match-prefix option is specified (for tblgen hackers), // filter the set of instruction aliases we consider, based on the target // instruction. - if (!StringRef(Alias->ResultInst->TheDef->getName()).startswith( - MatchPrefix)) + if (!StringRef(Alias->ResultInst->TheDef->getName()) + .startswith( MatchPrefix)) continue; OwningPtr<MatchableInfo> II(new MatchableInfo(Alias)); @@ -1328,6 +1329,9 @@ void AsmMatcherInfo::BuildInfo() { Record *Rec = AllTokenAliases[i]; ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken")); ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken")); + if (FromClass == ToClass) + throw TGError(Rec->getLoc(), + "error: Destination value identical to source value."); FromClass->SuperClasses.push_back(ToClass); } @@ -1868,7 +1872,8 @@ static void EmitComputeAvailableFeatures(AsmMatcherInfo &Info, SubtargetFeatureInfo &SFI = *it->second; OS << " if ("; - std::string CondStorage = SFI.TheDef->getValueAsString("AssemblerCondString"); + std::string CondStorage = + SFI.TheDef->getValueAsString("AssemblerCondString"); StringRef Conds = CondStorage; std::pair<StringRef,StringRef> Comma = Conds.split(','); bool First = true; diff --git a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp index e0b0aac..d079b45 100644 --- a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -289,7 +289,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; if (AWI != 0 && - AWI->Operands[0].OperandType == AsmWriterOperand::isLiteralTextOperand && + AWI->Operands[0].OperandType == + AsmWriterOperand::isLiteralTextOperand && !AWI->Operands[0].Str.empty()) { std::string Str = AWI->Operands[0].Str; UnescapeString(Str); @@ -589,7 +590,7 @@ class IAPrinter { std::map<StringRef, unsigned> OpMap; std::string Result; std::string AsmString; - std::vector<Record*> ReqFeatures; + SmallVector<Record*, 4> ReqFeatures; public: IAPrinter(std::string R, std::string AS) : Result(R), AsmString(AS) {} @@ -919,7 +920,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { O << " }\n"; O << " }\n"; O << " }\n\n"; - + O << " return true;\n"; O << "}\n\n"; diff --git a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index d2ddf23..d4b02fb 100644 --- a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -17,6 +17,7 @@ #include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include <algorithm> @@ -2483,10 +2484,9 @@ static void InferFromPattern(const CodeGenInstruction &Inst, // If we decided that this is a store from the pattern, then the .td file // entry is redundant. if (MayStore) - fprintf(stderr, - "Warning: mayStore flag explicitly set on instruction '%s'" - " but flag already inferred from pattern.\n", - Inst.TheDef->getName().c_str()); + PrintWarning(Inst.TheDef->getLoc(), + "mayStore flag explicitly set on " + "instruction, but flag already inferred from pattern."); MayStore = true; } @@ -2494,24 +2494,25 @@ static void InferFromPattern(const CodeGenInstruction &Inst, // If we decided that this is a load from the pattern, then the .td file // entry is redundant. if (MayLoad) - fprintf(stderr, - "Warning: mayLoad flag explicitly set on instruction '%s'" - " but flag already inferred from pattern.\n", - Inst.TheDef->getName().c_str()); + PrintWarning(Inst.TheDef->getLoc(), + "mayLoad flag explicitly set on " + "instruction, but flag already inferred from pattern."); MayLoad = true; } if (Inst.neverHasSideEffects) { if (HadPattern) - fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' " - "which already has a pattern\n", Inst.TheDef->getName().c_str()); + PrintWarning(Inst.TheDef->getLoc(), + "neverHasSideEffects flag explicitly set on " + "instruction, but flag already inferred from pattern."); HasSideEffects = false; } if (Inst.hasSideEffects) { if (HasSideEffects) - fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' " - "which already inferred this.\n", Inst.TheDef->getName().c_str()); + PrintWarning(Inst.TheDef->getLoc(), + "hasSideEffects flag explicitly set on " + "instruction, but flag already inferred from pattern."); HasSideEffects = true; } diff --git a/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp b/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp index 7ce4f878..45c5bb8 100644 --- a/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp +++ b/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" using namespace llvm; @@ -896,11 +897,10 @@ void CodeGenRegBank::computeComposites() { if (i1d->second == Reg3) { // Conflicting composition? Emit a warning but allow it. if (CodeGenSubRegIndex *Prev = Idx1->addComposite(Idx2, i1d->first)) - errs() << "Warning: SubRegIndex " << Idx1->getQualifiedName() - << " and " << Idx2->getQualifiedName() - << " compose ambiguously as " - << Prev->getQualifiedName() << " or " - << i1d->first->getQualifiedName() << "\n"; + PrintWarning(Twine("SubRegIndex") + Idx1->getQualifiedName() + + " and " + Idx2->getQualifiedName() + + " compose ambiguously as " + Prev->getQualifiedName() + + " or " + i1d->first->getQualifiedName()); } } } diff --git a/contrib/llvm/utils/TableGen/EDEmitter.cpp b/contrib/llvm/utils/TableGen/EDEmitter.cpp index 3809a45..fe484ca 100644 --- a/contrib/llvm/utils/TableGen/EDEmitter.cpp +++ b/contrib/llvm/utils/TableGen/EDEmitter.cpp @@ -594,6 +594,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("jtblock_operand"); IMM("nohash_imm"); IMM("p_imm"); + IMM("pf_imm"); IMM("c_imm"); IMM("coproc_option_imm"); IMM("imod_op"); diff --git a/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp index a2478a7..97fcca3 100644 --- a/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -17,22 +17,23 @@ #include "CodeGenTarget.h" #include "CodeGenRegisters.h" #include "SequenceToOffsetTable.h" +#include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Format.h" #include <algorithm> #include <set> using namespace llvm; // runEnums - Print out enum values for all of the registers. -void -RegisterInfoEmitter::runEnums(raw_ostream &OS, - CodeGenTarget &Target, CodeGenRegBank &Bank) { +void RegisterInfoEmitter::runEnums(raw_ostream &OS, + CodeGenTarget &Target, CodeGenRegBank &Bank) { const std::vector<CodeGenRegister*> &Registers = Bank.getRegisters(); - // Register enums are stored as uint16_t in the tables. Make sure we'll fit + // Register enums are stored as uint16_t in the tables. Make sure we'll fit. assert(Registers.size() <= 0xffff && "Too many regs to fit in tables"); std::string Namespace = Registers[0]->TheDef->getValueAsString("Namespace"); @@ -208,8 +209,8 @@ RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS, std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers"); maxLength = std::max((size_t)maxLength, RegNums.size()); if (DwarfRegNums.count(Reg)) - errs() << "Warning: DWARF numbers for register " << getQualifiedName(Reg) - << "specified multiple times\n"; + PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") + + getQualifiedName(Reg) + "specified multiple times"); DwarfRegNums[Reg] = RegNums; } diff --git a/lib/clang/Makefile b/lib/clang/Makefile index d6e9457..2d77383 100644 --- a/lib/clang/Makefile +++ b/lib/clang/Makefile @@ -12,7 +12,6 @@ SUBDIR= libclanganalysis \ libclangedit \ libclangfrontend \ libclangfrontendtool \ - libclangindex \ libclanglex \ libclangparse \ libclangrewrite \ diff --git a/lib/clang/clang.build.mk b/lib/clang/clang.build.mk index a14918d..67868f1 100644 --- a/lib/clang/clang.build.mk +++ b/lib/clang/clang.build.mk @@ -25,9 +25,7 @@ LLVM_REQUIRES_RTTI= CXXFLAGS+=-fno-rtti .endif -.ifdef TOOLS_PREFIX -CFLAGS+=-DCLANG_PREFIX=\"${TOOLS_PREFIX}\" -.endif +CFLAGS+=-DDEFAULT_SYSROOT=\"${TOOLS_PREFIX}\" .PATH: ${LLVM_SRCS}/${SRCDIR} diff --git a/lib/clang/include/clang/Basic/Version.inc b/lib/clang/include/clang/Basic/Version.inc index 55d4ea6..dd67a2b 100644 --- a/lib/clang/include/clang/Basic/Version.inc +++ b/lib/clang/include/clang/Basic/Version.inc @@ -5,6 +5,6 @@ #define CLANG_VERSION_MINOR 1 #define CLANG_VENDOR "FreeBSD " -#define CLANG_VENDOR_SUFFIX " 20120413" +#define CLANG_VENDOR_SUFFIX " 20120503" -#define SVN_REVISION "154661" +#define SVN_REVISION "155985" diff --git a/lib/clang/include/clang/Config/config.h b/lib/clang/include/clang/Config/config.h index 7348308..8a7936b 100644 --- a/lib/clang/include/clang/Config/config.h +++ b/lib/clang/include/clang/Config/config.h @@ -11,10 +11,16 @@ /* Relative directory for resource files */ #define CLANG_RESOURCE_DIR "" -/* Directory where gcc is installed. */ -#define GCC_INSTALL_PREFIX "" - /* Directories clang will search for headers */ #define C_INCLUDE_DIRS "" +/* Linker version detected at compile time. */ +/* #undef HOST_LINK_VERSION */ + +/* Default <path> to all compiler invocations for --sysroot=<path>. */ +/* #undef DEFAULT_SYSROOT */ + +/* Directory where gcc is installed. */ +#define GCC_INSTALL_PREFIX "" + #endif diff --git a/lib/clang/include/llvm/Config/config.h b/lib/clang/include/llvm/Config/config.h index f6001e9..c84c6d8 100644 --- a/lib/clang/include/llvm/Config/config.h +++ b/lib/clang/include/llvm/Config/config.h @@ -14,6 +14,9 @@ /* Directories clang will search for headers */ #define C_INCLUDE_DIRS "" +/* Default <path> to all compiler invocations for --sysroot=<path>. */ +/* #undef DEFAULT_SYSROOT */ + /* Define if position independent code is enabled */ #define ENABLE_PIC 0 diff --git a/lib/clang/libclangindex/Makefile b/lib/clang/libclangindex/Makefile deleted file mode 100644 index 63b532c..0000000 --- a/lib/clang/libclangindex/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# $FreeBSD$ - -LIB= clangindex - -SRCDIR= tools/clang/lib/Index -SRCS= ASTLocation.cpp \ - Analyzer.cpp \ - DeclReferenceMap.cpp \ - Entity.cpp \ - GlobalSelector.cpp \ - Handlers.cpp \ - IndexProvider.cpp \ - Indexer.cpp \ - Program.cpp \ - SelectorMap.cpp \ - -TGHDRS= AttrList \ - Attrs \ - DeclNodes \ - DiagnosticCommonKinds \ - StmtNodes - -.include "../clang.lib.mk" diff --git a/lib/clang/libclangsema/Makefile b/lib/clang/libclangsema/Makefile index e40a756..3b2b331 100644 --- a/lib/clang/libclangsema/Makefile +++ b/lib/clang/libclangsema/Makefile @@ -36,6 +36,7 @@ SRCS= AnalysisBasedWarnings.cpp \ SemaOverload.cpp \ SemaPseudoObject.cpp \ SemaStmt.cpp \ + SemaStmtAttr.cpp \ SemaTemplate.cpp \ SemaTemplateDeduction.cpp \ SemaTemplateInstantiate.cpp \ diff --git a/lib/clang/libllvmruntimedyld/Makefile b/lib/clang/libllvmruntimedyld/Makefile index 7280e1d..d5d5447 100644 --- a/lib/clang/libllvmruntimedyld/Makefile +++ b/lib/clang/libllvmruntimedyld/Makefile @@ -3,7 +3,8 @@ LIB= llvmruntimedyld SRCDIR= lib/ExecutionEngine/RuntimeDyld -SRCS= RuntimeDyld.cpp \ +SRCS= GDBRegistrar.cpp \ + RuntimeDyld.cpp \ RuntimeDyldELF.cpp \ RuntimeDyldMachO.cpp diff --git a/lib/clang/libllvmsupport/Makefile b/lib/clang/libllvmsupport/Makefile index 19afb44..5fcff88 100644 --- a/lib/clang/libllvmsupport/Makefile +++ b/lib/clang/libllvmsupport/Makefile @@ -30,6 +30,7 @@ SRCS= APFloat.cpp \ IntervalMap.cpp \ IntEqClasses.cpp \ IntrusiveRefCntPtr.cpp \ + Locale.cpp \ LockFileManager.cpp \ ManagedStatic.cpp \ Memory.cpp \ diff --git a/usr.bin/clang/clang/Makefile b/usr.bin/clang/clang/Makefile index 60f1736..946dea9 100644 --- a/usr.bin/clang/clang/Makefile +++ b/usr.bin/clang/clang/Makefile @@ -41,7 +41,6 @@ LIBDEPS=clangfrontendtool \ clangstaticanalyzercheckers \ clangstaticanalyzercore \ clanganalysis \ - clangindex \ clangarcmigrate \ clangrewrite \ clangedit \ |