diff options
Diffstat (limited to 'include/llvm/CodeGen')
29 files changed, 855 insertions, 211 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 377096c..28a1a3e 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -19,7 +19,6 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/DebugLoc.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/ADT/DenseMap.h" namespace llvm { class BlockAddress; @@ -62,13 +61,6 @@ namespace llvm { class AsmPrinter : public MachineFunctionPass { static char ID; - /// FunctionNumber - This provides a unique ID for each function emitted in - /// this translation unit. It is autoincremented by SetupMachineFunction, - /// and can be accessed with getFunctionNumber() and - /// IncrementFunctionNumber(). - /// - unsigned FunctionNumber; - // GCMetadataPrinters - The garbage collection metadata printer table. typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type; typedef gcp_map_type::iterator gcp_iterator; @@ -88,13 +80,6 @@ namespace llvm { DwarfWriter *DW; public: - /// Flags to specify different kinds of comments to output in - /// assembly code. These flags carry semantic information not - /// otherwise easily derivable from the IR text. - /// - enum CommentFlag { - ReloadReuse = 0x1 - }; /// Output stream on which we're printing assembly code. /// @@ -157,7 +142,8 @@ namespace llvm { protected: explicit AsmPrinter(formatted_raw_ostream &o, TargetMachine &TM, - const MCAsmInfo *T, bool V); + MCContext &Ctx, MCStreamer &Streamer, + const MCAsmInfo *T); public: virtual ~AsmPrinter(); @@ -168,7 +154,7 @@ namespace llvm { /// getFunctionNumber - Return a unique ID for the current function. /// - unsigned getFunctionNumber() const { return FunctionNumber; } + unsigned getFunctionNumber() const; protected: /// getAnalysisUsage - Record analysis usage. @@ -215,26 +201,51 @@ namespace llvm { unsigned AsmVariant, const char *ExtraCode); + /// runOnMachineFunction - Emit the specified function out to the + /// OutStreamer. + virtual bool runOnMachineFunction(MachineFunction &MF) { + SetupMachineFunction(MF); + EmitFunctionHeader(); + EmitFunctionBody(); + return false; + } + /// SetupMachineFunction - This should be called when a new MachineFunction /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); - /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should - /// not normally call this, as the counter is automatically bumped by - /// SetupMachineFunction. - void IncrementFunctionNumber() { FunctionNumber++; } + /// EmitFunctionHeader - This method emits the header for the current + /// function. + void EmitFunctionHeader(); + + /// EmitFunctionBody - This method emits the body and trailer for a + /// function. + void EmitFunctionBody(); + + /// EmitInstruction - Targets should implement this to emit instructions. + virtual void EmitInstruction(const MachineInstr *MI) { + assert(0 && "EmitInstruction not implemented"); + } + + /// EmitFunctionBodyStart - Targets can override this to emit stuff before + /// the first basic block in the function. + virtual void EmitFunctionBodyStart() {} + + /// EmitFunctionBodyEnd - Targets can override this to emit stuff after + /// the last basic block in the function. + virtual void EmitFunctionBodyEnd() {} /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by /// the code generator. /// - void EmitConstantPool(MachineConstantPool *MCP); - + virtual void EmitConstantPool(); + /// EmitJumpTableInfo - Print assembly representations of the jump tables /// used by the current function to the current output stream. /// - void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF); + void EmitJumpTableInfo(); /// EmitGlobalVariable - Emit the specified global variable to the .s file. virtual void EmitGlobalVariable(const GlobalVariable *GV); @@ -265,9 +276,6 @@ namespace llvm { /// void EmitInt64(uint64_t Value) const; - /// EmitFile - Emit a .file directive. - void EmitFile(unsigned Number, StringRef Name) const; - //===------------------------------------------------------------------===// /// EmitAlignment - Emit an alignment directive to the specified power of @@ -292,19 +300,15 @@ namespace llvm { /// printLabel - This method prints a local label used by debug and /// exception handling tables. - void printLabel(const MachineInstr *MI) const; void printLabel(unsigned Id) const; /// printDeclare - This method prints a local variable declaration used by /// debug tables. void printDeclare(const MachineInstr *MI) const; - /// EmitComments - Pretty-print comments for instructions - void EmitComments(const MachineInstr &MI) const; - /// GetGlobalValueSymbol - Return the MCSymbol for the specified global /// value. - MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const; + virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const; /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with /// global value name as its base, with the specified suffix, and where the @@ -317,23 +321,21 @@ namespace llvm { /// ExternalSymbol. MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const; - /// GetMBBSymbol - Return the MCSymbol corresponding to the specified basic - /// block label. - MCSymbol *GetMBBSymbol(unsigned MBBID) const; - /// GetCPISymbol - Return the symbol for the specified constant pool entry. MCSymbol *GetCPISymbol(unsigned CPID) const; /// GetJTISymbol - Return the symbol for the specified jump table entry. MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const; + /// GetJTSetSymbol - Return the symbol for the specified jump table .set + /// FIXME: privatize to AsmPrinter. + MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const; + /// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress /// uses of the specified basic block. - MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA, - const char *Suffix = "") const; + MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const; MCSymbol *GetBlockAddressSymbol(const Function *F, - const BasicBlock *BB, - const char *Suffix = "") const; + const BasicBlock *BB) const; /// EmitBasicBlockStart - This method prints the label for the specified /// MachineBasicBlock, an alignment (if present) and a comment describing @@ -347,12 +349,21 @@ namespace llvm { void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0); protected: + virtual void EmitFunctionEntryLabel(); + virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); + /// printOffset - This is just convenient handler for printing offsets. + void printOffset(int64_t Offset) const; + + private: + /// processDebugLoc - Processes the debug information of each machine /// instruction's DebugLoc. void processDebugLoc(const MachineInstr *MI, bool BeforePrintingInsn); + void printLabelInst(const MachineInstr *MI) const; + /// printInlineAsm - This method formats and prints the specified machine /// instruction that is an inline asm. void printInlineAsm(const MachineInstr *MI) const; @@ -364,24 +375,15 @@ namespace llvm { /// printKill - This method prints the specified kill machine instruction. void printKill(const MachineInstr *MI) const; - /// printPICJumpTableSetLabel - This method prints a set label for the - /// specified MachineBasicBlock for a jumptable entry. - virtual void printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const; - virtual void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, - const MachineBasicBlock *MBB) const; - virtual void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, - const MachineBasicBlock *MBB, - unsigned uid) const; - - /// printVisibility - This prints visibility information about symbol, if + /// EmitVisibility - This emits visibility information about symbol, if /// this is suported by the target. - void printVisibility(MCSymbol *Sym, unsigned Visibility) const; + void EmitVisibility(MCSymbol *Sym, unsigned Visibility) const; - /// printOffset - This is just convenient handler for printing offsets. - void printOffset(int64_t Offset) const; - - private: + void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const; + + void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, + const MachineBasicBlock *MBB, + unsigned uid) const; void EmitLLVMUsedList(Constant *List); void EmitXXStructorList(Constant *List); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index 4d50879..7fda6f7 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -132,4 +132,283 @@ void SelectRoot(SelectionDAG &DAG) { CurDAG->setRoot(Dummy.getValue()); } + +/// CheckInteger - Return true if the specified node is not a ConstantSDNode or +/// if it doesn't have the specified value. +static bool CheckInteger(SDValue V, int64_t Val) { + ConstantSDNode *C = dyn_cast<ConstantSDNode>(V); + return C == 0 || C->getSExtValue() != Val; +} + +/// CheckAndImmediate - Check to see if the specified node is an and with an +/// immediate returning true on failure. +/// +/// FIXME: Inline this gunk into CheckAndMask. +bool CheckAndImmediate(SDValue V, int64_t Val) { + if (V->getOpcode() == ISD::AND) + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1))) + if (CheckAndMask(V.getOperand(0), C, Val)) + return false; + return true; +} + +/// CheckOrImmediate - Check to see if the specified node is an or with an +/// immediate returning true on failure. +/// +/// FIXME: Inline this gunk into CheckOrMask. +bool CheckOrImmediate(SDValue V, int64_t Val) { + if (V->getOpcode() == ISD::OR) + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1))) + if (CheckOrMask(V.getOperand(0), C, Val)) + return false; + return true; +} + +// These functions are marked always inline so that Idx doesn't get pinned to +// the stack. +ALWAYS_INLINE static int8_t +GetInt1(const unsigned char *MatcherTable, unsigned &Idx) { + return MatcherTable[Idx++]; +} + +ALWAYS_INLINE static int16_t +GetInt2(const unsigned char *MatcherTable, unsigned &Idx) { + int16_t Val = GetInt1(MatcherTable, Idx); + Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8; + return Val; +} + +ALWAYS_INLINE static int32_t +GetInt4(const unsigned char *MatcherTable, unsigned &Idx) { + int32_t Val = GetInt2(MatcherTable, Idx); + Val |= int32_t(GetInt2(MatcherTable, Idx)) << 16; + return Val; +} + +ALWAYS_INLINE static int64_t +GetInt8(const unsigned char *MatcherTable, unsigned &Idx) { + int64_t Val = GetInt4(MatcherTable, Idx); + Val |= int64_t(GetInt4(MatcherTable, Idx)) << 32; + return Val; +} + +enum BuiltinOpcodes { + OPC_Emit, + OPC_Push, + OPC_Record, + OPC_MoveChild, + OPC_MoveParent, + OPC_CheckSame, + OPC_CheckPatternPredicate, + OPC_CheckPredicate, + OPC_CheckOpcode, + OPC_CheckType, + OPC_CheckInteger1, OPC_CheckInteger2, OPC_CheckInteger4, OPC_CheckInteger8, + OPC_CheckCondCode, + OPC_CheckValueType, + OPC_CheckComplexPat, + OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8, + OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8, + OPC_IsProfitableToFold, + OPC_IsLegalToFold +}; + +struct MatchScope { + /// FailIndex - If this match fails, this is the index to continue with. + unsigned FailIndex; + + /// NodeStackSize - The size of the node stack when the scope was formed. + unsigned NodeStackSize; + + /// NumRecordedNodes - The number of recorded nodes when the scope was formed. + unsigned NumRecordedNodes; +}; + +SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, + unsigned TableSize) { + switch (NodeToMatch->getOpcode()) { + default: + break; + case ISD::EntryToken: // These nodes remain the same. + case ISD::BasicBlock: + case ISD::Register: + case ISD::HANDLENODE: + case ISD::TargetConstant: + case ISD::TargetConstantFP: + case ISD::TargetConstantPool: + case ISD::TargetFrameIndex: + case ISD::TargetExternalSymbol: + case ISD::TargetBlockAddress: + case ISD::TargetJumpTable: + case ISD::TargetGlobalTLSAddress: + case ISD::TargetGlobalAddress: + case ISD::TokenFactor: + case ISD::CopyFromReg: + case ISD::CopyToReg: + return 0; + case ISD::AssertSext: + case ISD::AssertZext: + ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0)); + return 0; + case ISD::INLINEASM: return Select_INLINEASM(NodeToMatch); + case ISD::EH_LABEL: return Select_EH_LABEL(NodeToMatch); + case ISD::UNDEF: return Select_UNDEF(NodeToMatch); + } + + assert(!NodeToMatch->isMachineOpcode() && "Node already selected!"); + + SmallVector<MatchScope, 8> MatchScopes; + + // RecordedNodes - This is the set of nodes that have been recorded by the + // state machine. + SmallVector<SDValue, 8> RecordedNodes; + + // Set up the node stack with NodeToMatch as the only node on the stack. + SmallVector<SDValue, 8> NodeStack; + SDValue N = SDValue(NodeToMatch, 0); + NodeStack.push_back(N); + + // Interpreter starts at opcode #0. + unsigned MatcherIndex = 0; + while (1) { + assert(MatcherIndex < TableSize && "Invalid index"); + switch ((BuiltinOpcodes)MatcherTable[MatcherIndex++]) { + case OPC_Emit: { + errs() << "EMIT NODE\n"; + return 0; + } + case OPC_Push: { + unsigned NumToSkip = MatcherTable[MatcherIndex++]; + MatchScope NewEntry; + NewEntry.FailIndex = MatcherIndex+NumToSkip; + NewEntry.NodeStackSize = NodeStack.size(); + NewEntry.NumRecordedNodes = RecordedNodes.size(); + MatchScopes.push_back(NewEntry); + continue; + } + case OPC_Record: + // Remember this node, it may end up being an operand in the pattern. + RecordedNodes.push_back(N); + continue; + + case OPC_MoveChild: { + unsigned Child = MatcherTable[MatcherIndex++]; + if (Child >= N.getNumOperands()) + break; // Match fails if out of range child #. + N = N.getOperand(Child); + NodeStack.push_back(N); + continue; + } + + case OPC_MoveParent: + // Pop the current node off the NodeStack. + NodeStack.pop_back(); + assert(!NodeStack.empty() && "Node stack imbalance!"); + N = NodeStack.back(); + continue; + + case OPC_CheckSame: { + // Accept if it is exactly the same as a previously recorded node. + unsigned RecNo = MatcherTable[MatcherIndex++]; + assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); + if (N != RecordedNodes[RecNo]) break; + continue; + } + case OPC_CheckPatternPredicate: + if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break; + continue; + case OPC_CheckPredicate: + if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break; + continue; + case OPC_CheckComplexPat: { + unsigned PatNo = MatcherTable[MatcherIndex++]; + (void)PatNo; + // FIXME: CHECK IT. + continue; + } + + case OPC_CheckOpcode: + if (N->getOpcode() != MatcherTable[MatcherIndex++]) break; + continue; + case OPC_CheckType: + if (N.getValueType() != + (MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break; + continue; + case OPC_CheckCondCode: + if (cast<CondCodeSDNode>(N)->get() != + (ISD::CondCode)MatcherTable[MatcherIndex++]) break; + continue; + case OPC_CheckValueType: + if (cast<VTSDNode>(N)->getVT() != + (MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break; + continue; + + case OPC_CheckInteger1: + if (CheckInteger(N, GetInt1(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckInteger2: + if (CheckInteger(N, GetInt2(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckInteger4: + if (CheckInteger(N, GetInt4(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckInteger8: + if (CheckInteger(N, GetInt8(MatcherTable, MatcherIndex))) break; + continue; + + case OPC_CheckAndImm1: + if (CheckAndImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckAndImm2: + if (CheckAndImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckAndImm4: + if (CheckAndImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckAndImm8: + if (CheckAndImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break; + continue; + + case OPC_CheckOrImm1: + if (CheckOrImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckOrImm2: + if (CheckOrImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckOrImm4: + if (CheckOrImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckOrImm8: + if (CheckOrImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break; + continue; + + case OPC_IsProfitableToFold: + assert(!NodeStack.size() == 1 && "No parent node"); + if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(), + NodeToMatch)) + break; + continue; + case OPC_IsLegalToFold: + assert(!NodeStack.size() == 1 && "No parent node"); + if (!IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(), + NodeToMatch)) + break; + continue; + } + + // If the code reached this point, then the match failed pop out to the next + // match scope. + if (MatchScopes.empty()) { + CannotYetSelect(NodeToMatch); + return 0; + } + + RecordedNodes.resize(MatchScopes.back().NumRecordedNodes); + NodeStack.resize(MatchScopes.back().NodeStackSize); + MatcherIndex = MatchScopes.back().FailIndex; + MatchScopes.pop_back(); + } +} + + #endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */ diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h index 460c3c7..d59e22a 100644 --- a/include/llvm/CodeGen/DwarfWriter.h +++ b/include/llvm/CodeGen/DwarfWriter.h @@ -76,11 +76,11 @@ public: /// BeginFunction - Gather pre-function debug information. Assumes being /// emitted immediately after the function entry point. - void BeginFunction(MachineFunction *MF); + void BeginFunction(const MachineFunction *MF); /// EndFunction - Gather and emit post-function debug information. /// - void EndFunction(MachineFunction *MF); + void EndFunction(const MachineFunction *MF); /// RecordSourceLine - Register a source line with debug info. Returns a /// unique label ID used to generate a label and provide correspondence to diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h deleted file mode 100644 index 9dba838..0000000 --- a/include/llvm/CodeGen/FileWriters.h +++ /dev/null @@ -1,37 +0,0 @@ -//===-- FileWriters.h - File Writers Creation Functions ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Functions to add the various file writer passes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_FILEWRITERS_H -#define LLVM_CODEGEN_FILEWRITERS_H - -namespace llvm { - - class PassManagerBase; - class ObjectCodeEmitter; - class TargetMachine; - class raw_ostream; - class formatted_raw_ostream; - class MachineFunctionPass; - class MCAsmInfo; - class MCCodeEmitter; - - ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O, - TargetMachine &TM); - MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O, - TargetMachine &TM, - const MCAsmInfo *T, - MCCodeEmitter *MCE); - -} // end llvm namespace - -#endif // LLVM_CODEGEN_FILEWRITERS_H diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h index 9c4e5b9..0a1d4f4 100644 --- a/include/llvm/CodeGen/JITCodeEmitter.h +++ b/include/llvm/CodeGen/JITCodeEmitter.h @@ -146,7 +146,7 @@ public: } } - /// emitAlignment - Move the CurBufferPtr pointer up the the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment) { if (Alignment == 0) Alignment = 1; diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index e31a7f0..512c94d 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -320,7 +320,7 @@ namespace llvm { /// advanceTo - Advance the specified iterator to point to the LiveRange /// containing the specified position, or end() if the position is past the /// end of the interval. If no LiveRange contains this position, but the - /// position is in a hole, this method returns an iterator pointing the the + /// position is in a hole, this method returns an iterator pointing to the /// LiveRange immediately after the hole. iterator advanceTo(iterator I, SlotIndex Pos) { if (Pos >= endIndex()) diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 20644c1..db82ba5 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -21,6 +21,9 @@ namespace llvm { class BasicBlock; class MachineFunction; +class MCContext; +class MCSymbol; +class StringRef; class raw_ostream; template <> @@ -338,7 +341,7 @@ public: bool isCond); /// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping - /// any DEBUG_VALUE instructions. Return UnknownLoc if there is none. + /// any DBG_VALUE instructions. Return UnknownLoc if there is none. DebugLoc findDebugLoc(MachineBasicBlock::iterator &MBBI); // Debugging methods. @@ -352,6 +355,10 @@ public: int getNumber() const { return Number; } void setNumber(int N) { Number = N; } + /// getSymbol - Return the MCSymbol for this basic block. + /// + MCSymbol *getSymbol(MCContext &Ctx) const; + private: // Methods used to maintain doubly linked list of blocks... friend struct ilist_traits<MachineBasicBlock>; diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index d598a93..48b4082 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -155,7 +155,7 @@ public: } } - /// emitAlignment - Move the CurBufferPtr pointer up the the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment) { if (Alignment == 0) Alignment = 1; diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index 8d6c1d1..e6698a5 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -136,7 +136,7 @@ public: : TD(td), PoolAlignment(1) {} ~MachineConstantPool(); - /// getConstantPoolAlignment - Return the the alignment required by + /// getConstantPoolAlignment - Return the alignment required by /// the whole constant pool, of which the first element must be aligned. unsigned getConstantPoolAlignment() const { return PoolAlignment; } diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 968e4ea..043e97f 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -276,6 +276,7 @@ public: assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && "Invalid Object Idx!"); Objects[ObjectIdx+NumFixedObjects].Alignment = Align; + MaxAlignment = std::max(MaxAlignment, Align); } /// getObjectOffset - Return the assigned stack offset of the specified object @@ -328,19 +329,6 @@ public: /// void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } - /// calculateMaxStackAlignment() - If there is a local object which requires - /// greater alignment than the current max alignment, adjust accordingly. - void calculateMaxStackAlignment() { - for (int i = getObjectIndexBegin(), - e = getObjectIndexEnd(); i != e; ++i) { - if (isDeadObjectIndex(i)) - continue; - - unsigned Align = getObjectAlignment(i); - MaxAlignment = std::max(MaxAlignment, Align); - } - } - /// hasCalls - Return true if the current function has no function calls. /// This is only valid during or after prolog/epilog code emission. /// @@ -402,6 +390,7 @@ public: Objects.push_back(StackObject(Size, Alignment, 0, false, isSS)); int Index = (int)Objects.size()-NumFixedObjects-1; assert(Index >= 0 && "Bad frame index!"); + MaxAlignment = std::max(MaxAlignment, Alignment); return Index; } @@ -412,6 +401,7 @@ public: int CreateSpillStackObject(uint64_t Size, unsigned Alignment) { CreateStackObject(Size, Alignment, true); int Index = (int)Objects.size()-NumFixedObjects-1; + MaxAlignment = std::max(MaxAlignment, Alignment); return Index; } diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 6ca51bf..3c5b466 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -33,6 +33,7 @@ class MachineRegisterInfo; class MachineFrameInfo; class MachineConstantPool; class MachineJumpTableInfo; +class Pass; class TargetMachine; class TargetRegisterClass; @@ -112,6 +113,11 @@ class MachineFunction { // Tracks debug locations. DebugLocTracker DebugLocInfo; + /// FunctionNumber - This provides a unique ID for each function emitted in + /// this translation unit. + /// + unsigned FunctionNumber; + // The alignment of the function. unsigned Alignment; @@ -119,13 +125,17 @@ class MachineFunction { void operator=(const MachineFunction&); // intentionally unimplemented public: - MachineFunction(Function *Fn, const TargetMachine &TM); + MachineFunction(Function *Fn, const TargetMachine &TM, unsigned FunctionNum); ~MachineFunction(); /// getFunction - Return the LLVM function that this machine code represents /// Function *getFunction() const { return Fn; } + /// getFunctionNumber - Return a unique ID for the current function. + /// + unsigned getFunctionNumber() const { return FunctionNumber; } + /// getTarget - Return the target machine this machine code is compiled with /// const TargetMachine &getTarget() const { return Target; } @@ -143,11 +153,16 @@ public: const MachineFrameInfo *getFrameInfo() const { return FrameInfo; } /// getJumpTableInfo - Return the jump table info object for the current - /// function. This object contains information about jump tables for switch - /// instructions in the current function. - /// - MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; } + /// function. This object contains information about jump tables in the + /// current function. If the current function has no jump tables, this will + /// return null. const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; } + MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; } + + /// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it + /// does already exist, allocate one. + MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind); + /// getConstantPool - Return the constant pool object for the current /// function. @@ -163,6 +178,11 @@ public: /// void setAlignment(unsigned A) { Alignment = A; } + /// EnsureAlignment - Make sure the function is at least 'A' bits aligned. + void EnsureAlignment(unsigned A) { + if (Alignment < A) Alignment = A; + } + /// getInfo - Keep track of various per-function pieces of information for /// backends that would like to do so. /// @@ -310,7 +330,7 @@ public: bool NoImp = false); /// CloneMachineInstr - Create a new MachineInstr which is a copy of the - /// 'Orig' instruction, identical in all ways except the the instruction + /// 'Orig' instruction, identical in all ways except the instruction /// has no parent, prev, or next. /// /// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned @@ -363,6 +383,17 @@ public: MachineInstr::mmo_iterator End); //===--------------------------------------------------------------------===// + // Label Manipulation. + // + + /// getJTISymbol - Return the MCSymbol for the specified non-empty jump table. + /// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a + /// normal 'L' label is returned. + MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx, + bool isLinkerPrivate = false) const; + + + //===--------------------------------------------------------------------===// // Debug location. // diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h index aa4cc91..ee2c6dd 100644 --- a/include/llvm/CodeGen/MachineFunctionAnalysis.h +++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h @@ -28,7 +28,7 @@ private: const TargetMachine &TM; CodeGenOpt::Level OptLevel; MachineFunction *MF; - + unsigned NextFnNum; public: static char ID; explicit MachineFunctionAnalysis(const TargetMachine &tm, @@ -39,6 +39,7 @@ public: CodeGenOpt::Level getOptLevel() const { return OptLevel; } private: + virtual bool doInitialization(Module &) { NextFnNum = 1; return false; } virtual bool runOnFunction(Function &F); virtual void releaseMemory(); virtual void getAnalysisUsage(AnalysisUsage &AU) const; diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index c2a0578..6e33fb3 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -19,9 +19,9 @@ #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/Target/TargetInstrDesc.h" +#include "llvm/Target/TargetOpcodes.h" #include "llvm/Support/DebugLoc.h" #include <vector> @@ -41,6 +41,14 @@ class MachineInstr : public ilist_node<MachineInstr> { public: typedef MachineMemOperand **mmo_iterator; + /// Flags to specify different kinds of comments to output in + /// assembly code. These flags carry semantic information not + /// otherwise easily derivable from the IR text. + /// + enum CommentFlag { + ReloadReuse = 0x1 + }; + private: const TargetInstrDesc *TID; // Instruction descriptor. unsigned short NumImplicitOps; // Number of implicit operands (which @@ -121,14 +129,14 @@ public: /// getAsmPrinterFlag - Return whether an AsmPrinter flag is set. /// - bool getAsmPrinterFlag(AsmPrinter::CommentFlag Flag) const { + bool getAsmPrinterFlag(CommentFlag Flag) const { return AsmPrinterFlags & Flag; } /// setAsmPrinterFlag - Set a flag for the AsmPrinter. /// - void setAsmPrinterFlag(unsigned short Flag) { - AsmPrinterFlags |= Flag; + void setAsmPrinterFlag(CommentFlag Flag) { + AsmPrinterFlags |= (unsigned short)Flag; } /// getDebugLoc - Returns the debug location id of this MachineInstr. @@ -193,12 +201,31 @@ public: /// isLabel - Returns true if the MachineInstr represents a label. /// - bool isLabel() const; - - /// isDebugLabel - Returns true if the MachineInstr represents a debug label. - /// - bool isDebugLabel() const; - + bool isLabel() const { + return getOpcode() == TargetOpcode::DBG_LABEL || + getOpcode() == TargetOpcode::EH_LABEL || + getOpcode() == TargetOpcode::GC_LABEL; + } + + bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; } + bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } + bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } + bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } + + bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } + bool isKill() const { return getOpcode() == TargetOpcode::KILL; } + bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } + bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } + bool isExtractSubreg() const { + return getOpcode() == TargetOpcode::EXTRACT_SUBREG; + } + bool isInsertSubreg() const { + return getOpcode() == TargetOpcode::INSERT_SUBREG; + } + bool isSubregToReg() const { + return getOpcode() == TargetOpcode::SUBREG_TO_REG; + } + /// readsRegister - Return true if the MachineInstr reads the specified /// register. If TargetRegisterInfo is passed, then it also checks if there /// is a read of a super-register. @@ -320,7 +347,7 @@ public: /// isInvariantLoad - Return true if this instruction is loading from a /// location whose value is invariant across the function. For example, - /// loading a value from the constant pool or from from the argument area of + /// loading a value from the constant pool or from the argument area of /// a function if it does not change. This should only return true of *all* /// loads the instruction does are invariant (if it does multiple loads). bool isInvariantLoad(AliasAnalysis *AA) const; diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 8eb0add..a263a97 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -32,6 +32,7 @@ namespace RegState { Dead = 0x10, Undef = 0x20, EarlyClobber = 0x40, + Debug = 0x80, ImplicitDefine = Implicit | Define, ImplicitKill = Implicit | Kill }; @@ -62,7 +63,8 @@ public: flags & RegState::Dead, flags & RegState::Undef, flags & RegState::EarlyClobber, - SubReg)); + SubReg, + flags & RegState::Debug)); return *this; } diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index 57c65c8..5a4c9a9fb 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -40,13 +40,45 @@ struct MachineJumpTableEntry { }; class MachineJumpTableInfo { - unsigned EntrySize; - unsigned Alignment; +public: + /// JTEntryKind - This enum indicates how each entry of the jump table is + /// represented and emitted. + enum JTEntryKind { + /// EK_BlockAddress - Each entry is a plain address of block, e.g.: + /// .word LBB123 + EK_BlockAddress, + + /// EK_GPRel32BlockAddress - Each entry is an address of block, encoded + /// with a relocation as gp-relative, e.g.: + /// .gprel32 LBB123 + EK_GPRel32BlockAddress, + + /// EK_LabelDifference32 - Each entry is the address of the block minus + /// the address of the jump table. This is used for PIC jump tables where + /// gprel32 is not supported. e.g.: + /// .word LBB123 - LJTI1_2 + /// If the .set directive is supported, this is emitted as: + /// .set L4_5_set_123, LBB123 - LJTI1_2 + /// .word L4_5_set_123 + EK_LabelDifference32, + + /// EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the + /// TargetLowering::LowerCustomJumpTableEntry hook. + EK_Custom32 + }; +private: + JTEntryKind EntryKind; std::vector<MachineJumpTableEntry> JumpTables; public: - MachineJumpTableInfo(unsigned Size, unsigned Align) - : EntrySize(Size), Alignment(Align) {} + MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {} + JTEntryKind getEntryKind() const { return EntryKind; } + + /// getEntrySize - Return the size of each entry in the jump table. + unsigned getEntrySize(const TargetData &TD) const; + /// getEntryAlignment - Return the alignment of each entry in the jump table. + unsigned getEntryAlignment(const TargetData &TD) const; + /// getJumpTableIndex - Create a new jump table or return an existing one. /// unsigned getJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs); @@ -58,9 +90,9 @@ public: const std::vector<MachineJumpTableEntry> &getJumpTables() const { return JumpTables; } - - /// RemoveJumpTable - Mark the specific index as being dead. This will cause - /// it to not be emitted. + + /// RemoveJumpTable - Mark the specific index as being dead. This will + /// prevent it from being emitted. void RemoveJumpTable(unsigned Idx) { JumpTables[Idx].MBBs.clear(); } @@ -74,13 +106,6 @@ public: bool ReplaceMBBInJumpTable(unsigned Idx, MachineBasicBlock *Old, MachineBasicBlock *New); - /// getEntrySize - Returns the size of an individual field in a jump table. - /// - unsigned getEntrySize() const { return EntrySize; } - - /// getAlignment - returns the target's preferred alignment for jump tables - unsigned getAlignment() const { return Alignment; } - /// print - Used by the MachineFunction printer to print information about /// jump tables. Implemented in MachineFunction.cpp /// diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index 5dee199..7272aa5 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -46,7 +46,11 @@ public: /// The memory access writes data. MOStore = 2, /// The memory access is volatile. - MOVolatile = 4 + MOVolatile = 4, + /// The memory access is non-temporal. + MONonTemporal = 8, + // This is the number of bits we need to represent flags. + MOMaxBits = 4 }; /// MachineMemOperand - Construct an MachineMemOperand object with the @@ -64,7 +68,7 @@ public: const Value *getValue() const { return V; } /// getFlags - Return the raw flags of the source value, \see MemOperandFlags. - unsigned int getFlags() const { return Flags & 7; } + unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); } /// getOffset - For normal values, this is a byte offset added to the base /// address. For PseudoSourceValue::FPRel values, this is the FrameIndex @@ -80,11 +84,12 @@ public: /// getBaseAlignment - Return the minimum known alignment in bytes of the /// base address, without the offset. - uint64_t getBaseAlignment() const { return (1u << (Flags >> 3)) >> 1; } + uint64_t getBaseAlignment() const { return (1u << (Flags >> MOMaxBits)) >> 1; } bool isLoad() const { return Flags & MOLoad; } bool isStore() const { return Flags & MOStore; } bool isVolatile() const { return Flags & MOVolatile; } + bool isNonTemporal() const { return Flags & MONonTemporal; } /// refineAlignment - Update this MachineMemOperand to reflect the alignment /// of MMO, if it has a greater alignment. This must only be used when the diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index d365029..8eeac9f 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -50,6 +50,7 @@ namespace llvm { //===----------------------------------------------------------------------===// // Forward declarations. class Constant; +class MCSymbol; class MDNode; class GlobalVariable; class MachineBasicBlock; @@ -66,6 +67,12 @@ class StructType; class MachineModuleInfoImpl { public: virtual ~MachineModuleInfoImpl(); + + typedef std::vector<std::pair<MCSymbol*, MCSymbol*> > + SymbolListTy; +protected: + static SymbolListTy + GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map); }; @@ -113,7 +120,14 @@ class MachineModuleInfo : public ImmutablePass { // LandingPads - List of LandingPadInfo describing the landing pad information // in the current function. std::vector<LandingPadInfo> LandingPads; - + + // Map of invoke call site index values to associated begin EH_LABEL for + // the current function. + DenseMap<unsigned, unsigned> CallSiteMap; + + // The current call site index being processed, if any. 0 if none. + unsigned CurCallSite; + // TypeInfos - List of C++ TypeInfo used in the current function. // std::vector<GlobalVariable *> TypeInfos; @@ -157,10 +171,6 @@ public: bool doInitialization(); bool doFinalization(); - /// BeginFunction - Begin gathering function meta information. - /// - void BeginFunction(MachineFunction *) {} - /// EndFunction - Discard function meta information. /// void EndFunction(); @@ -298,7 +308,26 @@ public: const std::vector<LandingPadInfo> &getLandingPads() const { return LandingPads; } - + + /// setCallSiteBeginLabel - Map the begin label for a call site + void setCallSiteBeginLabel(unsigned BeginLabel, unsigned Site) { + CallSiteMap[BeginLabel] = Site; + } + + /// getCallSiteBeginLabel - Get the call site number for a begin label + unsigned getCallSiteBeginLabel(unsigned BeginLabel) { + assert(CallSiteMap.count(BeginLabel) && + "Missing call site number for EH_LABEL!"); + return CallSiteMap[BeginLabel]; + } + + /// setCurrentCallSite - Set the call site currently being processed. + void setCurrentCallSite(unsigned Site) { CurCallSite = Site; } + + /// getCurrentCallSite - Get the call site currently being processed, if any. + /// return zero if none. + unsigned getCurrentCallSite(void) { return CurCallSite; } + /// getTypeInfos - Return a reference to the C++ typeinfo for the current /// function. const std::vector<GlobalVariable *> &getTypeInfos() const { diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h index 44813cb..89b8207 100644 --- a/include/llvm/CodeGen/MachineModuleInfoImpls.h +++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h @@ -19,46 +19,43 @@ namespace llvm { class MCSymbol; - + /// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation /// for MachO targets. class MachineModuleInfoMachO : public MachineModuleInfoImpl { /// FnStubs - Darwin '$stub' stubs. The key is something like "Lfoo$stub", /// the value is something like "_foo". - DenseMap<const MCSymbol*, const MCSymbol*> FnStubs; + DenseMap<MCSymbol*, MCSymbol*> FnStubs; /// GVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like /// "Lfoo$non_lazy_ptr", the value is something like "_foo". - DenseMap<const MCSymbol*, const MCSymbol*> GVStubs; + DenseMap<MCSymbol*, MCSymbol*> GVStubs; /// HiddenGVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like /// "Lfoo$non_lazy_ptr", the value is something like "_foo". Unlike GVStubs /// these are for things with hidden visibility. - DenseMap<const MCSymbol*, const MCSymbol*> HiddenGVStubs; + DenseMap<MCSymbol*, MCSymbol*> HiddenGVStubs; virtual void Anchor(); // Out of line virtual method. public: MachineModuleInfoMachO(const MachineModuleInfo &) {} - const MCSymbol *&getFnStubEntry(const MCSymbol *Sym) { + MCSymbol *&getFnStubEntry(MCSymbol *Sym) { assert(Sym && "Key cannot be null"); return FnStubs[Sym]; } - const MCSymbol *&getGVStubEntry(const MCSymbol *Sym) { + MCSymbol *&getGVStubEntry(MCSymbol *Sym) { assert(Sym && "Key cannot be null"); return GVStubs[Sym]; } - const MCSymbol *&getHiddenGVStubEntry(const MCSymbol *Sym) { + MCSymbol *&getHiddenGVStubEntry(MCSymbol *Sym) { assert(Sym && "Key cannot be null"); return HiddenGVStubs[Sym]; } - + /// Accessor methods to return the set of stubs in sorted order. - typedef std::vector<std::pair<const MCSymbol*, const MCSymbol*> > - SymbolListTy; - SymbolListTy GetFnStubList() const { return GetSortedStubs(FnStubs); } @@ -68,12 +65,31 @@ namespace llvm { SymbolListTy GetHiddenGVStubList() const { return GetSortedStubs(HiddenGVStubs); } - - private: - static SymbolListTy - GetSortedStubs(const DenseMap<const MCSymbol*, const MCSymbol*> &Map); }; - + + /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation + /// for ELF targets. + class MachineModuleInfoELF : public MachineModuleInfoImpl { + /// GVStubs - These stubs are used to materialize global addresses in PIC + /// mode. + DenseMap<MCSymbol*, MCSymbol*> GVStubs; + + virtual void Anchor(); // Out of line virtual method. + public: + MachineModuleInfoELF(const MachineModuleInfo &) {} + + MCSymbol *&getGVStubEntry(MCSymbol *Sym) { + assert(Sym && "Key cannot be null"); + return GVStubs[Sym]; + } + + /// Accessor methods to return the set of stubs in sorted order. + + SymbolListTy GetGVStubList() const { + return GetSortedStubs(GVStubs); + } + }; + } // end namespace llvm #endif diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 07d886d..dac0092 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -87,6 +87,10 @@ private: /// model the GCC inline asm '&' constraint modifier. bool IsEarlyClobber : 1; + /// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo, + /// not a real instruction. Such uses should be ignored during codegen. + bool IsDebug : 1; + /// ParentMI - This is the instruction that this operand is embedded into. /// This is valid for all operand types, when the operand is in an instr. MachineInstr *ParentMI; @@ -214,6 +218,11 @@ public: return IsEarlyClobber; } + bool isDebug() const { + assert(isReg() && "Wrong MachineOperand accessor"); + return IsDebug; + } + /// getNextOperandForReg - Return the next MachineOperand in the function that /// uses or defines this register. MachineOperand *getNextOperandForReg() const { @@ -236,11 +245,13 @@ public: void setIsUse(bool Val = true) { assert(isReg() && "Wrong MachineOperand accessor"); + assert((Val || !isDebug()) && "Marking a debug operation as def"); IsDef = !Val; } void setIsDef(bool Val = true) { assert(isReg() && "Wrong MachineOperand accessor"); + assert((!Val || !isDebug()) && "Marking a debug operation as def"); IsDef = Val; } @@ -251,6 +262,7 @@ public: void setIsKill(bool Val = true) { assert(isReg() && !IsDef && "Wrong MachineOperand accessor"); + assert((!Val || !isDebug()) && "Marking a debug operation as kill"); IsKill = Val; } @@ -366,7 +378,7 @@ public: /// the setReg method should be used. void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false, bool isKill = false, bool isDead = false, - bool isUndef = false); + bool isUndef = false, bool isDebug = false); //===--------------------------------------------------------------------===// // Construction methods. @@ -388,7 +400,8 @@ public: bool isKill = false, bool isDead = false, bool isUndef = false, bool isEarlyClobber = false, - unsigned SubReg = 0) { + unsigned SubReg = 0, + bool isDebug = false) { MachineOperand Op(MachineOperand::MO_Register); Op.IsDef = isDef; Op.IsImp = isImp; @@ -396,6 +409,7 @@ public: Op.IsDead = isDead; Op.IsUndef = isUndef; Op.IsEarlyClobber = isEarlyClobber; + Op.IsDebug = isDebug; Op.Contents.Reg.RegNo = Reg; Op.Contents.Reg.Prev = 0; Op.Contents.Reg.Next = 0; diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index c55cb32..01dc018 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -78,12 +78,12 @@ public: /// reg_begin/reg_end - Provide iteration support to walk over all definitions /// and uses of a register within the MachineFunction that corresponds to this /// MachineRegisterInfo object. - template<bool Uses, bool Defs> + template<bool Uses, bool Defs, bool SkipDebug> class defusechain_iterator; /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified /// register. - typedef defusechain_iterator<true,true> reg_iterator; + typedef defusechain_iterator<true,true,false> reg_iterator; reg_iterator reg_begin(unsigned RegNo) const { return reg_iterator(getRegUseDefListHead(RegNo)); } @@ -94,7 +94,7 @@ public: bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); } /// def_iterator/def_begin/def_end - Walk all defs of the specified register. - typedef defusechain_iterator<false,true> def_iterator; + typedef defusechain_iterator<false,true,false> def_iterator; def_iterator def_begin(unsigned RegNo) const { return def_iterator(getRegUseDefListHead(RegNo)); } @@ -105,7 +105,7 @@ public: bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); } /// use_iterator/use_begin/use_end - Walk all uses of the specified register. - typedef defusechain_iterator<true,false> use_iterator; + typedef defusechain_iterator<true,false,false> use_iterator; use_iterator use_begin(unsigned RegNo) const { return use_iterator(getRegUseDefListHead(RegNo)); } @@ -115,7 +115,20 @@ public: /// register. bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); } + /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the + /// specified register, skipping those marked as Debug. + typedef defusechain_iterator<true,false,true> use_nodbg_iterator; + use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const { + return use_nodbg_iterator(getRegUseDefListHead(RegNo)); + } + static use_nodbg_iterator use_nodbg_end() { return use_nodbg_iterator(0); } + /// use_nodbg_empty - Return true if there are no non-Debug instructions + /// using the specified register. + bool use_nodbg_empty(unsigned RegNo) const { + return use_nodbg_begin(RegNo) == use_nodbg_end(); + } + /// replaceRegWith - Replace all instances of FromReg with ToReg in the /// machine function. This is like llvm-level X->replaceAllUsesWith(Y), /// except that it also changes any definitions of the register as well. @@ -258,8 +271,9 @@ public: /// operands in the function that use or define a specific register. If /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it /// returns defs. If neither are true then you are silly and it always - /// returns end(). - template<bool ReturnUses, bool ReturnDefs> + /// returns end(). If SkipDebug is true it skips uses marked Debug + /// when incrementing. + template<bool ReturnUses, bool ReturnDefs, bool SkipDebug> class defusechain_iterator : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> { MachineOperand *Op; @@ -268,7 +282,8 @@ public: // we are interested in. if (op) { if ((!ReturnUses && op->isUse()) || - (!ReturnDefs && op->isDef())) + (!ReturnDefs && op->isDef()) || + (SkipDebug && op->isDebug())) ++*this; } } @@ -299,7 +314,8 @@ public: // If this is an operand we don't care about, skip it. while (Op && ((!ReturnUses && Op->isUse()) || - (!ReturnDefs && Op->isDef()))) + (!ReturnDefs && Op->isDef()) || + (SkipDebug && Op->isDebug()))) Op = Op->getNextOperandForReg(); return *this; diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h index 1c15fab..c316785 100644 --- a/include/llvm/CodeGen/MachineRelocation.h +++ b/include/llvm/CodeGen/MachineRelocation.h @@ -138,14 +138,15 @@ public: /// static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType, const char *ES, intptr_t cst = 0, - bool GOTrelative = 0) { + bool GOTrelative = 0, + bool NeedStub = true) { assert((RelocationType & ~63) == 0 && "Relocation type too large!"); MachineRelocation Result; Result.Offset = offset; Result.ConstantVal = cst; Result.TargetReloType = RelocationType; Result.AddrType = isExtSym; - Result.MayNeedFarStub = true; + Result.MayNeedFarStub = NeedStub; Result.GOTRelative = GOTrelative; Result.TargetResolve = false; Result.Target.ExtSym = ES; diff --git a/include/llvm/CodeGen/ObjectCodeEmitter.h b/include/llvm/CodeGen/ObjectCodeEmitter.h index 8252e07..170c0c8 100644 --- a/include/llvm/CodeGen/ObjectCodeEmitter.h +++ b/include/llvm/CodeGen/ObjectCodeEmitter.h @@ -81,7 +81,7 @@ public: /// written to the data stream in big-endian format. void emitDWordBE(uint64_t W); - /// emitAlignment - Move the CurBufferPtr pointer up the the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment = 0, uint8_t fill = 0); diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 7e0da3f..dbc73cb 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -174,6 +174,10 @@ namespace llvm { /// optimization by increasing uses of extended values. FunctionPass *createOptimizeExtsPass(); + /// createOptimizePHIsPass - This pass optimizes machine instruction PHIs + /// to take advantage of opportunities created during DAG legalization. + FunctionPass *createOptimizePHIsPass(); + /// createStackSlotColoringPass - This pass performs stack slot coloring. FunctionPass *createStackSlotColoringPass(bool); diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 33ebd00..e628603 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -581,18 +581,18 @@ public: /// determined by their operands, and they produce a value AND a token chain. /// SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, - const Value *SV, int SVOffset, bool isVolatile=false, - unsigned Alignment=0); + const Value *SV, int SVOffset, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT, - SDValue Chain, SDValue Ptr, const Value *SV, - int SVOffset, EVT MemVT, bool isVolatile=false, - unsigned Alignment=0); + SDValue Chain, SDValue Ptr, const Value *SV, + int SVOffset, EVT MemVT, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM); SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, const Value *SV, int SVOffset, EVT MemVT, - bool isVolatile=false, unsigned Alignment=0); + bool isVolatile, bool isNonTemporal, unsigned Alignment); SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, EVT MemVT, MachineMemOperand *MMO); @@ -600,13 +600,14 @@ public: /// getStore - Helper function to build ISD::STORE nodes. /// SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, - const Value *SV, int SVOffset, bool isVolatile=false, - unsigned Alignment=0); + const Value *SV, int SVOffset, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, MachineMemOperand *MMO); SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, - const Value *SV, int SVOffset, EVT TVT, - bool isVolatile=false, unsigned Alignment=0); + const Value *SV, int SVOffset, EVT TVT, + bool isNonTemporal, bool isVolatile, + unsigned Alignment); SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, EVT TVT, MachineMemOperand *MMO); SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base, @@ -841,7 +842,7 @@ public: } /// AssignOrdering - Assign an order to the SDNode. - void AssignOrdering(SDNode *SD, unsigned Order); + void AssignOrdering(const SDNode *SD, unsigned Order); /// GetOrdering - Get the order for the SDNode. unsigned GetOrdering(const SDNode *SD) const; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index b33b21d..0be91b4 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -85,11 +85,13 @@ public: return true; } - /// IsLegalAndProfitableToFold - Returns true if the specific operand node N of - /// U can be folded during instruction selection that starts at Root and - /// folding N is profitable. - virtual - bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const; + /// IsProfitableToFold - Returns true if it's profitable to fold the specific + /// operand node N of U during instruction selection that starts at Root. + virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const; + + /// IsLegalToFold - Returns true if the specific operand node N of + /// U can be folded during instruction selection that starts at Root. + virtual bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const; /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer /// to use for this target when scheduling the DAG. @@ -110,6 +112,25 @@ protected: bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS, int64_t DesiredMaskS) const; + + /// CheckPatternPredicate - This function is generated by tblgen in the + /// target. It runs the specified pattern predicate and returns true if it + /// succeeds or false if it fails. The number is a private implementation + /// detail to the code tblgen produces. + virtual bool CheckPatternPredicate(unsigned PredNo) const { + assert(0 && "Tblgen should generate the implementation of this!"); + return 0; + } + + /// CheckNodePredicate - This function is generated by tblgen in the + /// target. It runs node predicate #PredNo and returns true if it succeeds or + /// false if it fails. The number is a private implementation + /// detail to the code tblgen produces. + virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const { + assert(0 && "Tblgen should generate the implementation of this!"); + return 0; + } + // Calls to these functions are generated by tblgen. SDNode *Select_INLINEASM(SDNode *N); SDNode *Select_UNDEF(SDNode *N); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 45a9d40..df1f91b 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -609,7 +609,7 @@ namespace ISD { /// which do not reference a specific memory location should be less than /// this value. Those that do must not be less than this value, and can /// be used with SelectionDAG::getMemIntrinsicNode. - static const int FIRST_TARGET_MEMORY_OPCODE = 1 << 14; + static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+80; /// Node predicates @@ -821,6 +821,8 @@ public: /// set the SDNode void setNode(SDNode *N) { Node = N; } + inline SDNode *operator->() const { return Node; } + bool operator==(const SDValue &O) const { return Node == O.Node && ResNo == O.ResNo; } @@ -1594,6 +1596,7 @@ public: } bool isVolatile() const { return (SubclassData >> 5) & 1; } + bool isNonTemporal() const { return MMO->isNonTemporal(); } /// Returns the SrcValue and offset that describes the location of the access const Value *getSrcValue() const { return MMO->getValue(); } diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 163642a..dd4caba 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -72,10 +72,13 @@ namespace llvm { } } + bool isValid() const { + return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX); + } + MachineInstr* getInstr() const { return mi; } void setInstr(MachineInstr *mi) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to modify reserved index."); + assert(isValid() && "Attempt to modify reserved index."); this->mi = mi; } @@ -83,25 +86,21 @@ namespace llvm { void setIndex(unsigned index) { assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && "Attempt to set index to invalid value."); - assert(this->index != EMPTY_KEY_INDEX && - this->index != TOMBSTONE_KEY_INDEX && - "Attempt to reset reserved index value."); + assert(isValid() && "Attempt to reset reserved index value."); this->index = index; } IndexListEntry* getNext() { return next; } const IndexListEntry* getNext() const { return next; } void setNext(IndexListEntry *next) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to modify reserved index."); + assert(isValid() && "Attempt to modify reserved index."); this->next = next; } IndexListEntry* getPrev() { return prev; } const IndexListEntry* getPrev() const { return prev; } void setPrev(IndexListEntry *prev) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to modify reserved index."); + assert(isValid() && "Attempt to modify reserved index."); this->prev = prev; } @@ -192,7 +191,8 @@ namespace llvm { /// Returns true if this is a valid index. Invalid indicies do /// not point into an index table, and cannot be compared. bool isValid() const { - return (lie.getPointer() != 0) && (lie.getPointer()->getIndex() != 0); + IndexListEntry *entry = lie.getPointer(); + return ((entry!= 0) && (entry->isValid())); } /// Print this index to the given raw_ostream. diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h new file mode 100644 index 0000000..c5aa626 --- /dev/null +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -0,0 +1,202 @@ +//==-- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object Info -*- 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 classes used to handle lowerings specific to common +// object file formats. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H +#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/SectionKind.h" +#include "llvm/Target/TargetLoweringObjectFile.h" + +namespace llvm { + class MachineModuleInfo; + class Mangler; + class MCAsmInfo; + class MCExpr; + class MCSection; + class MCSectionMachO; + class MCSymbol; + class MCContext; + class GlobalValue; + class TargetMachine; + + +class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { + mutable void *UniquingMap; +protected: + /// TLSDataSection - Section directive for Thread Local data. + /// + const MCSection *TLSDataSection; // Defaults to ".tdata". + + /// TLSBSSSection - Section directive for Thread Local uninitialized data. + /// Null if this target doesn't support a BSS section. + /// + const MCSection *TLSBSSSection; // Defaults to ".tbss". + + const MCSection *DataRelSection; + const MCSection *DataRelLocalSection; + const MCSection *DataRelROSection; + const MCSection *DataRelROLocalSection; + + const MCSection *MergeableConst4Section; + const MCSection *MergeableConst8Section; + const MCSection *MergeableConst16Section; + +protected: + const MCSection *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, SectionKind Kind, + bool IsExplicit = false) const; +public: + TargetLoweringObjectFileELF() : UniquingMap(0) {} + ~TargetLoweringObjectFileELF(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + const MCSection *getDataRelSection() const { return DataRelSection; } + + /// getSectionForConstant - Given a constant with the SectionKind, return a + /// section that it should be placed in. + virtual const MCSection *getSectionForConstant(SectionKind Kind) const; + + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference + /// to the specified global variable from exception handling information. + /// + virtual const MCExpr * + getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding) const; +}; + + + +class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { + mutable void *UniquingMap; + + const MCSection *CStringSection; + const MCSection *UStringSection; + const MCSection *TextCoalSection; + const MCSection *ConstTextCoalSection; + const MCSection *ConstDataCoalSection; + const MCSection *ConstDataSection; + const MCSection *DataCoalSection; + const MCSection *DataCommonSection; + const MCSection *DataBSSSection; + const MCSection *FourByteConstantSection; + const MCSection *EightByteConstantSection; + const MCSection *SixteenByteConstantSection; + + const MCSection *LazySymbolPointerSection; + const MCSection *NonLazySymbolPointerSection; +public: + TargetLoweringObjectFileMachO() : UniquingMap(0) {} + ~TargetLoweringObjectFileMachO(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection *getSectionForConstant(SectionKind Kind) const; + + /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively + /// decide not to emit the UsedDirective for some symbols in llvm.used. + /// FIXME: REMOVE this (rdar://7071300) + virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, + Mangler *) const; + + /// getMachOSection - Return the MCSection for the specified mach-o section. + /// This requires the operands to be valid. + const MCSectionMachO *getMachOSection(StringRef Segment, + StringRef Section, + unsigned TypeAndAttributes, + SectionKind K) const { + return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); + } + const MCSectionMachO *getMachOSection(StringRef Segment, + StringRef Section, + unsigned TypeAndAttributes, + unsigned Reserved2, + SectionKind K) const; + + /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak + /// text symbols into. + const MCSection *getTextCoalSection() const { + return TextCoalSection; + } + + /// getConstTextCoalSection - Return the "__TEXT,__const_coal" section + /// we put weak read-only symbols into. + const MCSection *getConstTextCoalSection() const { + return ConstTextCoalSection; + } + + /// getLazySymbolPointerSection - Return the section corresponding to + /// the .lazy_symbol_pointer directive. + const MCSection *getLazySymbolPointerSection() const { + return LazySymbolPointerSection; + } + + /// getNonLazySymbolPointerSection - Return the section corresponding to + /// the .non_lazy_symbol_pointer directive. + const MCSection *getNonLazySymbolPointerSection() const { + return NonLazySymbolPointerSection; + } + + /// getSymbolForDwarfGlobalReference - The mach-o version of this method + /// defaults to returning a stub reference. + virtual const MCExpr * + getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding) const; +}; + + + +class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { + mutable void *UniquingMap; +public: + TargetLoweringObjectFileCOFF() : UniquingMap(0) {} + ~TargetLoweringObjectFileCOFF(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + /// getCOFFSection - Return the MCSection for the specified COFF section. + /// FIXME: Switch this to a semantic view eventually. + const MCSection *getCOFFSection(StringRef Name, bool isDirective, + SectionKind K) const; +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 0125190..a7aafc0 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -492,26 +492,31 @@ namespace llvm { /// bitsEq - Return true if this has the same number of bits as VT. bool bitsEq(EVT VT) const { + if (EVT::operator==(VT)) return true; return getSizeInBits() == VT.getSizeInBits(); } /// bitsGT - Return true if this has more bits than VT. bool bitsGT(EVT VT) const { + if (EVT::operator==(VT)) return false; return getSizeInBits() > VT.getSizeInBits(); } /// bitsGE - Return true if this has no less bits than VT. bool bitsGE(EVT VT) const { + if (EVT::operator==(VT)) return true; return getSizeInBits() >= VT.getSizeInBits(); } /// bitsLT - Return true if this has less bits than VT. bool bitsLT(EVT VT) const { + if (EVT::operator==(VT)) return false; return getSizeInBits() < VT.getSizeInBits(); } /// bitsLE - Return true if this has no more bits than VT. bool bitsLE(EVT VT) const { + if (EVT::operator==(VT)) return true; return getSizeInBits() <= VT.getSizeInBits(); } |