aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/CodeGen
diff options
context:
space:
mode:
authorDan Gohman <djg@cray.com>2007-07-18 16:29:46 +0000
committerDan Gohman <djg@cray.com>2007-07-18 16:29:46 +0000
commitf17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc (patch)
treeebb79ea1ee5e3bc1fdf38541a811a8b804f0679a /include/llvm/CodeGen
downloadexternal_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.zip
external_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.tar.gz
external_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.tar.bz2
It's not necessary to do rounding for alloca operations when the requested
alignment is equal to the stack alignment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40004 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h316
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h202
-rw-r--r--include/llvm/CodeGen/DwarfWriter.h82
-rw-r--r--include/llvm/CodeGen/ELFRelocation.h52
-rw-r--r--include/llvm/CodeGen/FileWriters.h32
-rw-r--r--include/llvm/CodeGen/IntrinsicLowering.h50
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h48
-rw-r--r--include/llvm/CodeGen/LiveInterval.h287
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h235
-rw-r--r--include/llvm/CodeGen/LiveVariables.h304
-rw-r--r--include/llvm/CodeGen/MachORelocation.h54
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h371
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h200
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h149
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h327
-rw-r--r--include/llvm/CodeGen/MachineFunction.h374
-rw-r--r--include/llvm/CodeGen/MachineFunctionPass.h50
-rw-r--r--include/llvm/CodeGen/MachineInstr.h567
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h147
-rw-r--r--include/llvm/CodeGen/MachineJumpTableInfo.h103
-rw-r--r--include/llvm/CodeGen/MachineLocation.h106
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h1280
-rw-r--r--include/llvm/CodeGen/MachinePassRegistry.h156
-rw-r--r--include/llvm/CodeGen/MachineRelocation.h298
-rw-r--r--include/llvm/CodeGen/Passes.h120
-rw-r--r--include/llvm/CodeGen/RegAllocRegistry.h64
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h148
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h109
-rw-r--r--include/llvm/CodeGen/SSARegMap.h55
-rw-r--r--include/llvm/CodeGen/SchedGraphCommon.h289
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h306
-rw-r--r--include/llvm/CodeGen/SchedulerRegistry.h71
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h524
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h194
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h1641
-rw-r--r--include/llvm/CodeGen/SimpleRegisterCoalescing.h160
-rw-r--r--include/llvm/CodeGen/ValueTypes.h284
-rw-r--r--include/llvm/CodeGen/ValueTypes.td52
38 files changed, 9807 insertions, 0 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
new file mode 100644
index 0000000..954b9bc
--- /dev/null
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -0,0 +1,316 @@
+//===-- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class to be used as the base class for target specific
+// asm writers. This class primarily handles common functionality used by
+// all asm writers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ASMPRINTER_H
+#define LLVM_CODEGEN_ASMPRINTER_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/DataTypes.h"
+#include <set>
+
+namespace llvm {
+ class Constant;
+ class ConstantArray;
+ class GlobalVariable;
+ class GlobalAlias;
+ class MachineConstantPoolEntry;
+ class MachineConstantPoolValue;
+ class Mangler;
+ class TargetAsmInfo;
+
+
+ /// AsmPrinter - This class is intended to be used as a driving class for all
+ /// asm writers.
+ 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;
+
+ protected:
+ // Necessary for external weak linkage support
+ std::set<const GlobalValue*> ExtWeakSymbols;
+
+ public:
+ /// Output stream on which we're printing assembly code.
+ ///
+ std::ostream &O;
+
+ /// Target machine description.
+ ///
+ TargetMachine &TM;
+
+ /// Target Asm Printer information.
+ ///
+ const TargetAsmInfo *TAI;
+
+ /// Name-mangler for global names.
+ ///
+ Mangler *Mang;
+
+ /// Cache of mangled name for current function. This is recalculated at the
+ /// beginning of each call to runOnMachineFunction().
+ ///
+ std::string CurrentFnName;
+
+ /// CurrentSection - The current section we are emitting to. This is
+ /// controlled and used by the SwitchSection method.
+ std::string CurrentSection;
+
+ protected:
+ AsmPrinter(std::ostream &o, TargetMachine &TM, const TargetAsmInfo *T);
+
+ public:
+ /// SwitchToTextSection - Switch to the specified section of the executable
+ /// if we are not already in it! If GV is non-null and if the global has an
+ /// explicitly requested section, we switch to the section indicated for the
+ /// global instead of NewSection.
+ ///
+ /// If the new section is an empty string, this method forgets what the
+ /// current section is, but does not emit a .section directive.
+ ///
+ /// This method is used when about to emit executable code.
+ ///
+ void SwitchToTextSection(const char *NewSection, const GlobalValue *GV = NULL);
+
+ /// SwitchToDataSection - Switch to the specified section of the executable
+ /// if we are not already in it! If GV is non-null and if the global has an
+ /// explicitly requested section, we switch to the section indicated for the
+ /// global instead of NewSection.
+ ///
+ /// If the new section is an empty string, this method forgets what the
+ /// current section is, but does not emit a .section directive.
+ ///
+ /// This method is used when about to emit data. For most assemblers, this
+ /// is the same as the SwitchToTextSection method, but not all assemblers
+ /// are the same.
+ ///
+ void SwitchToDataSection(const char *NewSection, const GlobalValue *GV = NULL);
+
+ /// getGlobalLinkName - Returns the asm/link name of of the specified
+ /// global variable. Should be overridden by each target asm printer to
+ /// generate the appropriate value.
+ virtual const std::string getGlobalLinkName(const GlobalVariable *GV) const;
+
+ /// EmitExternalGlobal - Emit the external reference to a global variable.
+ /// Should be overridden if an indirect reference should be used.
+ virtual void EmitExternalGlobal(const GlobalVariable *GV);
+
+ protected:
+ /// doInitialization - Set up the AsmPrinter when we are working on a new
+ /// module. If your pass overrides this, it must make sure to explicitly
+ /// call this implementation.
+ bool doInitialization(Module &M);
+
+ /// doFinalization - Shut down the asmprinter. If you override this in your
+ /// pass, you must make sure to call it explicitly.
+ bool doFinalization(Module &M);
+
+ /// PrintSpecial - Print information related to the specified machine instr
+ /// that is independent of the operand, and may be independent of the instr
+ /// itself. This can be useful for portably encoding the comment character
+ /// or other bits of target-specific knowledge into the asmstrings. The
+ /// syntax used is ${:comment}. Targets can override this to add support
+ /// for their own strange codes.
+ virtual void PrintSpecial(const MachineInstr *MI, const char *Code);
+
+ /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
+ /// instruction, using the specified assembler variant. Targets should
+ /// override this to format as appropriate. This method can return true if
+ /// the operand is erroneous.
+ virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode);
+
+ /// PrintAsmMemoryOperand - Print the specified operand of MI, an INLINEASM
+ /// instruction, using the specified assembler variant as an address.
+ /// Targets should override this to format as appropriate. This method can
+ /// return true if the operand is erroneous.
+ virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant,
+ const char *ExtraCode);
+
+ /// getSectionForFunction - Return the section that we should emit the
+ /// specified function body into. This defaults to 'TextSection'. This
+ /// should most likely be overridden by the target to put linkonce/weak
+ /// functions into special sections.
+ virtual std::string getSectionForFunction(const Function &F) const;
+
+ /// SetupMachineFunction - This should be called when a new MachineFunction
+ /// is being processed from runOnMachineFunction.
+ void SetupMachineFunction(MachineFunction &MF);
+
+ /// getFunctionNumber - Return a unique ID for the current function.
+ ///
+ unsigned getFunctionNumber() const { return FunctionNumber; }
+
+ /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should
+ /// not normally call this, as the counter is automatically bumped by
+ /// SetupMachineFunction.
+ void IncrementFunctionNumber() { FunctionNumber++; }
+
+ /// 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);
+
+ /// EmitJumpTableInfo - Print assembly representations of the jump tables
+ /// used by the current function to the current output stream.
+ ///
+ void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF);
+
+ /// EmitSpecialLLVMGlobal - Check to see if the specified global is a
+ /// special global used by LLVM. If so, emit it and return true, otherwise
+ /// do nothing and return false.
+ bool EmitSpecialLLVMGlobal(const GlobalVariable *GV);
+
+ public:
+ //===------------------------------------------------------------------===//
+ /// LEB 128 number encoding.
+
+ /// PrintULEB128 - Print a series of hexidecimal values(separated by commas)
+ /// representing an unsigned leb128 value.
+ void PrintULEB128(unsigned Value) const;
+
+ /// SizeULEB128 - Compute the number of bytes required for an unsigned
+ /// leb128 value.
+ static unsigned SizeULEB128(unsigned Value);
+
+ /// PrintSLEB128 - Print a series of hexidecimal values(separated by commas)
+ /// representing a signed leb128 value.
+ void PrintSLEB128(int Value) const;
+
+ /// SizeSLEB128 - Compute the number of bytes required for a signed leb128
+ /// value.
+ static unsigned SizeSLEB128(int Value);
+
+ //===------------------------------------------------------------------===//
+ // Emission and print routines
+ //
+
+ /// PrintHex - Print a value as a hexidecimal value.
+ ///
+ void PrintHex(int Value) const;
+
+ /// EOL - Print a newline character to asm stream. If a comment is present
+ /// then it will be printed first. Comments should not contain '\n'.
+ void EOL() const;
+ void EOL(const std::string &Comment) const;
+
+ /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
+ /// unsigned leb128 value.
+ void EmitULEB128Bytes(unsigned Value) const;
+
+ /// EmitSLEB128Bytes - print an assembler byte data directive to compose a
+ /// signed leb128 value.
+ void EmitSLEB128Bytes(int Value) const;
+
+ /// EmitInt8 - Emit a byte directive and value.
+ ///
+ void EmitInt8(int Value) const;
+
+ /// EmitInt16 - Emit a short directive and value.
+ ///
+ void EmitInt16(int Value) const;
+
+ /// EmitInt32 - Emit a long directive and value.
+ ///
+ void EmitInt32(int Value) const;
+
+ /// EmitInt64 - Emit a long long directive and value.
+ ///
+ void EmitInt64(uint64_t Value) const;
+
+ /// EmitString - Emit a string with quotes and a null terminator.
+ /// Special characters are emitted properly.
+ /// \literal (Eg. '\t') \endliteral
+ void EmitString(const std::string &String) const;
+
+ //===------------------------------------------------------------------===//
+
+ /// EmitAlignment - Emit an alignment directive to the specified power of
+ /// two boundary. For example, if you pass in 3 here, you will get an 8
+ /// byte alignment. If a global value is specified, and if that global has
+ /// an explicit alignment requested, it will unconditionally override the
+ /// alignment request. However, if ForcedAlignBits is specified, this value
+ /// has final say: the ultimate alignment will be the max of ForcedAlignBits
+ /// and the alignment computed with NumBits and the global.
+ ///
+ /// The algorithm is:
+ /// Align = NumBits;
+ /// if (GV && GV->hasalignment) Align = GV->getalignment();
+ /// Align = std::max(Align, ForcedAlignBits);
+ ///
+ void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0,
+ unsigned ForcedAlignBits = 0) const;
+
+ protected:
+ /// EmitZeros - Emit a block of zeros.
+ ///
+ void EmitZeros(uint64_t NumZeros) const;
+
+ /// EmitString - Emit a zero-byte-terminated string constant.
+ ///
+ virtual void EmitString(const ConstantArray *CVA) const;
+
+ /// EmitConstantValueOnly - Print out the specified constant, without a
+ /// storage class. Only constants of first-class type are allowed here.
+ void EmitConstantValueOnly(const Constant *CV);
+
+ /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
+ ///
+ void EmitGlobalConstant(const Constant* CV);
+
+ virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
+
+ /// printInlineAsm - This method formats and prints the specified machine
+ /// instruction that is an inline asm.
+ void printInlineAsm(const MachineInstr *MI) const;
+
+ /// printLabel - This method prints a local label used by debug and
+ /// exception handling tables.
+ void printLabel(const MachineInstr *MI) const;
+
+ /// printBasicBlockLabel - This method prints the label for the specified
+ /// MachineBasicBlock
+ virtual void printBasicBlockLabel(const MachineBasicBlock *MBB,
+ bool printColon = false,
+ bool printComment = true) const;
+
+ /// printSetLabel - This method prints a set label for the specified
+ /// MachineBasicBlock
+ void printSetLabel(unsigned uid, const MachineBasicBlock *MBB) const;
+ void printSetLabel(unsigned uid, unsigned uid2,
+ const MachineBasicBlock *MBB) const;
+
+ /// printDataDirective - This method prints the asm directive for the
+ /// specified type.
+ void printDataDirective(const Type *type);
+
+ private:
+ void EmitLLVMUsedList(Constant *List);
+ void EmitXXStructorList(Constant *List);
+ void EmitConstantPool(unsigned Alignment, const char *Section,
+ std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP);
+
+ };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
new file mode 100644
index 0000000..959d052
--- /dev/null
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -0,0 +1,202 @@
+//===-- llvm/CallingConvLower.h - Calling Conventions -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the CCState and CCValAssign classes, used for lowering
+// and implementing calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H
+#define LLVM_CODEGEN_CALLINGCONVLOWER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/ValueTypes.h"
+
+namespace llvm {
+ class MRegisterInfo;
+ class TargetMachine;
+ class CCState;
+ class SDNode;
+
+/// CCValAssign - Represent assignment of one arg/retval to a location.
+class CCValAssign {
+public:
+ enum LocInfo {
+ Full, // The value fills the full location.
+ SExt, // The value is sign extended in the location.
+ ZExt, // The value is zero extended in the location.
+ AExt // The value is extended with undefined upper bits.
+ // TODO: a subset of the value is in the location.
+ };
+private:
+ /// ValNo - This is the value number begin assigned (e.g. an argument number).
+ unsigned ValNo;
+
+ /// Loc is either a stack offset or a register number.
+ unsigned Loc;
+
+ /// isMem - True if this is a memory loc, false if it is a register loc.
+ bool isMem : 1;
+
+ /// Information about how the value is assigned.
+ LocInfo HTP : 7;
+
+ /// ValVT - The type of the value being assigned.
+ MVT::ValueType ValVT;
+
+ /// LocVT - The type of the location being assigned to.
+ MVT::ValueType LocVT;
+public:
+
+ static CCValAssign getReg(unsigned ValNo, MVT::ValueType ValVT,
+ unsigned RegNo, MVT::ValueType LocVT,
+ LocInfo HTP) {
+ CCValAssign Ret;
+ Ret.ValNo = ValNo;
+ Ret.Loc = RegNo;
+ Ret.isMem = false;
+ Ret.HTP = HTP;
+ Ret.ValVT = ValVT;
+ Ret.LocVT = LocVT;
+ return Ret;
+ }
+ static CCValAssign getMem(unsigned ValNo, MVT::ValueType ValVT,
+ unsigned Offset, MVT::ValueType LocVT,
+ LocInfo HTP) {
+ CCValAssign Ret;
+ Ret.ValNo = ValNo;
+ Ret.Loc = Offset;
+ Ret.isMem = true;
+ Ret.HTP = HTP;
+ Ret.ValVT = ValVT;
+ Ret.LocVT = LocVT;
+ return Ret;
+ }
+
+ unsigned getValNo() const { return ValNo; }
+ MVT::ValueType getValVT() const { return ValVT; }
+
+ bool isRegLoc() const { return !isMem; }
+ bool isMemLoc() const { return isMem; }
+
+ unsigned getLocReg() const { assert(isRegLoc()); return Loc; }
+ unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; }
+ MVT::ValueType getLocVT() const { return LocVT; }
+
+ LocInfo getLocInfo() const { return HTP; }
+};
+
+
+/// CCAssignFn - This function assigns a location for Val, updating State to
+/// reflect the change.
+typedef bool CCAssignFn(unsigned ValNo, MVT::ValueType ValVT,
+ MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,
+ unsigned ArgFlags, CCState &State);
+
+
+/// CCState - This class holds information needed while lowering arguments and
+/// return values. It captures which registers are already assigned and which
+/// stack slots are used. It provides accessors to allocate these values.
+class CCState {
+ unsigned CallingConv;
+ bool IsVarArg;
+ const TargetMachine &TM;
+ const MRegisterInfo &MRI;
+ SmallVector<CCValAssign, 16> &Locs;
+
+ unsigned StackOffset;
+ SmallVector<uint32_t, 16> UsedRegs;
+public:
+ CCState(unsigned CC, bool isVarArg, const TargetMachine &TM,
+ SmallVector<CCValAssign, 16> &locs);
+
+ void addLoc(const CCValAssign &V) {
+ Locs.push_back(V);
+ }
+
+ const TargetMachine &getTarget() const { return TM; }
+ unsigned getCallingConv() const { return CallingConv; }
+ bool isVarArg() const { return IsVarArg; }
+
+ unsigned getNextStackOffset() const { return StackOffset; }
+
+ /// isAllocated - Return true if the specified register (or an alias) is
+ /// allocated.
+ bool isAllocated(unsigned Reg) const {
+ return UsedRegs[Reg/32] & (1 << (Reg&31));
+ }
+
+ /// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node,
+ /// incorporating info about the formals into this state.
+ void AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn);
+
+ /// AnalyzeReturn - Analyze the returned values of an ISD::RET node,
+ /// incorporating info about the result values into this state.
+ void AnalyzeReturn(SDNode *TheRet, CCAssignFn Fn);
+
+ /// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info
+ /// about the passed values into this state.
+ void AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn);
+
+ /// AnalyzeCallResult - Analyze the return values of an ISD::CALL node,
+ /// incorporating info about the passed values into this state.
+ void AnalyzeCallResult(SDNode *TheCall, CCAssignFn Fn);
+
+
+ /// getFirstUnallocated - Return the first unallocated register in the set, or
+ /// NumRegs if they are all allocated.
+ unsigned getFirstUnallocated(const unsigned *Regs, unsigned NumRegs) const {
+ for (unsigned i = 0; i != NumRegs; ++i)
+ if (!isAllocated(Regs[i]))
+ return i;
+ return NumRegs;
+ }
+
+ /// AllocateReg - Attempt to allocate one register. If it is not available,
+ /// return zero. Otherwise, return the register, marking it and any aliases
+ /// as allocated.
+ unsigned AllocateReg(unsigned Reg) {
+ if (isAllocated(Reg)) return 0;
+ MarkAllocated(Reg);
+ return Reg;
+ }
+
+ /// AllocateReg - Attempt to allocate one of the specified registers. If none
+ /// are available, return zero. Otherwise, return the first one available,
+ /// marking it and any aliases as allocated.
+ unsigned AllocateReg(const unsigned *Regs, unsigned NumRegs) {
+ unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
+ if (FirstUnalloc == NumRegs)
+ return 0; // Didn't find the reg.
+
+ // Mark the register and any aliases as allocated.
+ unsigned Reg = Regs[FirstUnalloc];
+ MarkAllocated(Reg);
+ return Reg;
+ }
+
+ /// AllocateStack - Allocate a chunk of stack space with the specified size
+ /// and alignment.
+ unsigned AllocateStack(unsigned Size, unsigned Align) {
+ assert(Align && ((Align-1) & Align) == 0); // Align is power of 2.
+ StackOffset = ((StackOffset + Align-1) & ~(Align-1));
+ unsigned Result = StackOffset;
+ StackOffset += Size;
+ return Result;
+ }
+private:
+ /// MarkAllocated - Mark a register and all of its aliases as allocated.
+ void MarkAllocated(unsigned Reg);
+};
+
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
new file mode 100644
index 0000000..d5d6925
--- /dev/null
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -0,0 +1,82 @@
+//===-- llvm/CodeGen/DwarfWriter.h - Dwarf Framework ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing Dwarf debug and exception info into
+// asm files. For Details on the Dwarf 3 specfication see DWARF Debugging
+// Information Format V.3 reference manual http://dwarf.freestandards.org ,
+//
+// The role of the Dwarf Writer class is to extract information from the
+// MachineModuleInfo object, organize it in Dwarf form and then emit it into asm
+// the current asm file using data and high level Dwarf directives.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DWARFWRITER_H
+#define LLVM_CODEGEN_DWARFWRITER_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+class AsmPrinter;
+class DwarfDebug;
+class DwarfException;
+class MachineModuleInfo;
+class MachineFunction;
+class Module;
+class TargetAsmInfo;
+
+//===----------------------------------------------------------------------===//
+// DwarfWriter - Emits Dwarf debug and exception handling directives.
+//
+
+class DwarfWriter {
+private:
+ /// DD - Provides the DwarfWriter debug implementation.
+ ///
+ DwarfDebug *DD;
+
+ /// DE - Provides the DwarfWriter exception implementation.
+ ///
+ DwarfException *DE;
+
+public:
+
+ DwarfWriter(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T);
+ virtual ~DwarfWriter();
+
+ /// SetModuleInfo - Set machine module info when it's known that pass manager
+ /// has created it. Set by the target AsmPrinter.
+ void SetModuleInfo(MachineModuleInfo *MMI);
+
+ //===--------------------------------------------------------------------===//
+ // Main entry points.
+ //
+
+ /// BeginModule - Emit all Dwarf sections that should come prior to the
+ /// content.
+ void BeginModule(Module *M);
+
+ /// EndModule - Emit all Dwarf sections that should come after the content.
+ ///
+ void EndModule();
+
+ /// BeginFunction - Gather pre-function debug information. Assumes being
+ /// emitted immediately after the function entry point.
+ void BeginFunction(MachineFunction *MF);
+
+ /// EndFunction - Gather and emit post-function debug information.
+ ///
+ void EndFunction();
+};
+
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ELFRelocation.h b/include/llvm/CodeGen/ELFRelocation.h
new file mode 100644
index 0000000..1c0b3e9
--- /dev/null
+++ b/include/llvm/CodeGen/ELFRelocation.h
@@ -0,0 +1,52 @@
+//=== ELFRelocation.h - ELF Relocation Info ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Christopher Lamb and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ELFRelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ELF_RELOCATION_H
+#define LLVM_CODEGEN_ELF_RELOCATION_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+ /// ELFRelocation - This class contains all the information necessary to
+ /// to generate any 32-bit or 64-bit ELF relocation entry.
+ class ELFRelocation {
+ uint64_t r_offset; // offset in the section of the object this applies to
+ uint32_t r_symidx; // symbol table index of the symbol to use
+ uint32_t r_type; // machine specific relocation type
+ int64_t r_add; // explicit relocation addend
+ bool r_rela; // if true then the addend is part of the entry
+ // otherwise the addend is at the location specified
+ // by r_offset
+ public:
+
+ uint64_t getInfo(bool is64Bit = false) const {
+ if (is64Bit)
+ return ((uint64_t)r_symidx << 32) + ((uint64_t)r_type & 0xFFFFFFFFL);
+ else
+ return (r_symidx << 8) + (r_type & 0xFFL);
+ }
+
+ uint64_t getOffset() const { return r_offset; }
+ uint64_t getAddress() const { return r_add; }
+
+ ELFRelocation(uint64_t off, uint32_t sym, uint32_t type,
+ bool rela = true, int64_t addend = 0) :
+ r_offset(off), r_symidx(sym), r_type(type),
+ r_add(addend), r_rela(rela) {}
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_CODEGEN_ELF_RELOCATION_H
+
diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h
new file mode 100644
index 0000000..6baa89f
--- /dev/null
+++ b/include/llvm/CodeGen/FileWriters.h
@@ -0,0 +1,32 @@
+//===-- FileWriters.h - File Writers Creation Functions ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and 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
+
+#include <iosfwd>
+
+namespace llvm {
+
+ class FunctionPassManager;
+ class MachineCodeEmitter;
+ class TargetMachine;
+
+ MachineCodeEmitter *AddELFWriter(FunctionPassManager &FPM, std::ostream &O,
+ TargetMachine &TM);
+ MachineCodeEmitter *AddMachOWriter(FunctionPassManager &FPM, std::ostream &O,
+ TargetMachine &TM);
+
+} // end llvm namespace
+
+#endif // LLVM_CODEGEN_FILEWRITERS_H
diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h
new file mode 100644
index 0000000..bff1b39
--- /dev/null
+++ b/include/llvm/CodeGen/IntrinsicLowering.h
@@ -0,0 +1,50 @@
+//===-- IntrinsicLowering.h - Intrinsic Function Lowering -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the IntrinsicLowering interface. This interface allows
+// addition of domain-specific or front-end specific intrinsics to LLVM without
+// having to modify all of the C backend or interpreter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_INTRINSICLOWERING_H
+#define LLVM_CODEGEN_INTRINSICLOWERING_H
+
+#include "llvm/Intrinsics.h"
+
+namespace llvm {
+ class CallInst;
+ class Module;
+ class TargetData;
+
+ class IntrinsicLowering {
+ const TargetData& TD;
+ public:
+ explicit IntrinsicLowering(const TargetData &td) : TD(td) {}
+
+ /// AddPrototypes - This method, if called, causes all of the prototypes
+ /// that might be needed by an intrinsic lowering implementation to be
+ /// inserted into the module specified.
+ void AddPrototypes(Module &M);
+
+ /// LowerIntrinsicCall - This method replaces a call with the LLVM function
+ /// which should be used to implement the specified intrinsic function call.
+ /// If an intrinsic function must be implemented by the code generator
+ /// (such as va_start), this function should print a message and abort.
+ ///
+ /// Otherwise, if an intrinsic function call can be lowered, the code to
+ /// implement it (often a call to a non-intrinsic function) is inserted
+ /// _after_ the call instruction and the call is deleted. The caller must
+ /// be capable of handling this kind of change.
+ ///
+ void LowerIntrinsicCall(CallInst *CI);
+ };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
new file mode 100644
index 0000000..15021c1
--- /dev/null
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -0,0 +1,48 @@
+//===- llvm/Codegen/LinkAllCodegenComponents.h ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all codegen related passes for tools like lli and
+// llc that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+#define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+
+namespace {
+ struct ForceCodegenLinking {
+ ForceCodegenLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ (void) llvm::createSimpleRegisterAllocator();
+ (void) llvm::createLocalRegisterAllocator();
+ (void) llvm::createBigBlockRegisterAllocator();
+ (void) llvm::createLinearScanRegisterAllocator();
+
+ (void) llvm::createBFS_DAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createSimpleDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createNoItinsDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createTDRRListDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createTDListDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createDefaultScheduler(NULL, NULL, NULL);
+
+ }
+ } ForceCodegenLinking; // Force link by creating a global definition.
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
new file mode 100644
index 0000000..1912d64
--- /dev/null
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -0,0 +1,287 @@
+//===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveRange and LiveInterval classes. Given some
+// numbering of each the machine instructions an interval [i, j) is said to be a
+// live interval for register v if there is no instruction with number j' > j
+// such that v is live at j' and there is no instruction with number i' < i such
+// that v is live at i'. In this implementation intervals can have holes,
+// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
+// individual range is represented as an instance of LiveRange, and the whole
+// interval is represented as an instance of LiveInterval.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
+#define LLVM_CODEGEN_LIVEINTERVAL_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Streams.h"
+#include <iosfwd>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ class MachineInstr;
+ class MRegisterInfo;
+
+ /// LiveRange structure - This represents a simple register range in the
+ /// program, with an inclusive start point and an exclusive end point.
+ /// These ranges are rendered as [start,end).
+ struct LiveRange {
+ unsigned start; // Start point of the interval (inclusive)
+ unsigned end; // End point of the interval (exclusive)
+ unsigned ValId; // identifier for the value contained in this interval.
+
+ LiveRange(unsigned S, unsigned E, unsigned V) : start(S), end(E), ValId(V) {
+ assert(S < E && "Cannot create empty or backwards range");
+ }
+
+ /// contains - Return true if the index is covered by this range.
+ ///
+ bool contains(unsigned I) const {
+ return start <= I && I < end;
+ }
+
+ bool operator<(const LiveRange &LR) const {
+ return start < LR.start || (start == LR.start && end < LR.end);
+ }
+ bool operator==(const LiveRange &LR) const {
+ return start == LR.start && end == LR.end;
+ }
+
+ void dump() const;
+ void print(std::ostream &os) const;
+ void print(std::ostream *os) const { if (os) print(*os); }
+
+ private:
+ LiveRange(); // DO NOT IMPLEMENT
+ };
+
+ std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
+
+
+ inline bool operator<(unsigned V, const LiveRange &LR) {
+ return V < LR.start;
+ }
+
+ inline bool operator<(const LiveRange &LR, unsigned V) {
+ return LR.start < V;
+ }
+
+ /// LiveInterval - This class represents some number of live ranges for a
+ /// register or value. This class also contains a bit of register allocator
+ /// state.
+ struct LiveInterval {
+ typedef SmallVector<LiveRange,4> Ranges;
+ unsigned reg; // the register of this interval
+ unsigned preference; // preferred register to allocate for this interval
+ float weight; // weight of this interval
+ MachineInstr* remat; // definition if the definition rematerializable
+ Ranges ranges; // the ranges in which this register is live
+ private:
+ /// ValueNumberInfo - If this value number is not defined by a copy, this
+ /// holds ~0,x. If the value number is not in use, it contains ~1,x to
+ /// indicate that the value # is not used. If the val# is defined by a
+ /// copy, the first entry is the instruction # of the copy, and the second
+ /// is the register number copied from.
+ SmallVector<std::pair<unsigned,unsigned>, 4> ValueNumberInfo;
+ public:
+
+ LiveInterval(unsigned Reg, float Weight)
+ : reg(Reg), preference(0), weight(Weight), remat(NULL) {
+ }
+
+ typedef Ranges::iterator iterator;
+ iterator begin() { return ranges.begin(); }
+ iterator end() { return ranges.end(); }
+
+ typedef Ranges::const_iterator const_iterator;
+ const_iterator begin() const { return ranges.begin(); }
+ const_iterator end() const { return ranges.end(); }
+
+
+ /// 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
+ /// LiveRange immediately after the hole.
+ iterator advanceTo(iterator I, unsigned Pos) {
+ if (Pos >= endNumber())
+ return end();
+ while (I->end <= Pos) ++I;
+ return I;
+ }
+
+ void swap(LiveInterval& other) {
+ std::swap(reg, other.reg);
+ std::swap(weight, other.weight);
+ std::swap(remat, other.remat);
+ std::swap(ranges, other.ranges);
+ std::swap(ValueNumberInfo, other.ValueNumberInfo);
+ }
+
+ bool containsOneValue() const { return ValueNumberInfo.size() == 1; }
+
+ unsigned getNumValNums() const { return ValueNumberInfo.size(); }
+
+ /// getNextValue - Create a new value number and return it. MIIdx specifies
+ /// the instruction that defines the value number.
+ unsigned getNextValue(unsigned MIIdx, unsigned SrcReg) {
+ ValueNumberInfo.push_back(std::make_pair(MIIdx, SrcReg));
+ return ValueNumberInfo.size()-1;
+ }
+
+ /// getInstForValNum - Return the machine instruction index that defines the
+ /// specified value number.
+ unsigned getInstForValNum(unsigned ValNo) const {
+ //assert(ValNo < ValueNumberInfo.size());
+ return ValueNumberInfo[ValNo].first;
+ }
+
+ unsigned getSrcRegForValNum(unsigned ValNo) const {
+ //assert(ValNo < ValueNumberInfo.size());
+ if (ValueNumberInfo[ValNo].first < ~2U)
+ return ValueNumberInfo[ValNo].second;
+ return 0;
+ }
+
+ std::pair<unsigned, unsigned> getValNumInfo(unsigned ValNo) const {
+ //assert(ValNo < ValueNumberInfo.size());
+ return ValueNumberInfo[ValNo];
+ }
+
+ /// setValueNumberInfo - Change the value number info for the specified
+ /// value number.
+ void setValueNumberInfo(unsigned ValNo,
+ const std::pair<unsigned, unsigned> &I){
+ ValueNumberInfo[ValNo] = I;
+ }
+
+ /// MergeValueNumberInto - This method is called when two value nubmers
+ /// are found to be equivalent. This eliminates V1, replacing all
+ /// LiveRanges with the V1 value number with the V2 value number. This can
+ /// cause merging of V1/V2 values numbers and compaction of the value space.
+ void MergeValueNumberInto(unsigned V1, unsigned V2);
+
+ /// MergeInClobberRanges - For any live ranges that are not defined in the
+ /// current interval, but are defined in the Clobbers interval, mark them
+ /// used with an unknown definition value.
+ void MergeInClobberRanges(const LiveInterval &Clobbers);
+
+
+ /// MergeRangesInAsValue - Merge all of the intervals in RHS into this live
+ /// interval as the specified value number. The LiveRanges in RHS are
+ /// allowed to overlap with LiveRanges in the current interval, but only if
+ /// the overlapping LiveRanges have the specified value number.
+ void MergeRangesInAsValue(const LiveInterval &RHS, unsigned LHSValNo);
+
+ bool empty() const { return ranges.empty(); }
+
+ /// beginNumber - Return the lowest numbered slot covered by interval.
+ unsigned beginNumber() const {
+ assert(!empty() && "empty interval for register");
+ return ranges.front().start;
+ }
+
+ /// endNumber - return the maximum point of the interval of the whole,
+ /// exclusive.
+ unsigned endNumber() const {
+ assert(!empty() && "empty interval for register");
+ return ranges.back().end;
+ }
+
+ bool expiredAt(unsigned index) const {
+ return index >= endNumber();
+ }
+
+ bool liveAt(unsigned index) const;
+
+ /// getLiveRangeContaining - Return the live range that contains the
+ /// specified index, or null if there is none.
+ const LiveRange *getLiveRangeContaining(unsigned Idx) const {
+ const_iterator I = FindLiveRangeContaining(Idx);
+ return I == end() ? 0 : &*I;
+ }
+
+ /// FindLiveRangeContaining - Return an iterator to the live range that
+ /// contains the specified index, or end() if there is none.
+ const_iterator FindLiveRangeContaining(unsigned Idx) const;
+
+ /// FindLiveRangeContaining - Return an iterator to the live range that
+ /// contains the specified index, or end() if there is none.
+ iterator FindLiveRangeContaining(unsigned Idx);
+
+ /// getOverlapingRanges - Given another live interval which is defined as a
+ /// copy from this one, return a list of all of the live ranges where the
+ /// two overlap and have different value numbers.
+ void getOverlapingRanges(const LiveInterval &Other, unsigned CopyIdx,
+ std::vector<LiveRange*> &Ranges);
+
+ /// overlaps - Return true if the intersection of the two live intervals is
+ /// not empty.
+ bool overlaps(const LiveInterval& other) const {
+ return overlapsFrom(other, other.begin());
+ }
+
+ /// overlapsFrom - Return true if the intersection of the two live intervals
+ /// is not empty. The specified iterator is a hint that we can begin
+ /// scanning the Other interval starting at I.
+ bool overlapsFrom(const LiveInterval& other, const_iterator I) const;
+
+ /// addRange - Add the specified LiveRange to this interval, merging
+ /// intervals as appropriate. This returns an iterator to the inserted live
+ /// range (which may have grown since it was inserted.
+ void addRange(LiveRange LR) {
+ addRangeFrom(LR, ranges.begin());
+ }
+
+ /// join - Join two live intervals (this, and other) together. This applies
+ /// mappings to the value numbers in the LHS/RHS intervals as specified. If
+ /// the intervals are not joinable, this aborts.
+ void join(LiveInterval &Other, int *ValNoAssignments,
+ int *RHSValNoAssignments,
+ SmallVector<std::pair<unsigned,unsigned>,16> &NewValueNumberInfo);
+
+ /// removeRange - Remove the specified range from this interval. Note that
+ /// the range must already be in this interval in its entirety.
+ void removeRange(unsigned Start, unsigned End);
+
+ void removeRange(LiveRange LR) {
+ removeRange(LR.start, LR.end);
+ }
+
+ /// getSize - Returns the sum of sizes of all the LiveRange's.
+ ///
+ unsigned getSize() const;
+
+ bool operator<(const LiveInterval& other) const {
+ return beginNumber() < other.beginNumber();
+ }
+
+ void print(std::ostream &OS, const MRegisterInfo *MRI = 0) const;
+ void print(std::ostream *OS, const MRegisterInfo *MRI = 0) const {
+ if (OS) print(*OS, MRI);
+ }
+ void dump() const;
+
+ private:
+ Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
+ void extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd);
+ Ranges::iterator extendIntervalStartTo(Ranges::iterator I, unsigned NewStr);
+ LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
+ };
+
+ inline std::ostream &operator<<(std::ostream &OS, const LiveInterval &LI) {
+ LI.print(OS);
+ return OS;
+ }
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
new file mode 100644
index 0000000..4783df4
--- /dev/null
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -0,0 +1,235 @@
+//===-- LiveIntervalAnalysis.h - Live Interval Analysis ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveInterval analysis pass. Given some numbering of
+// each the machine instructions (in this implemention depth-first order) an
+// interval [i, j) is said to be a live interval for register v if there is no
+// instruction with number j' > j such that v is live at j' abd there is no
+// instruction with number i' < i such that v is live at i'. In this
+// implementation intervals can have holes, i.e. an interval might look like
+// [1,20), [50,65), [1000,1001).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IndexedMap.h"
+
+namespace llvm {
+
+ class LiveVariables;
+ class MRegisterInfo;
+ class TargetInstrInfo;
+ class TargetRegisterClass;
+ class VirtRegMap;
+
+ class LiveIntervals : public MachineFunctionPass {
+ MachineFunction* mf_;
+ const TargetMachine* tm_;
+ const MRegisterInfo* mri_;
+ const TargetInstrInfo* tii_;
+ LiveVariables* lv_;
+
+ /// MBB2IdxMap - The index of the first instruction in the specified basic
+ /// block.
+ std::vector<unsigned> MBB2IdxMap;
+
+ typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
+ Mi2IndexMap mi2iMap_;
+
+ typedef std::vector<MachineInstr*> Index2MiMap;
+ Index2MiMap i2miMap_;
+
+ typedef std::map<unsigned, LiveInterval> Reg2IntervalMap;
+ Reg2IntervalMap r2iMap_;
+
+ BitVector allocatableRegs_;
+
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ LiveIntervals() : MachineFunctionPass((intptr_t)&ID) {}
+
+ struct InstrSlots {
+ enum {
+ LOAD = 0,
+ USE = 1,
+ DEF = 2,
+ STORE = 3,
+ NUM = 4
+ };
+ };
+
+ static unsigned getBaseIndex(unsigned index) {
+ return index - (index % InstrSlots::NUM);
+ }
+ static unsigned getBoundaryIndex(unsigned index) {
+ return getBaseIndex(index + InstrSlots::NUM - 1);
+ }
+ static unsigned getLoadIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::LOAD;
+ }
+ static unsigned getUseIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::USE;
+ }
+ static unsigned getDefIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::DEF;
+ }
+ static unsigned getStoreIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::STORE;
+ }
+
+ typedef Reg2IntervalMap::iterator iterator;
+ typedef Reg2IntervalMap::const_iterator const_iterator;
+ const_iterator begin() const { return r2iMap_.begin(); }
+ const_iterator end() const { return r2iMap_.end(); }
+ iterator begin() { return r2iMap_.begin(); }
+ iterator end() { return r2iMap_.end(); }
+ unsigned getNumIntervals() const { return r2iMap_.size(); }
+
+ LiveInterval &getInterval(unsigned reg) {
+ Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+ assert(I != r2iMap_.end() && "Interval does not exist for register");
+ return I->second;
+ }
+
+ const LiveInterval &getInterval(unsigned reg) const {
+ Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
+ assert(I != r2iMap_.end() && "Interval does not exist for register");
+ return I->second;
+ }
+
+ bool hasInterval(unsigned reg) const {
+ return r2iMap_.count(reg);
+ }
+
+ /// getMBBStartIdx - Return the base index of the first instruction in the
+ /// specified MachineBasicBlock.
+ unsigned getMBBStartIdx(MachineBasicBlock *MBB) const {
+ return getMBBStartIdx(MBB->getNumber());
+ }
+
+ unsigned getMBBStartIdx(unsigned MBBNo) const {
+ assert(MBBNo < MBB2IdxMap.size() && "Invalid MBB number!");
+ return MBB2IdxMap[MBBNo];
+ }
+
+ /// getInstructionIndex - returns the base index of instr
+ unsigned getInstructionIndex(MachineInstr* instr) const {
+ Mi2IndexMap::const_iterator it = mi2iMap_.find(instr);
+ assert(it != mi2iMap_.end() && "Invalid instruction!");
+ return it->second;
+ }
+
+ /// getInstructionFromIndex - given an index in any slot of an
+ /// instruction return a pointer the instruction
+ MachineInstr* getInstructionFromIndex(unsigned index) const {
+ index /= InstrSlots::NUM; // convert index to vector index
+ assert(index < i2miMap_.size() &&
+ "index does not correspond to an instruction");
+ return i2miMap_[index];
+ }
+
+ // Interval creation
+
+ LiveInterval &getOrCreateInterval(unsigned reg) {
+ Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+ if (I == r2iMap_.end())
+ I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg)));
+ return I->second;
+ }
+
+ /// CreateNewLiveInterval - Create a new live interval with the given live
+ /// ranges. The new live interval will have an infinite spill weight.
+ LiveInterval &CreateNewLiveInterval(const LiveInterval *LI,
+ const std::vector<LiveRange> &LRs);
+
+ std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
+ VirtRegMap& vrm,
+ int slot);
+
+ // Interval removal
+
+ void removeInterval(unsigned Reg) {
+ r2iMap_.erase(Reg);
+ }
+
+ /// isRemoved - returns true if the specified machine instr has been
+ /// removed.
+ bool isRemoved(MachineInstr* instr) const {
+ return !mi2iMap_.count(instr);
+ }
+
+ /// RemoveMachineInstrFromMaps - This marks the specified machine instr as
+ /// deleted.
+ void RemoveMachineInstrFromMaps(MachineInstr *MI) {
+ // remove index -> MachineInstr and
+ // MachineInstr -> index mappings
+ Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI);
+ if (mi2i != mi2iMap_.end()) {
+ i2miMap_[mi2i->second/InstrSlots::NUM] = 0;
+ mi2iMap_.erase(mi2i);
+ }
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+
+ /// runOnMachineFunction - pass entry point
+ virtual bool runOnMachineFunction(MachineFunction&);
+
+ /// print - Implement the dump method.
+ virtual void print(std::ostream &O, const Module* = 0) const;
+ void print(std::ostream *O, const Module* M = 0) const {
+ if (O) print(*O, M);
+ }
+
+ private:
+ /// computeIntervals - Compute live intervals.
+ void computeIntervals();
+
+ /// handleRegisterDef - update intervals for a register def
+ /// (calls handlePhysicalRegisterDef and
+ /// handleVirtualRegisterDef)
+ void handleRegisterDef(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator MI, unsigned MIIdx,
+ unsigned reg);
+
+ /// handleVirtualRegisterDef - update intervals for a virtual
+ /// register def
+ void handleVirtualRegisterDef(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned MIIdx,
+ LiveInterval& interval);
+
+ /// handlePhysicalRegisterDef - update intervals for a physical register
+ /// def.
+ void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
+ MachineBasicBlock::iterator mi,
+ unsigned MIIdx,
+ LiveInterval &interval,
+ unsigned SrcReg);
+
+ /// handleLiveInRegister - Create interval for a livein register.
+ void handleLiveInRegister(MachineBasicBlock* mbb,
+ unsigned MIIdx,
+ LiveInterval &interval, bool isAlias = false);
+
+ static LiveInterval createInterval(unsigned Reg);
+
+ void printRegName(unsigned reg) const;
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
new file mode 100644
index 0000000..ec01556
--- /dev/null
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -0,0 +1,304 @@
+//===-- llvm/CodeGen/LiveVariables.h - Live Variable Analysis ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveVariable analysis pass. For each machine
+// instruction in the function, this pass calculates the set of registers that
+// are immediately dead after the instruction (i.e., the instruction calculates
+// the value, but it is never used) and the set of registers that are used by
+// the instruction, but are never used after the instruction (i.e., they are
+// killed).
+//
+// This class computes live variables using are sparse implementation based on
+// the machine code SSA form. This class computes live variable information for
+// each virtual and _register allocatable_ physical register in a function. It
+// uses the dominance properties of SSA form to efficiently compute live
+// variables for virtual registers, and assumes that physical registers are only
+// live within a single basic block (allowing it to do a single local analysis
+// to resolve physical register lifetimes in each basic block). If a physical
+// register is not register allocatable, it is not tracked. This is useful for
+// things like the stack pointer and condition codes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEVARIABLES_H
+#define LLVM_CODEGEN_LIVEVARIABLES_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include <map>
+
+namespace llvm {
+
+class MRegisterInfo;
+
+class LiveVariables : public MachineFunctionPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ LiveVariables() : MachineFunctionPass((intptr_t)&ID) {}
+
+ /// VarInfo - This represents the regions where a virtual register is live in
+ /// the program. We represent this with three different pieces of
+ /// information: the instruction that uniquely defines the value, the set of
+ /// blocks the instruction is live into and live out of, and the set of
+ /// non-phi instructions that are the last users of the value.
+ ///
+ /// In the common case where a value is defined and killed in the same block,
+ /// DefInst is the defining inst, there is one killing instruction, and
+ /// AliveBlocks is empty.
+ ///
+ /// Otherwise, the value is live out of the block. If the value is live
+ /// across any blocks, these blocks are listed in AliveBlocks. Blocks where
+ /// the liveness range ends are not included in AliveBlocks, instead being
+ /// captured by the Kills set. In these blocks, the value is live into the
+ /// block (unless the value is defined and killed in the same block) and lives
+ /// until the specified instruction. Note that there cannot ever be a value
+ /// whose Kills set contains two instructions from the same basic block.
+ ///
+ /// PHI nodes complicate things a bit. If a PHI node is the last user of a
+ /// value in one of its predecessor blocks, it is not listed in the kills set,
+ /// but does include the predecessor block in the AliveBlocks set (unless that
+ /// block also defines the value). This leads to the (perfectly sensical)
+ /// situation where a value is defined in a block, and the last use is a phi
+ /// node in the successor. In this case, DefInst will be the defining
+ /// instruction, AliveBlocks is empty (the value is not live across any
+ /// blocks) and Kills is empty (phi nodes are not included). This is sensical
+ /// because the value must be live to the end of the block, but is not live in
+ /// any successor blocks.
+ struct VarInfo {
+ /// DefInst - The machine instruction that defines this register.
+ ///
+ MachineInstr *DefInst;
+
+ /// AliveBlocks - Set of blocks of which this value is alive completely
+ /// through. This is a bit set which uses the basic block number as an
+ /// index.
+ ///
+ BitVector AliveBlocks;
+
+ /// NumUses - Number of uses of this register across the entire function.
+ ///
+ unsigned NumUses;
+
+ /// Kills - List of MachineInstruction's which are the last use of this
+ /// virtual register (kill it) in their basic block.
+ ///
+ std::vector<MachineInstr*> Kills;
+
+ VarInfo() : DefInst(0), NumUses(0) {}
+
+ /// removeKill - Delete a kill corresponding to the specified
+ /// machine instruction. Returns true if there was a kill
+ /// corresponding to this instruction, false otherwise.
+ bool removeKill(MachineInstr *MI) {
+ for (std::vector<MachineInstr*>::iterator i = Kills.begin(),
+ e = Kills.end(); i != e; ++i)
+ if (*i == MI) {
+ Kills.erase(i);
+ return true;
+ }
+ return false;
+ }
+
+ void dump() const;
+ };
+
+private:
+ /// VirtRegInfo - This list is a mapping from virtual register number to
+ /// variable information. FirstVirtualRegister is subtracted from the virtual
+ /// register number before indexing into this list.
+ ///
+ std::vector<VarInfo> VirtRegInfo;
+
+ /// ReservedRegisters - This vector keeps track of which registers
+ /// are reserved register which are not allocatable by the target machine.
+ /// We can not track liveness for values that are in this set.
+ ///
+ BitVector ReservedRegisters;
+
+private: // Intermediate data structures
+ MachineFunction *MF;
+
+ const MRegisterInfo *RegInfo;
+
+ // PhysRegInfo - Keep track of which instruction was the last def/use of a
+ // physical register. This is a purely local property, because all physical
+ // register references as presumed dead across basic blocks.
+ MachineInstr **PhysRegInfo;
+
+ // PhysRegUsed - Keep track whether the physical register has been used after
+ // its last definition. This is local property.
+ bool *PhysRegUsed;
+
+ // PhysRegPartUse - Keep track of which instruction was the last partial use
+ // of a physical register (e.g. on X86 a def of EAX followed by a use of AX).
+ // This is a purely local property.
+ MachineInstr **PhysRegPartUse;
+
+ // PhysRegPartDef - Keep track of a list of instructions which "partially"
+ // defined the physical register (e.g. on X86 AX partially defines EAX).
+ // These are turned into use/mod/write if there is a use of the register
+ // later in the same block. This is local property.
+ SmallVector<MachineInstr*, 4> *PhysRegPartDef;
+
+ SmallVector<unsigned, 4> *PHIVarInfo;
+
+ /// addRegisterKilled - We have determined MI kills a register. Look for the
+ /// operand that uses it and mark it as IsKill. If AddIfNotFound is true,
+ /// add a implicit operand if it's not found. Returns true if the operand
+ /// exists / is added.
+ bool addRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false);
+
+ /// addRegisterDead - We have determined MI defined a register without a use.
+ /// Look for the operand that defines it and mark it as IsDead. If
+ /// AddIfNotFound is true, add a implicit operand if it's not found. Returns
+ /// true if the operand exists / is added.
+ bool addRegisterDead(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false);
+
+ void addRegisterKills(unsigned Reg, MachineInstr *MI,
+ SmallSet<unsigned, 4> &SubKills);
+
+ /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
+ /// uses. Pay special attention to the sub-register uses which may come below
+ /// the last use of the whole register.
+ bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI,
+ SmallSet<unsigned, 4> &SubKills);
+ bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI);
+ void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
+ void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
+
+ /// analyzePHINodes - Gather information about the PHI nodes in here. In
+ /// particular, we want to map the variable information of a virtual
+ /// register which is used in a PHI node. We map that to the BB the vreg
+ /// is coming from.
+ void analyzePHINodes(const MachineFunction& Fn);
+public:
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ /// KillsRegister - Return true if the specified instruction kills the
+ /// specified register.
+ bool KillsRegister(MachineInstr *MI, unsigned Reg) const;
+
+ /// RegisterDefIsDead - Return true if the specified instruction defines the
+ /// specified register, but that definition is dead.
+ bool RegisterDefIsDead(MachineInstr *MI, unsigned Reg) const;
+
+ /// ModifiesRegister - Return true if the specified instruction modifies the
+ /// specified register.
+ bool ModifiesRegister(MachineInstr *MI, unsigned Reg) const;
+
+ //===--------------------------------------------------------------------===//
+ // API to update live variable information
+
+ /// instructionChanged - When the address of an instruction changes, this
+ /// method should be called so that live variables can update its internal
+ /// data structures. This removes the records for OldMI, transfering them to
+ /// the records for NewMI.
+ void instructionChanged(MachineInstr *OldMI, MachineInstr *NewMI);
+
+ /// addVirtualRegisterKilled - Add information about the fact that the
+ /// specified register is killed after being used by the specified
+ /// instruction. If AddIfNotFound is true, add a implicit operand if it's
+ /// not found.
+ void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false) {
+ if (addRegisterKilled(IncomingReg, MI, AddIfNotFound))
+ getVarInfo(IncomingReg).Kills.push_back(MI);
+ }
+
+ /// removeVirtualRegisterKilled - Remove the specified virtual
+ /// register from the live variable information. Returns true if the
+ /// variable was marked as killed by the specified instruction,
+ /// false otherwise.
+ bool removeVirtualRegisterKilled(unsigned reg,
+ MachineBasicBlock *MBB,
+ MachineInstr *MI) {
+ if (!getVarInfo(reg).removeKill(MI))
+ return false;
+
+ bool Removed = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isUse() && MO.getReg() == reg) {
+ MO.unsetIsKill();
+ Removed = true;
+ break;
+ }
+ }
+
+ assert(Removed && "Register is not used by this instruction!");
+ return true;
+ }
+
+ /// removeVirtualRegistersKilled - Remove all killed info for the specified
+ /// instruction.
+ void removeVirtualRegistersKilled(MachineInstr *MI);
+
+ /// addVirtualRegisterDead - Add information about the fact that the specified
+ /// register is dead after being used by the specified instruction. If
+ /// AddIfNotFound is true, add a implicit operand if it's not found.
+ void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false) {
+ if (addRegisterDead(IncomingReg, MI, AddIfNotFound))
+ getVarInfo(IncomingReg).Kills.push_back(MI);
+ }
+
+ /// removeVirtualRegisterDead - Remove the specified virtual
+ /// register from the live variable information. Returns true if the
+ /// variable was marked dead at the specified instruction, false
+ /// otherwise.
+ bool removeVirtualRegisterDead(unsigned reg,
+ MachineBasicBlock *MBB,
+ MachineInstr *MI) {
+ if (!getVarInfo(reg).removeKill(MI))
+ return false;
+
+ bool Removed = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isDef() && MO.getReg() == reg) {
+ MO.unsetIsDead();
+ Removed = true;
+ break;
+ }
+ }
+ assert(Removed && "Register is not defined by this instruction!");
+ return true;
+ }
+
+ /// removeVirtualRegistersDead - Remove all of the dead registers for the
+ /// specified instruction from the live variable information.
+ void removeVirtualRegistersDead(MachineInstr *MI);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ virtual void releaseMemory() {
+ VirtRegInfo.clear();
+ }
+
+ /// getVarInfo - Return the VarInfo structure for the specified VIRTUAL
+ /// register.
+ VarInfo &getVarInfo(unsigned RegIdx);
+
+ void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *BB);
+ void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *BB,
+ std::vector<MachineBasicBlock*> &WorkList);
+ void HandleVirtRegUse(VarInfo &VRInfo, MachineBasicBlock *MBB,
+ MachineInstr *MI);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachORelocation.h b/include/llvm/CodeGen/MachORelocation.h
new file mode 100644
index 0000000..6bf176d
--- /dev/null
+++ b/include/llvm/CodeGen/MachORelocation.h
@@ -0,0 +1,54 @@
+//=== MachORelocation.h - Mach-O Relocation Info ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MachORelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_MACHO_RELOCATION_H
+#define LLVM_CODEGEN_MACHO_RELOCATION_H
+
+namespace llvm {
+
+ /// MachORelocation - This struct contains information about each relocation
+ /// that needs to be emitted to the file.
+ /// see <mach-o/reloc.h>
+ class MachORelocation {
+ uint32_t r_address; // offset in the section to what is being relocated
+ uint32_t r_symbolnum; // symbol index if r_extern == 1 else section index
+ bool r_pcrel; // was relocated pc-relative already
+ uint8_t r_length; // length = 2 ^ r_length
+ bool r_extern; //
+ uint8_t r_type; // if not 0, machine-specific relocation type.
+ bool r_scattered; // 1 = scattered, 0 = non-scattered
+ int32_t r_value; // the value the item to be relocated is referring
+ // to.
+ public:
+ uint32_t getPackedFields() const {
+ if (r_scattered)
+ return (1 << 31) | (r_pcrel << 30) | ((r_length & 3) << 28) |
+ ((r_type & 15) << 24) | (r_address & 0x00FFFFFF);
+ else
+ return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
+ (r_extern << 4) | (r_type & 15);
+ }
+ uint32_t getAddress() const { return r_scattered ? r_value : r_address; }
+ uint32_t getRawAddress() const { return r_address; }
+
+ MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len,
+ bool ext, uint8_t type, bool scattered = false,
+ int32_t value = 0) :
+ r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len),
+ r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) {}
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_CODEGEN_MACHO_RELOCATION_H
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
new file mode 100644
index 0000000..df6e5a3
--- /dev/null
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -0,0 +1,371 @@
+//===-- llvm/CodeGen/MachineBasicBlock.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect the sequence of machine instructions for a basic block.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H
+#define LLVM_CODEGEN_MACHINEBASICBLOCK_H
+
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/ilist"
+#include "llvm/Support/Streams.h"
+
+namespace llvm {
+ class MachineFunction;
+
+// ilist_traits
+template <>
+struct ilist_traits<MachineInstr> {
+protected:
+ // this is only set by the MachineBasicBlock owning the ilist
+ friend class MachineBasicBlock;
+ MachineBasicBlock* parent;
+
+public:
+ ilist_traits<MachineInstr>() : parent(0) { }
+
+ static MachineInstr* getPrev(MachineInstr* N) { return N->prev; }
+ static MachineInstr* getNext(MachineInstr* N) { return N->next; }
+
+ static const MachineInstr*
+ getPrev(const MachineInstr* N) { return N->prev; }
+
+ static const MachineInstr*
+ getNext(const MachineInstr* N) { return N->next; }
+
+ static void setPrev(MachineInstr* N, MachineInstr* prev) { N->prev = prev; }
+ static void setNext(MachineInstr* N, MachineInstr* next) { N->next = next; }
+
+ static MachineInstr* createSentinel();
+ static void destroySentinel(MachineInstr *MI) { delete MI; }
+ void addNodeToList(MachineInstr* N);
+ void removeNodeFromList(MachineInstr* N);
+ void transferNodesFromList(
+ iplist<MachineInstr, ilist_traits<MachineInstr> >& toList,
+ ilist_iterator<MachineInstr> first,
+ ilist_iterator<MachineInstr> last);
+};
+
+class BasicBlock;
+
+class MachineBasicBlock {
+ typedef ilist<MachineInstr> Instructions;
+ Instructions Insts;
+ MachineBasicBlock *Prev, *Next;
+ const BasicBlock *BB;
+ int Number;
+ MachineFunction *Parent;
+
+ /// Predecessors/Successors - Keep track of the predecessor / successor
+ /// basicblocks.
+ std::vector<MachineBasicBlock *> Predecessors;
+ std::vector<MachineBasicBlock *> Successors;
+
+ /// LiveIns - Keep track of the physical registers that are livein of
+ /// the basicblock.
+ std::vector<unsigned> LiveIns;
+
+ /// IsLandingPad - Indicate that this basic block is entered via an
+ /// exception handler.
+ bool IsLandingPad;
+
+public:
+ explicit MachineBasicBlock(const BasicBlock *bb = 0) : Prev(0), Next(0),
+ BB(bb), Number(-1),
+ Parent(0),
+ IsLandingPad(false) {
+ Insts.parent = this;
+ }
+
+ ~MachineBasicBlock();
+
+ /// getBasicBlock - Return the LLVM basic block that this instance
+ /// corresponded to originally.
+ ///
+ const BasicBlock *getBasicBlock() const { return BB; }
+
+ /// getParent - Return the MachineFunction containing this basic block.
+ ///
+ const MachineFunction *getParent() const { return Parent; }
+ MachineFunction *getParent() { return Parent; }
+
+ typedef ilist<MachineInstr>::iterator iterator;
+ typedef ilist<MachineInstr>::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ unsigned size() const { return Insts.size(); }
+ bool empty() const { return Insts.empty(); }
+
+ MachineInstr& front() { return Insts.front(); }
+ MachineInstr& back() { return Insts.back(); }
+
+ iterator begin() { return Insts.begin(); }
+ const_iterator begin() const { return Insts.begin(); }
+ iterator end() { return Insts.end(); }
+ const_iterator end() const { return Insts.end(); }
+ reverse_iterator rbegin() { return Insts.rbegin(); }
+ const_reverse_iterator rbegin() const { return Insts.rbegin(); }
+ reverse_iterator rend () { return Insts.rend(); }
+ const_reverse_iterator rend () const { return Insts.rend(); }
+
+ // Machine-CFG iterators
+ typedef std::vector<MachineBasicBlock *>::iterator pred_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_iterator const_pred_iterator;
+ typedef std::vector<MachineBasicBlock *>::iterator succ_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_iterator const_succ_iterator;
+ typedef std::vector<MachineBasicBlock *>::reverse_iterator
+ pred_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+ const_pred_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::reverse_iterator
+ succ_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+ const_succ_reverse_iterator;
+
+ pred_iterator pred_begin() { return Predecessors.begin(); }
+ const_pred_iterator pred_begin() const { return Predecessors.begin(); }
+ pred_iterator pred_end() { return Predecessors.end(); }
+ const_pred_iterator pred_end() const { return Predecessors.end(); }
+ pred_reverse_iterator pred_rbegin()
+ { return Predecessors.rbegin();}
+ const_pred_reverse_iterator pred_rbegin() const
+ { return Predecessors.rbegin();}
+ pred_reverse_iterator pred_rend()
+ { return Predecessors.rend(); }
+ const_pred_reverse_iterator pred_rend() const
+ { return Predecessors.rend(); }
+ unsigned pred_size() const { return Predecessors.size(); }
+ bool pred_empty() const { return Predecessors.empty(); }
+ succ_iterator succ_begin() { return Successors.begin(); }
+ const_succ_iterator succ_begin() const { return Successors.begin(); }
+ succ_iterator succ_end() { return Successors.end(); }
+ const_succ_iterator succ_end() const { return Successors.end(); }
+ succ_reverse_iterator succ_rbegin()
+ { return Successors.rbegin(); }
+ const_succ_reverse_iterator succ_rbegin() const
+ { return Successors.rbegin(); }
+ succ_reverse_iterator succ_rend()
+ { return Successors.rend(); }
+ const_succ_reverse_iterator succ_rend() const
+ { return Successors.rend(); }
+ unsigned succ_size() const { return Successors.size(); }
+ bool succ_empty() const { return Successors.empty(); }
+
+ // LiveIn management methods.
+
+ /// addLiveIn - Add the specified register as a live in. Note that it
+ /// is an error to add the same register to the same set more than once.
+ void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); }
+
+ /// removeLiveIn - Remove the specified register from the live in set.
+ ///
+ void removeLiveIn(unsigned Reg);
+
+ // Iteration support for live in sets. These sets are kept in sorted
+ // order by their register number.
+ typedef std::vector<unsigned>::iterator livein_iterator;
+ typedef std::vector<unsigned>::const_iterator const_livein_iterator;
+ livein_iterator livein_begin() { return LiveIns.begin(); }
+ const_livein_iterator livein_begin() const { return LiveIns.begin(); }
+ livein_iterator livein_end() { return LiveIns.end(); }
+ const_livein_iterator livein_end() const { return LiveIns.end(); }
+ bool livein_empty() const { return LiveIns.empty(); }
+
+ /// isLandingPad - Returns true if the block is a landing pad. That is
+ /// this basic block is entered via an exception handler.
+ bool isLandingPad() const { return IsLandingPad; }
+
+ /// setIsLandingPad - Indicates the block is a landing pad. That is
+ /// this basic block is entered via an exception handler.
+ void setIsLandingPad() { IsLandingPad = true; }
+
+ // Code Layout methods.
+
+ /// moveBefore/moveAfter - move 'this' block before or after the specified
+ /// block. This only moves the block, it does not modify the CFG or adjust
+ /// potential fall-throughs at the end of the block.
+ void moveBefore(MachineBasicBlock *NewAfter);
+ void moveAfter(MachineBasicBlock *NewBefore);
+
+ // Machine-CFG mutators
+
+ /// addSuccessor - Add succ as a successor of this MachineBasicBlock.
+ /// The Predecessors list of succ is automatically updated.
+ ///
+ void addSuccessor(MachineBasicBlock *succ);
+
+ /// removeSuccessor - Remove successor from the successors list of this
+ /// MachineBasicBlock. The Predecessors list of succ is automatically updated.
+ ///
+ void removeSuccessor(MachineBasicBlock *succ);
+
+ /// removeSuccessor - Remove specified successor from the successors list of
+ /// this MachineBasicBlock. The Predecessors list of succ is automatically
+ /// updated. Return the iterator to the element after the one removed.
+ ///
+ succ_iterator removeSuccessor(succ_iterator I);
+
+ /// isSuccessor - Return true if the specified MBB is a successor of this
+ /// block.
+ bool isSuccessor(MachineBasicBlock *MBB) const;
+
+ /// getFirstTerminator - returns an iterator to the first terminator
+ /// instruction of this basic block. If a terminator does not exist,
+ /// it returns end()
+ iterator getFirstTerminator();
+
+ void pop_front() { Insts.pop_front(); }
+ void pop_back() { Insts.pop_back(); }
+ void push_back(MachineInstr *MI) { Insts.push_back(MI); }
+ template<typename IT>
+ void insert(iterator I, IT S, IT E) { Insts.insert(I, S, E); }
+ iterator insert(iterator I, MachineInstr *M) { return Insts.insert(I, M); }
+
+ // erase - Remove the specified element or range from the instruction list.
+ // These functions delete any instructions removed.
+ //
+ iterator erase(iterator I) { return Insts.erase(I); }
+ iterator erase(iterator I, iterator E) { return Insts.erase(I, E); }
+ MachineInstr *remove(MachineInstr *I) { return Insts.remove(I); }
+ void clear() { Insts.clear(); }
+
+ /// splice - Take a block of instructions from MBB 'Other' in the range [From,
+ /// To), and insert them into this MBB right before 'where'.
+ void splice(iterator where, MachineBasicBlock *Other, iterator From,
+ iterator To) {
+ Insts.splice(where, Other->Insts, From, To);
+ }
+
+ /// ReplaceUsesOfBlockWith - Given a machine basic block that branched to
+ /// 'Old', change the code and CFG so that it branches to 'New' instead.
+ void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+ /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in
+ /// the CFG to be inserted. If we have proven that MBB can only branch to
+ /// DestA and DestB, remove any other MBB successors from the CFG. DestA and
+ /// DestB can be null. Besides DestA and DestB, retain other edges leading
+ /// to LandingPads (currently there can be only one; we don't check or require
+ /// that here). Note it is possible that DestA and/or DestB are LandingPads.
+ bool CorrectExtraCFGEdges(MachineBasicBlock *DestA,
+ MachineBasicBlock *DestB,
+ bool isCond);
+
+ // Debugging methods.
+ void dump() const;
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// getNumber - MachineBasicBlocks are uniquely numbered at the function
+ /// level, unless they're not in a MachineFunction yet, in which case this
+ /// will return -1.
+ ///
+ int getNumber() const { return Number; }
+ void setNumber(int N) { Number = N; }
+
+private: // Methods used to maintain doubly linked list of blocks...
+ friend struct ilist_traits<MachineBasicBlock>;
+
+ MachineBasicBlock *getPrev() const { return Prev; }
+ MachineBasicBlock *getNext() const { return Next; }
+ void setPrev(MachineBasicBlock *P) { Prev = P; }
+ void setNext(MachineBasicBlock *N) { Next = N; }
+
+ // Machine-CFG mutators
+
+ /// addPredecessor - Remove pred as a predecessor of this MachineBasicBlock.
+ /// Don't do this unless you know what you're doing, because it doesn't
+ /// update pred's successors list. Use pred->addSuccessor instead.
+ ///
+ void addPredecessor(MachineBasicBlock *pred);
+
+ /// removePredecessor - Remove pred as a predecessor of this
+ /// MachineBasicBlock. Don't do this unless you know what you're
+ /// doing, because it doesn't update pred's successors list. Use
+ /// pred->removeSuccessor instead.
+ ///
+ void removePredecessor(MachineBasicBlock *pred);
+};
+
+std::ostream& operator<<(std::ostream &OS, const MachineBasicBlock &MBB);
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for machine basic block graphs (machine-CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a
+// MachineFunction as a graph of MachineBasicBlocks...
+//
+
+template <> struct GraphTraits<MachineBasicBlock *> {
+ typedef MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(MachineBasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->succ_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->succ_end();
+ }
+};
+
+template <> struct GraphTraits<const MachineBasicBlock *> {
+ typedef const MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const MachineBasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->succ_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->succ_end();
+ }
+};
+
+// Provide specializations of GraphTraits to be able to treat a
+// MachineFunction as a graph of MachineBasicBlocks... and to walk it
+// in inverse order. Inverse order for a function is considered
+// to be when traversing the predecessor edges of a MBB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<MachineBasicBlock*> > {
+ typedef MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<MachineBasicBlock *> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->pred_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->pred_end();
+ }
+};
+
+template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > {
+ typedef const MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::const_pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<const MachineBasicBlock*> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->pred_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->pred_end();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
new file mode 100644
index 0000000..018c5e5
--- /dev/null
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -0,0 +1,200 @@
+//===-- llvm/CodeGen/MachineCodeEmitter.h - Code emission -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an abstract interface that is used by the machine code
+// emission framework to output the code. This allows machine code emission to
+// be separated from concerns such as resolution of call targets, and where the
+// machine code will be written (memory or disk, f.e.).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
+#define LLVM_CODEGEN_MACHINECODEEMITTER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+class MachineFunction;
+class MachineRelocation;
+class Value;
+class GlobalValue;
+class Function;
+
+/// MachineCodeEmitter - This class defines two sorts of methods: those for
+/// emitting the actual bytes of machine code, and those for emitting auxillary
+/// structures, such as jump tables, relocations, etc.
+///
+/// Emission of machine code is complicated by the fact that we don't (in
+/// general) know the size of the machine code that we're about to emit before
+/// we emit it. As such, we preallocate a certain amount of memory, and set the
+/// BufferBegin/BufferEnd pointers to the start and end of the buffer. As we
+/// emit machine instructions, we advance the CurBufferPtr to indicate the
+/// location of the next byte to emit. In the case of a buffer overflow (we
+/// need to emit more machine code than we have allocated space for), the
+/// CurBufferPtr will saturate to BufferEnd and ignore stores. Once the entire
+/// function has been emitted, the overflow condition is checked, and if it has
+/// occurred, more memory is allocated, and we reemit the code into it.
+///
+class MachineCodeEmitter {
+protected:
+ /// BufferBegin/BufferEnd - Pointers to the start and end of the memory
+ /// allocated for this code buffer.
+ unsigned char *BufferBegin, *BufferEnd;
+
+ /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
+ /// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
+ /// this pointer is at BufferEnd, it will never move due to code emission, and
+ /// all code emission requests will be ignored (this is the buffer overflow
+ /// condition).
+ unsigned char *CurBufferPtr;
+public:
+ virtual ~MachineCodeEmitter() {}
+
+ /// startFunction - This callback is invoked when the specified function is
+ /// about to be code generated. This initializes the BufferBegin/End/Ptr
+ /// fields.
+ ///
+ virtual void startFunction(MachineFunction &F) = 0;
+
+ /// finishFunction - This callback is invoked when the specified function has
+ /// finished code generation. If a buffer overflow has occurred, this method
+ /// returns true (the callee is required to try again), otherwise it returns
+ /// false.
+ ///
+ virtual bool finishFunction(MachineFunction &F) = 0;
+
+ /// startFunctionStub - This callback is invoked when the JIT needs the
+ /// address of a function that has not been code generated yet. The StubSize
+ /// specifies the total size required by the stub. Stubs are not allowed to
+ /// have constant pools, the can only use the other emitByte*/emitWord*
+ /// methods.
+ ///
+ virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) = 0;
+
+ /// finishFunctionStub - This callback is invoked to terminate a function
+ /// stub.
+ ///
+ virtual void *finishFunctionStub(const Function *F) = 0;
+
+ /// emitByte - This callback is invoked when a byte needs to be written to the
+ /// output stream.
+ ///
+ void emitByte(unsigned char B) {
+ if (CurBufferPtr != BufferEnd)
+ *CurBufferPtr++ = B;
+ }
+
+ /// emitWordLE - This callback is invoked when a 32-bit word needs to be
+ /// written to the output stream in little-endian format.
+ ///
+ void emitWordLE(unsigned W) {
+ if (CurBufferPtr+4 <= BufferEnd) {
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitWordBE - This callback is invoked when a 32-bit word needs to be
+ /// written to the output stream in big-endian format.
+ ///
+ void emitWordBE(unsigned W) {
+ if (CurBufferPtr+4 <= BufferEnd) {
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitAlignment - Move the CurBufferPtr pointer up the the specified
+ /// alignment (saturated to BufferEnd of course).
+ void emitAlignment(unsigned Alignment) {
+ if (Alignment == 0) Alignment = 1;
+ // Move the current buffer ptr up to the specified alignment.
+ CurBufferPtr =
+ (unsigned char*)(((intptr_t)CurBufferPtr+Alignment-1) &
+ ~(intptr_t)(Alignment-1));
+ if (CurBufferPtr > BufferEnd)
+ CurBufferPtr = BufferEnd;
+ }
+
+ /// allocateSpace - Allocate a block of space in the current output buffer,
+ /// returning null (and setting conditions to indicate buffer overflow) on
+ /// failure. Alignment is the alignment in bytes of the buffer desired.
+ void *allocateSpace(intptr_t Size, unsigned Alignment) {
+ emitAlignment(Alignment);
+ void *Result = CurBufferPtr;
+
+ // Allocate the space.
+ CurBufferPtr += Size;
+
+ // Check for buffer overflow.
+ if (CurBufferPtr >= BufferEnd) {
+ CurBufferPtr = BufferEnd;
+ Result = 0;
+ }
+ return Result;
+ }
+
+ /// StartMachineBasicBlock - This should be called by the target when a new
+ /// basic block is about to be emitted. This way the MCE knows where the
+ /// start of the block is, and can implement getMachineBasicBlockAddress.
+ virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0;
+
+ /// getCurrentPCValue - This returns the address that the next emitted byte
+ /// will be output to.
+ ///
+ virtual intptr_t getCurrentPCValue() const {
+ return (intptr_t)CurBufferPtr;
+ }
+
+ /// getCurrentPCOffset - Return the offset from the start of the emitted
+ /// buffer that we are currently writing to.
+ intptr_t getCurrentPCOffset() const {
+ return CurBufferPtr-BufferBegin;
+ }
+
+ /// addRelocation - Whenever a relocatable address is needed, it should be
+ /// noted with this interface.
+ virtual void addRelocation(const MachineRelocation &MR) = 0;
+
+
+ /// FIXME: These should all be handled with relocations!
+
+ /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
+ /// the constant pool that was last emitted with the emitConstantPool method.
+ ///
+ virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const = 0;
+
+ /// getJumpTableEntryAddress - Return the address of the jump table with index
+ /// 'Index' in the function that last called initJumpTableInfo.
+ ///
+ virtual intptr_t getJumpTableEntryAddress(unsigned Index) const = 0;
+
+ /// getMachineBasicBlockAddress - Return the address of the specified
+ /// MachineBasicBlock, only usable after the label for the MBB has been
+ /// emitted.
+ ///
+ virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
new file mode 100644
index 0000000..1500053
--- /dev/null
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -0,0 +1,149 @@
+//===-- CodeGen/MachineConstantPool.h - Abstract Constant Pool --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file This file declares the MachineConstantPool class which is an abstract
+/// constant pool to keep track of constants referenced by a function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+#define LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/Support/Streams.h"
+#include <vector>
+#include <iosfwd>
+
+namespace llvm {
+
+class AsmPrinter;
+class Constant;
+class TargetData;
+class TargetMachine;
+class MachineConstantPool;
+
+/// Abstract base class for all machine specific constantpool value subclasses.
+///
+class MachineConstantPoolValue {
+ const Type *Ty;
+
+public:
+ explicit MachineConstantPoolValue(const Type *ty) : Ty(ty) {}
+ virtual ~MachineConstantPoolValue() {};
+
+ /// getType - get type of this MachineConstantPoolValue.
+ ///
+ inline const Type *getType() const { return Ty; }
+
+ virtual int getExistingMachineCPValue(MachineConstantPool *CP,
+ unsigned Alignment) = 0;
+
+ virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID) = 0;
+
+ /// print - Implement operator<<...
+ ///
+ virtual void print(std::ostream &O) const = 0;
+ void print(std::ostream *O) const { if (O) print(*O); }
+};
+
+inline std::ostream &operator<<(std::ostream &OS,
+ const MachineConstantPoolValue &V) {
+ V.print(OS);
+ return OS;
+}
+
+/// This class is a data container for one entry in a MachineConstantPool.
+/// It contains a pointer to the value and an offset from the start of
+/// the constant pool.
+/// @brief An entry in a MachineConstantPool
+class MachineConstantPoolEntry {
+public:
+ /// The constant itself.
+ union {
+ Constant *ConstVal;
+ MachineConstantPoolValue *MachineCPVal;
+ } Val;
+
+ /// The offset of the constant from the start of the pool. The top bit is set
+ /// when Val is a MachineConstantPoolValue.
+ unsigned Offset;
+
+ MachineConstantPoolEntry(Constant *V, unsigned O)
+ : Offset(O) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.ConstVal = V;
+ }
+ MachineConstantPoolEntry(MachineConstantPoolValue *V, unsigned O)
+ : Offset(O){
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.MachineCPVal = V;
+ Offset |= 1 << (sizeof(unsigned)*8-1);
+ }
+
+ bool isMachineConstantPoolEntry() const {
+ return (int)Offset < 0;
+ }
+
+ int getOffset() const {
+ return Offset & ~(1 << (sizeof(unsigned)*8-1));
+ }
+
+ const Type *getType() const;
+};
+
+/// The MachineConstantPool class keeps track of constants referenced by a
+/// function which must be spilled to memory. This is used for constants which
+/// are unable to be used directly as operands to instructions, which typically
+/// include floating point and large integer constants.
+///
+/// Instructions reference the address of these constant pool constants through
+/// the use of MO_ConstantPoolIndex values. When emitting assembly or machine
+/// code, these virtual address references are converted to refer to the
+/// address of the function constant pool values.
+/// @brief The machine constant pool.
+class MachineConstantPool {
+ const TargetData *TD; ///< The machine's TargetData.
+ unsigned PoolAlignment; ///< The alignment for the pool.
+ std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
+public:
+ /// @brief The only constructor.
+ MachineConstantPool(const TargetData *td) : TD(td), PoolAlignment(1) {}
+ ~MachineConstantPool();
+
+ /// getConstantPoolAlignment - Return the log2 of the alignment required by
+ /// the whole constant pool, of which the first element must be aligned.
+ unsigned getConstantPoolAlignment() const { return PoolAlignment; }
+
+ /// getConstantPoolIndex - Create a new entry in the constant pool or return
+ /// an existing one. User must specify an alignment in bytes for the object.
+ unsigned getConstantPoolIndex(Constant *C, unsigned Alignment);
+ unsigned getConstantPoolIndex(MachineConstantPoolValue *V,unsigned Alignment);
+
+ /// isEmpty - Return true if this constant pool contains no constants.
+ bool isEmpty() const { return Constants.empty(); }
+
+ const std::vector<MachineConstantPoolEntry> &getConstants() const {
+ return Constants;
+ }
+
+ /// print - Used by the MachineFunction printer to print information about
+ /// constant pool objects. Implemented in MachineFunction.cpp
+ ///
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// dump - Call print(std::cerr) to be called from the debugger.
+ ///
+ void dump() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
new file mode 100644
index 0000000..be481f7
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -0,0 +1,327 @@
+//===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H
+#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
+
+#include <vector>
+
+namespace llvm {
+class TargetData;
+class TargetRegisterClass;
+class Type;
+class MachineModuleInfo;
+class MachineFunction;
+
+/// The CalleeSavedInfo class tracks the information need to locate where a
+/// callee saved register in the current frame.
+class CalleeSavedInfo {
+
+private:
+ unsigned Reg;
+ const TargetRegisterClass *RegClass;
+ int FrameIdx;
+
+public:
+ CalleeSavedInfo(unsigned R, const TargetRegisterClass *RC, int FI = 0)
+ : Reg(R)
+ , RegClass(RC)
+ , FrameIdx(FI)
+ {}
+
+ // Accessors.
+ unsigned getReg() const { return Reg; }
+ const TargetRegisterClass *getRegClass() const { return RegClass; }
+ int getFrameIdx() const { return FrameIdx; }
+ void setFrameIdx(int FI) { FrameIdx = FI; }
+};
+
+/// The MachineFrameInfo class represents an abstract stack frame until
+/// prolog/epilog code is inserted. This class is key to allowing stack frame
+/// representation optimizations, such as frame pointer elimination. It also
+/// allows more mundane (but still important) optimizations, such as reordering
+/// of abstract objects on the stack frame.
+///
+/// To support this, the class assigns unique integer identifiers to stack
+/// objects requested clients. These identifiers are negative integers for
+/// fixed stack objects (such as arguments passed on the stack) or positive
+/// for objects that may be reordered. Instructions which refer to stack
+/// objects use a special MO_FrameIndex operand to represent these frame
+/// indexes.
+///
+/// Because this class keeps track of all references to the stack frame, it
+/// knows when a variable sized object is allocated on the stack. This is the
+/// sole condition which prevents frame pointer elimination, which is an
+/// important optimization on register-poor architectures. Because original
+/// variable sized alloca's in the source program are the only source of
+/// variable sized stack objects, it is safe to decide whether there will be
+/// any variable sized objects before all stack objects are known (for
+/// example, register allocator spill code never needs variable sized
+/// objects).
+///
+/// When prolog/epilog code emission is performed, the final stack frame is
+/// built and the machine instructions are modified to refer to the actual
+/// stack offsets of the object, eliminating all MO_FrameIndex operands from
+/// the program.
+///
+/// @brief Abstract Stack Frame Information
+class MachineFrameInfo {
+
+ // StackObject - Represent a single object allocated on the stack.
+ struct StackObject {
+ // The size of this object on the stack. 0 means a variable sized object
+ uint64_t Size;
+
+ // Alignment - The required alignment of this stack slot.
+ unsigned Alignment;
+
+ // SPOffset - The offset of this object from the stack pointer on entry to
+ // the function. This field has no meaning for a variable sized element.
+ int64_t SPOffset;
+
+ StackObject(uint64_t Sz, unsigned Al, int64_t SP)
+ : Size(Sz), Alignment(Al), SPOffset(SP) {}
+ };
+
+ /// Objects - The list of stack objects allocated...
+ ///
+ std::vector<StackObject> Objects;
+
+ /// NumFixedObjects - This contains the number of fixed objects contained on
+ /// the stack. Because fixed objects are stored at a negative index in the
+ /// Objects list, this is also the index to the 0th object in the list.
+ ///
+ unsigned NumFixedObjects;
+
+ /// HasVarSizedObjects - This boolean keeps track of whether any variable
+ /// sized objects have been allocated yet.
+ ///
+ bool HasVarSizedObjects;
+
+ /// StackSize - The prolog/epilog code inserter calculates the final stack
+ /// offsets for all of the fixed size objects, updating the Objects list
+ /// above. It then updates StackSize to contain the number of bytes that need
+ /// to be allocated on entry to the function.
+ ///
+ uint64_t StackSize;
+
+ /// OffsetAdjustment - The amount that a frame offset needs to be adjusted to
+ /// have the actual offset from the stack/frame pointer. The calculation is
+ /// MFI->getObjectOffset(Index) + StackSize - TFI.getOffsetOfLocalArea() +
+ /// OffsetAdjustment. If OffsetAdjustment is zero (default) then offsets are
+ /// away from TOS. If OffsetAdjustment == StackSize then offsets are toward
+ /// TOS.
+ int OffsetAdjustment;
+
+ /// MaxAlignment - The prolog/epilog code inserter may process objects
+ /// that require greater alignment than the default alignment the target
+ /// provides. To handle this, MaxAlignment is set to the maximum alignment
+ /// needed by the objects on the current frame. If this is greater than the
+ /// native alignment maintained by the compiler, dynamic alignment code will
+ /// be needed.
+ ///
+ unsigned MaxAlignment;
+
+ /// HasCalls - Set to true if this function has any function calls. This is
+ /// only valid during and after prolog/epilog code insertion.
+ bool HasCalls;
+
+ /// MaxCallFrameSize - This contains the size of the largest call frame if the
+ /// target uses frame setup/destroy pseudo instructions (as defined in the
+ /// TargetFrameInfo class). This information is important for frame pointer
+ /// elimination. If is only valid during and after prolog/epilog code
+ /// insertion.
+ ///
+ unsigned MaxCallFrameSize;
+
+ /// CSInfo - The prolog/epilog code inserter fills in this vector with each
+ /// callee saved register saved in the frame. Beyond its use by the prolog/
+ /// epilog code inserter, this data used for debug info and exception
+ /// handling.
+ std::vector<CalleeSavedInfo> CSInfo;
+
+ /// MMI - This field is set (via setMachineModuleInfo) by a module info
+ /// consumer (ex. DwarfWriter) to indicate that frame layout information
+ /// should be acquired. Typically, it's the responsibility of the target's
+ /// MRegisterInfo prologue/epilogue emitting code to inform MachineModuleInfo
+ /// of frame layouts.
+ MachineModuleInfo *MMI;
+
+public:
+ MachineFrameInfo() {
+ StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
+ HasVarSizedObjects = false;
+ HasCalls = false;
+ MaxCallFrameSize = 0;
+ MMI = 0;
+ }
+
+ /// hasStackObjects - Return true if there are any stack objects in this
+ /// function.
+ ///
+ bool hasStackObjects() const { return !Objects.empty(); }
+
+ /// hasVarSizedObjects - This method may be called any time after instruction
+ /// selection is complete to determine if the stack frame for this function
+ /// contains any variable sized objects.
+ ///
+ bool hasVarSizedObjects() const { return HasVarSizedObjects; }
+
+ /// getObjectIndexBegin - Return the minimum frame object index...
+ ///
+ int getObjectIndexBegin() const { return -NumFixedObjects; }
+
+ /// getObjectIndexEnd - Return one past the maximum frame object index...
+ ///
+ int getObjectIndexEnd() const { return Objects.size()-NumFixedObjects; }
+
+ /// getObjectSize - Return the size of the specified object
+ ///
+ int64_t getObjectSize(int ObjectIdx) const {
+ assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].Size;
+ }
+
+ /// getObjectAlignment - Return the alignment of the specified stack object...
+ int getObjectAlignment(int ObjectIdx) const {
+ assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].Alignment;
+ }
+
+ /// getObjectOffset - Return the assigned stack offset of the specified object
+ /// from the incoming stack pointer.
+ ///
+ int64_t getObjectOffset(int ObjectIdx) const {
+ assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].SPOffset;
+ }
+
+ /// setObjectOffset - Set the stack frame offset of the specified object. The
+ /// offset is relative to the stack pointer on entry to the function.
+ ///
+ void setObjectOffset(int ObjectIdx, int64_t SPOffset) {
+ assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+ Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
+ }
+
+ /// getStackSize - Return the number of bytes that must be allocated to hold
+ /// all of the fixed size frame objects. This is only valid after
+ /// Prolog/Epilog code insertion has finalized the stack frame layout.
+ ///
+ uint64_t getStackSize() const { return StackSize; }
+
+ /// setStackSize - Set the size of the stack...
+ ///
+ void setStackSize(uint64_t Size) { StackSize = Size; }
+
+ /// getOffsetAdjustment - Return the correction for frame offsets.
+ ///
+ int getOffsetAdjustment() const { return OffsetAdjustment; }
+
+ /// setOffsetAdjustment - Set the correction for frame offsets.
+ ///
+ void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; }
+
+ /// getMaxAlignment - Return the alignment in bytes that this function must be
+ /// aligned to, which is greater than the default stack alignment provided by
+ /// the target.
+ ///
+ unsigned getMaxAlignment() const { return MaxAlignment; }
+
+ /// setMaxAlignment - Set the preferred alignment.
+ ///
+ void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
+
+ /// hasCalls - Return true if the current function has no function calls.
+ /// This is only valid during or after prolog/epilog code emission.
+ ///
+ bool hasCalls() const { return HasCalls; }
+ void setHasCalls(bool V) { HasCalls = V; }
+
+ /// getMaxCallFrameSize - Return the maximum size of a call frame that must be
+ /// allocated for an outgoing function call. This is only available if
+ /// CallFrameSetup/Destroy pseudo instructions are used by the target, and
+ /// then only during or after prolog/epilog code insertion.
+ ///
+ unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; }
+ void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; }
+
+ /// CreateFixedObject - Create a new object at a fixed location on the stack.
+ /// All fixed objects should be created before other objects are created for
+ /// efficiency. This returns an index with a negative value.
+ ///
+ int CreateFixedObject(uint64_t Size, int64_t SPOffset) {
+ assert(Size != 0 && "Cannot allocate zero size fixed stack objects!");
+ Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset));
+ return -++NumFixedObjects;
+ }
+
+ /// isFixedObjectIndex - Returns true if the specified index corresponds to a
+ /// fixed stack object.
+ bool isFixedObjectIndex(int ObjectIdx) const {
+ return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects);
+ }
+
+ /// CreateStackObject - Create a new statically sized stack object, returning
+ /// a postive identifier to represent it.
+ ///
+ int CreateStackObject(uint64_t Size, unsigned Alignment) {
+ // Keep track of the maximum alignment.
+ if (MaxAlignment < Alignment) MaxAlignment = Alignment;
+
+ assert(Size != 0 && "Cannot allocate zero size stack objects!");
+ Objects.push_back(StackObject(Size, Alignment, -1));
+ return Objects.size()-NumFixedObjects-1;
+ }
+
+ /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a
+ /// variable sized object has been created. This must be created whenever a
+ /// variable sized object is created, whether or not the index returned is
+ /// actually used.
+ ///
+ int CreateVariableSizedObject() {
+ HasVarSizedObjects = true;
+ if (MaxAlignment < 1) MaxAlignment = 1;
+ Objects.push_back(StackObject(0, 1, -1));
+ return Objects.size()-NumFixedObjects-1;
+ }
+
+ /// getCalleeSavedInfo - Returns a reference to call saved info vector for the
+ /// current function.
+ const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const {
+ return CSInfo;
+ }
+
+ /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's
+ /// callee saved information.
+ void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
+ CSInfo = CSI;
+ }
+
+ /// getMachineModuleInfo - Used by a prologue/epilogue emitter (MRegisterInfo)
+ /// to provide frame layout information.
+ MachineModuleInfo *getMachineModuleInfo() const { return MMI; }
+
+ /// setMachineModuleInfo - Used by a meta info consumer (DwarfWriter) to
+ /// indicate that frame layout information should be gathered.
+ void setMachineModuleInfo(MachineModuleInfo *mmi) { MMI = mmi; }
+
+ /// print - Used by the MachineFunction printer to print information about
+ /// stack objects. Implemented in MachineFunction.cpp
+ ///
+ void print(const MachineFunction &MF, std::ostream &OS) const;
+
+ /// dump - Call print(MF, std::cerr) to be called from the debugger.
+ void dump(const MachineFunction &MF) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
new file mode 100644
index 0000000..00a1fe8
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -0,0 +1,374 @@
+//===-- llvm/CodeGen/MachineFunction.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect native machine code for a function. This class contains a list of
+// MachineBasicBlock instances that make up the current compiled function.
+//
+// This class also contains pointers to various classes which hold
+// target-specific information about the generated code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
+#define LLVM_CODEGEN_MACHINEFUNCTION_H
+
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Support/Annotation.h"
+#include "llvm/ADT/BitVector.h"
+
+namespace llvm {
+
+class Function;
+class TargetMachine;
+class SSARegMap;
+class MachineFrameInfo;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+
+// ilist_traits
+template <>
+struct ilist_traits<MachineBasicBlock> {
+ // this is only set by the MachineFunction owning the ilist
+ friend class MachineFunction;
+ MachineFunction* Parent;
+
+public:
+ ilist_traits<MachineBasicBlock>() : Parent(0) { }
+
+ static MachineBasicBlock* getPrev(MachineBasicBlock* N) { return N->Prev; }
+ static MachineBasicBlock* getNext(MachineBasicBlock* N) { return N->Next; }
+
+ static const MachineBasicBlock*
+ getPrev(const MachineBasicBlock* N) { return N->Prev; }
+
+ static const MachineBasicBlock*
+ getNext(const MachineBasicBlock* N) { return N->Next; }
+
+ static void setPrev(MachineBasicBlock* N, MachineBasicBlock* prev) {
+ N->Prev = prev;
+ }
+ static void setNext(MachineBasicBlock* N, MachineBasicBlock* next) {
+ N->Next = next;
+ }
+
+ static MachineBasicBlock* createSentinel();
+ static void destroySentinel(MachineBasicBlock *MBB) { delete MBB; }
+ void addNodeToList(MachineBasicBlock* N);
+ void removeNodeFromList(MachineBasicBlock* N);
+ void transferNodesFromList(iplist<MachineBasicBlock,
+ ilist_traits<MachineBasicBlock> > &toList,
+ ilist_iterator<MachineBasicBlock> first,
+ ilist_iterator<MachineBasicBlock> last);
+};
+
+/// MachineFunctionInfo - This class can be derived from and used by targets to
+/// hold private target-specific information for each MachineFunction. Objects
+/// of type are accessed/created with MF::getInfo and destroyed when the
+/// MachineFunction is destroyed.
+struct MachineFunctionInfo {
+ virtual ~MachineFunctionInfo() {};
+};
+
+class MachineFunction : private Annotation {
+ const Function *Fn;
+ const TargetMachine &Target;
+
+ // List of machine basic blocks in function
+ ilist<MachineBasicBlock> BasicBlocks;
+
+ // Keeping track of mapping from SSA values to registers
+ SSARegMap *SSARegMapping;
+
+ // Used to keep track of target-specific per-machine function information for
+ // the target implementation.
+ MachineFunctionInfo *MFInfo;
+
+ // Keep track of objects allocated on the stack.
+ MachineFrameInfo *FrameInfo;
+
+ // Keep track of constants which are spilled to memory
+ MachineConstantPool *ConstantPool;
+
+ // Keep track of jump tables for switch instructions
+ MachineJumpTableInfo *JumpTableInfo;
+
+ // Function-level unique numbering for MachineBasicBlocks. When a
+ // MachineBasicBlock is inserted into a MachineFunction is it automatically
+ // numbered and this vector keeps track of the mapping from ID's to MBB's.
+ std::vector<MachineBasicBlock*> MBBNumbering;
+
+ /// UsedPhysRegs - This is a bit vector that is computed and set by the
+ /// register allocator, and must be kept up to date by passes that run after
+ /// register allocation (though most don't modify this). This is used
+ /// so that the code generator knows which callee save registers to save and
+ /// for other target specific uses.
+ BitVector UsedPhysRegs;
+
+ /// LiveIns/LiveOuts - Keep track of the physical registers that are
+ /// livein/liveout of the function. Live in values are typically arguments in
+ /// registers, live out values are typically return values in registers.
+ /// LiveIn values are allowed to have virtual registers associated with them,
+ /// stored in the second element.
+ std::vector<std::pair<unsigned, unsigned> > LiveIns;
+ std::vector<unsigned> LiveOuts;
+
+public:
+ MachineFunction(const Function *Fn, const TargetMachine &TM);
+ ~MachineFunction();
+
+ /// getFunction - Return the LLVM function that this machine code represents
+ ///
+ const Function *getFunction() const { return Fn; }
+
+ /// getTarget - Return the target machine this machine code is compiled with
+ ///
+ const TargetMachine &getTarget() const { return Target; }
+
+ /// SSARegMap Interface... Keep track of information about each SSA virtual
+ /// register, such as which register class it belongs to.
+ ///
+ SSARegMap *getSSARegMap() const { return SSARegMapping; }
+ void clearSSARegMap();
+
+ /// getFrameInfo - Return the frame info object for the current function.
+ /// This object contains information about objects allocated on the stack
+ /// frame of the current function in an abstract way.
+ ///
+ 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() const { return JumpTableInfo; }
+
+ /// getConstantPool - Return the constant pool object for the current
+ /// function.
+ ///
+ MachineConstantPool *getConstantPool() const { return ConstantPool; }
+
+ /// MachineFunctionInfo - Keep track of various per-function pieces of
+ /// information for backends that would like to do so.
+ ///
+ template<typename Ty>
+ Ty *getInfo() {
+ if (!MFInfo) MFInfo = new Ty(*this);
+
+ assert((void*)dynamic_cast<Ty*>(MFInfo) == (void*)MFInfo &&
+ "Invalid concrete type or multiple inheritence for getInfo");
+ return static_cast<Ty*>(MFInfo);
+ }
+
+ template<typename Ty>
+ const Ty *getInfo() const {
+ return const_cast<MachineFunction*>(this)->getInfo<Ty>();
+ }
+
+ /// isPhysRegUsed - Return true if the specified register is used in this
+ /// function. This only works after register allocation.
+ bool isPhysRegUsed(unsigned Reg) const { return UsedPhysRegs[Reg]; }
+
+ /// setPhysRegUsed - Mark the specified register used in this function.
+ /// This should only be called during and after register allocation.
+ void setPhysRegUsed(unsigned Reg) { UsedPhysRegs[Reg] = true; }
+
+ /// setPhysRegUnused - Mark the specified register unused in this function.
+ /// This should only be called during and after register allocation.
+ void setPhysRegUnused(unsigned Reg) { UsedPhysRegs[Reg] = false; }
+
+ // LiveIn/LiveOut management methods.
+
+ /// addLiveIn/Out - Add the specified register as a live in/out. Note that it
+ /// is an error to add the same register to the same set more than once.
+ void addLiveIn(unsigned Reg, unsigned vreg = 0) {
+ LiveIns.push_back(std::make_pair(Reg, vreg));
+ }
+ void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); }
+
+ // Iteration support for live in/out sets. These sets are kept in sorted
+ // order by their register number.
+ typedef std::vector<std::pair<unsigned,unsigned> >::const_iterator
+ livein_iterator;
+ typedef std::vector<unsigned>::const_iterator liveout_iterator;
+ livein_iterator livein_begin() const { return LiveIns.begin(); }
+ livein_iterator livein_end() const { return LiveIns.end(); }
+ bool livein_empty() const { return LiveIns.empty(); }
+ liveout_iterator liveout_begin() const { return LiveOuts.begin(); }
+ liveout_iterator liveout_end() const { return LiveOuts.end(); }
+ bool liveout_empty() const { return LiveOuts.empty(); }
+
+ /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they
+ /// are inserted into the machine function. The block number for a machine
+ /// basic block can be found by using the MBB::getBlockNumber method, this
+ /// method provides the inverse mapping.
+ ///
+ MachineBasicBlock *getBlockNumbered(unsigned N) {
+ assert(N < MBBNumbering.size() && "Illegal block number");
+ assert(MBBNumbering[N] && "Block was removed from the machine function!");
+ return MBBNumbering[N];
+ }
+
+ /// getNumBlockIDs - Return the number of MBB ID's allocated.
+ ///
+ unsigned getNumBlockIDs() const { return MBBNumbering.size(); }
+
+ /// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
+ /// recomputes them. This guarantees that the MBB numbers are sequential,
+ /// dense, and match the ordering of the blocks within the function. If a
+ /// specific MachineBasicBlock is specified, only that block and those after
+ /// it are renumbered.
+ void RenumberBlocks(MachineBasicBlock *MBBFrom = 0);
+
+ /// print - Print out the MachineFunction in a format suitable for debugging
+ /// to the specified stream.
+ ///
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// viewCFG - This function is meant for use from the debugger. You can just
+ /// say 'call F->viewCFG()' and a ghostview window should pop up from the
+ /// program, displaying the CFG of the current function with the code for each
+ /// basic block inside. This depends on there being a 'dot' and 'gv' program
+ /// in your path.
+ ///
+ void viewCFG() const;
+
+ /// viewCFGOnly - This function is meant for use from the debugger. It works
+ /// just like viewCFG, but it does not include the contents of basic blocks
+ /// into the nodes, just the label. If you are only interested in the CFG
+ /// this can make the graph smaller.
+ ///
+ void viewCFGOnly() const;
+
+ /// dump - Print the current MachineFunction to cerr, useful for debugger use.
+ ///
+ void dump() const;
+
+ /// construct - Allocate and initialize a MachineFunction for a given Function
+ /// and Target
+ ///
+ static MachineFunction& construct(const Function *F, const TargetMachine &TM);
+
+ /// destruct - Destroy the MachineFunction corresponding to a given Function
+ ///
+ static void destruct(const Function *F);
+
+ /// get - Return a handle to a MachineFunction corresponding to the given
+ /// Function. This should not be called before "construct()" for a given
+ /// Function.
+ ///
+ static MachineFunction& get(const Function *F);
+
+ // Provide accessors for the MachineBasicBlock list...
+ typedef ilist<MachineBasicBlock> BasicBlockListType;
+ typedef BasicBlockListType::iterator iterator;
+ typedef BasicBlockListType::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ // Provide accessors for basic blocks...
+ const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
+ BasicBlockListType &getBasicBlockList() { return BasicBlocks; }
+
+ //===--------------------------------------------------------------------===//
+ // BasicBlock iterator forwarding functions
+ //
+ iterator begin() { return BasicBlocks.begin(); }
+ const_iterator begin() const { return BasicBlocks.begin(); }
+ iterator end () { return BasicBlocks.end(); }
+ const_iterator end () const { return BasicBlocks.end(); }
+
+ reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
+ const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
+ reverse_iterator rend () { return BasicBlocks.rend(); }
+ const_reverse_iterator rend () const { return BasicBlocks.rend(); }
+
+ unsigned size() const { return BasicBlocks.size(); }
+ bool empty() const { return BasicBlocks.empty(); }
+ const MachineBasicBlock &front() const { return BasicBlocks.front(); }
+ MachineBasicBlock &front() { return BasicBlocks.front(); }
+ const MachineBasicBlock & back() const { return BasicBlocks.back(); }
+ MachineBasicBlock & back() { return BasicBlocks.back(); }
+
+ //===--------------------------------------------------------------------===//
+ // Internal functions used to automatically number MachineBasicBlocks
+ //
+
+ /// getNextMBBNumber - Returns the next unique number to be assigned
+ /// to a MachineBasicBlock in this MachineFunction.
+ ///
+ unsigned addToMBBNumbering(MachineBasicBlock *MBB) {
+ MBBNumbering.push_back(MBB);
+ return MBBNumbering.size()-1;
+ }
+
+ /// removeFromMBBNumbering - Remove the specific machine basic block from our
+ /// tracker, this is only really to be used by the MachineBasicBlock
+ /// implementation.
+ void removeFromMBBNumbering(unsigned N) {
+ assert(N < MBBNumbering.size() && "Illegal basic block #");
+ MBBNumbering[N] = 0;
+ }
+};
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a
+// machine function as a graph of machine basic blocks... these are
+// the same as the machine basic block iterators, except that the root
+// node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<MachineFunction*> :
+ public GraphTraits<MachineBasicBlock*> {
+ static NodeType *getEntryNode(MachineFunction *F) {
+ return &F->front();
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef MachineFunction::iterator nodes_iterator;
+ static nodes_iterator nodes_begin(MachineFunction *F) { return F->begin(); }
+ static nodes_iterator nodes_end (MachineFunction *F) { return F->end(); }
+};
+template <> struct GraphTraits<const MachineFunction*> :
+ public GraphTraits<const MachineBasicBlock*> {
+ static NodeType *getEntryNode(const MachineFunction *F) {
+ return &F->front();
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef MachineFunction::const_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(const MachineFunction *F) { return F->begin(); }
+ static nodes_iterator nodes_end (const MachineFunction *F) { return F->end(); }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<MachineFunction*> > :
+ public GraphTraits<Inverse<MachineBasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<MachineFunction*> G) {
+ return &G.Graph->front();
+ }
+};
+template <> struct GraphTraits<Inverse<const MachineFunction*> > :
+ public GraphTraits<Inverse<const MachineBasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<const MachineFunction *> G) {
+ return &G.Graph->front();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h
new file mode 100644
index 0000000..f90c696
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFunctionPass.h
@@ -0,0 +1,50 @@
+//===-- MachineFunctionPass.h - Pass for MachineFunctions --------*-C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MachineFunctionPass class. MachineFunctionPass's are
+// just FunctionPass's, except they operate on machine code as part of a code
+// generator. Because they operate on machine code, not the LLVM
+// representation, MachineFunctionPass's are not allowed to modify the LLVM
+// representation. Due to this limitation, the MachineFunctionPass class takes
+// care of declaring that no LLVM passes are invalidated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H
+#define LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H
+
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+
+struct MachineFunctionPass : public FunctionPass {
+
+ explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {}
+
+protected:
+ /// runOnMachineFunction - This method must be overloaded to perform the
+ /// desired machine code transformation or analysis.
+ ///
+ virtual bool runOnMachineFunction(MachineFunction &MF) = 0;
+
+public:
+ // FIXME: This pass should declare that the pass does not invalidate any LLVM
+ // passes.
+ bool runOnFunction(Function &F) {
+ return runOnMachineFunction(MachineFunction::get(&F));
+ }
+
+private:
+ virtual void virtfn(); // out of line virtual fn to give class a home.
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
new file mode 100644
index 0000000..1f621c1
--- /dev/null
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -0,0 +1,567 @@
+//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MachineInstr class, which is the
+// basic representation for all target dependent machine instructions used by
+// the back end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTR_H
+#define LLVM_CODEGEN_MACHINEINSTR_H
+
+#include "llvm/ADT/iterator"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
+#include <vector>
+#include <cassert>
+#include <iosfwd>
+
+namespace llvm {
+
+class Value;
+class Function;
+class MachineBasicBlock;
+class TargetInstrDescriptor;
+class TargetMachine;
+class GlobalValue;
+
+template <typename T> struct ilist_traits;
+template <typename T> struct ilist;
+
+//===----------------------------------------------------------------------===//
+// class MachineOperand
+//
+// Representation of each machine instruction operand.
+//
+struct MachineOperand {
+ enum MachineOperandType {
+ MO_Register, // Register operand.
+ MO_Immediate, // Immediate Operand
+ MO_MachineBasicBlock, // MachineBasicBlock reference
+ MO_FrameIndex, // Abstract Stack Frame Index
+ MO_ConstantPoolIndex, // Address of indexed Constant in Constant Pool
+ MO_JumpTableIndex, // Address of indexed Jump Table for switch
+ MO_ExternalSymbol, // Name of external global symbol
+ MO_GlobalAddress // Address of a global value
+ };
+
+private:
+ union {
+ GlobalValue *GV; // For MO_GlobalAddress.
+ MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
+ const char *SymbolName; // For MO_ExternalSymbol.
+ unsigned RegNo; // For MO_Register.
+ int64_t immedVal; // For MO_Immediate and MO_*Index.
+ } contents;
+
+ MachineOperandType opType:8; // Discriminate the union.
+ bool IsDef : 1; // True if this is a def, false if this is a use.
+ bool IsImp : 1; // True if this is an implicit def or use.
+
+ bool IsKill : 1; // True if this is a reg use and the reg is dead
+ // immediately after the read.
+ bool IsDead : 1; // True if this is a reg def and the reg is dead
+ // immediately after the write. i.e. A register
+ // that is defined but never used.
+
+ /// auxInfo - auxiliary information used by the MachineOperand
+ union {
+ /// offset - Offset to address of global or external, only valid for
+ /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
+ int offset;
+
+ /// subReg - SubRegister number, only valid for MO_Register. A value of 0
+ /// indicates the MO_Register has no subReg.
+ unsigned subReg;
+ } auxInfo;
+
+ MachineOperand() {}
+
+ void print(std::ostream &os) const;
+ void print(std::ostream *os) const { if (os) print(*os); }
+
+public:
+ MachineOperand(const MachineOperand &M) {
+ *this = M;
+ }
+
+ ~MachineOperand() {}
+
+ static MachineOperand CreateImm(int64_t Val) {
+ MachineOperand Op;
+ Op.opType = MachineOperand::MO_Immediate;
+ Op.contents.immedVal = Val;
+ Op.IsDef = false;
+ Op.IsImp = false;
+ Op.IsKill = false;
+ Op.IsDead = false;
+ Op.auxInfo.offset = 0;
+ return Op;
+ }
+
+ const MachineOperand &operator=(const MachineOperand &MO) {
+ contents = MO.contents;
+ IsDef = MO.IsDef;
+ IsImp = MO.IsImp;
+ IsKill = MO.IsKill;
+ IsDead = MO.IsDead;
+ opType = MO.opType;
+ auxInfo = MO.auxInfo;
+ return *this;
+ }
+
+ /// getType - Returns the MachineOperandType for this operand.
+ ///
+ MachineOperandType getType() const { return opType; }
+
+ /// Accessors that tell you what kind of MachineOperand you're looking at.
+ ///
+ bool isReg() const { return opType == MO_Register; }
+ bool isImm() const { return opType == MO_Immediate; }
+ bool isMBB() const { return opType == MO_MachineBasicBlock; }
+
+ bool isRegister() const { return opType == MO_Register; }
+ bool isImmediate() const { return opType == MO_Immediate; }
+ bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
+ bool isFrameIndex() const { return opType == MO_FrameIndex; }
+ bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; }
+ bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; }
+ bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
+ bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
+
+ int64_t getImm() const {
+ assert(isImm() && "Wrong MachineOperand accessor");
+ return contents.immedVal;
+ }
+
+ int64_t getImmedValue() const {
+ assert(isImm() && "Wrong MachineOperand accessor");
+ return contents.immedVal;
+ }
+ MachineBasicBlock *getMBB() const {
+ assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
+ return contents.MBB;
+ }
+ MachineBasicBlock *getMachineBasicBlock() const {
+ assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
+ return contents.MBB;
+ }
+ void setMachineBasicBlock(MachineBasicBlock *MBB) {
+ assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
+ contents.MBB = MBB;
+ }
+ int getFrameIndex() const {
+ assert(isFrameIndex() && "Wrong MachineOperand accessor");
+ return (int)contents.immedVal;
+ }
+ unsigned getConstantPoolIndex() const {
+ assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
+ return (unsigned)contents.immedVal;
+ }
+ unsigned getJumpTableIndex() const {
+ assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
+ return (unsigned)contents.immedVal;
+ }
+ GlobalValue *getGlobal() const {
+ assert(isGlobalAddress() && "Wrong MachineOperand accessor");
+ return contents.GV;
+ }
+ int getOffset() const {
+ assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
+ "Wrong MachineOperand accessor");
+ return auxInfo.offset;
+ }
+ unsigned getSubReg() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return auxInfo.subReg;
+ }
+ const char *getSymbolName() const {
+ assert(isExternalSymbol() && "Wrong MachineOperand accessor");
+ return contents.SymbolName;
+ }
+
+ bool isUse() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return !IsDef;
+ }
+ bool isDef() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsDef;
+ }
+ void setIsUse() {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ IsDef = false;
+ }
+ void setIsDef() {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ IsDef = true;
+ }
+
+ bool isImplicit() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsImp;
+ }
+ void setImplicit() {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ IsImp = true;
+ }
+
+ bool isKill() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsKill;
+ }
+ bool isDead() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsDead;
+ }
+ void setIsKill() {
+ assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
+ IsKill = true;
+ }
+ void setIsDead() {
+ assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
+ IsDead = true;
+ }
+ void unsetIsKill() {
+ assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
+ IsKill = false;
+ }
+ void unsetIsDead() {
+ assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
+ IsDead = false;
+ }
+
+ /// getReg - Returns the register number.
+ ///
+ unsigned getReg() const {
+ assert(isRegister() && "This is not a register operand!");
+ return contents.RegNo;
+ }
+
+ /// MachineOperand mutators.
+ ///
+ void setReg(unsigned Reg) {
+ assert(isRegister() && "This is not a register operand!");
+ contents.RegNo = Reg;
+ }
+
+ void setImmedValue(int64_t immVal) {
+ assert(isImm() && "Wrong MachineOperand mutator");
+ contents.immedVal = immVal;
+ }
+ void setImm(int64_t immVal) {
+ assert(isImm() && "Wrong MachineOperand mutator");
+ contents.immedVal = immVal;
+ }
+
+ void setOffset(int Offset) {
+ assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
+ isJumpTableIndex()) &&
+ "Wrong MachineOperand accessor");
+ auxInfo.offset = Offset;
+ }
+ void setSubReg(unsigned subReg) {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ auxInfo.subReg = subReg;
+ }
+ void setConstantPoolIndex(unsigned Idx) {
+ assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
+ contents.immedVal = Idx;
+ }
+ void setJumpTableIndex(unsigned Idx) {
+ assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
+ contents.immedVal = Idx;
+ }
+
+ /// isIdenticalTo - Return true if this operand is identical to the specified
+ /// operand. Note: This method ignores isKill and isDead properties.
+ bool isIdenticalTo(const MachineOperand &Other) const;
+
+ /// ChangeToImmediate - Replace this operand with a new immediate operand of
+ /// the specified value. If an operand is known to be an immediate already,
+ /// the setImmedValue method should be used.
+ void ChangeToImmediate(int64_t ImmVal) {
+ opType = MO_Immediate;
+ contents.immedVal = ImmVal;
+ }
+
+ /// ChangeToRegister - Replace this operand with a new register operand of
+ /// the specified value. If an operand is known to be an register already,
+ /// the setReg method should be used.
+ void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
+ bool isKill = false, bool isDead = false) {
+ opType = MO_Register;
+ contents.RegNo = Reg;
+ IsDef = isDef;
+ IsImp = isImp;
+ IsKill = isKill;
+ IsDead = isDead;
+ }
+
+ friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop) {
+ mop.print(os);
+ return os;
+ }
+
+ friend class MachineInstr;
+};
+
+
+//===----------------------------------------------------------------------===//
+/// MachineInstr - Representation of each machine instruction.
+///
+class MachineInstr {
+ const TargetInstrDescriptor *TID; // Instruction descriptor.
+ unsigned short NumImplicitOps; // Number of implicit operands (which
+ // are determined at construction time).
+
+ std::vector<MachineOperand> Operands; // the operands
+ MachineInstr* prev, *next; // links for our intrusive list
+ MachineBasicBlock* parent; // pointer to the owning basic block
+
+ // OperandComplete - Return true if it's illegal to add a new operand
+ bool OperandsComplete() const;
+
+ MachineInstr(const MachineInstr&);
+ void operator=(const MachineInstr&); // DO NOT IMPLEMENT
+
+ // Intrusive list support
+ //
+ friend struct ilist_traits<MachineInstr>;
+
+public:
+ /// MachineInstr ctor - This constructor creates a dummy MachineInstr with
+ /// TID NULL and no operands.
+ MachineInstr();
+
+ /// MachineInstr ctor - This constructor create a MachineInstr and add the
+ /// implicit operands. It reserves space for number of operands specified by
+ /// TargetInstrDescriptor.
+ explicit MachineInstr(const TargetInstrDescriptor &TID);
+
+ /// MachineInstr ctor - Work exactly the same as the ctor above, except that
+ /// the MachineInstr is created and added to the end of the specified basic
+ /// block.
+ ///
+ MachineInstr(MachineBasicBlock *MBB, const TargetInstrDescriptor &TID);
+
+ ~MachineInstr();
+
+ const MachineBasicBlock* getParent() const { return parent; }
+ MachineBasicBlock* getParent() { return parent; }
+
+ /// getInstrDescriptor - Returns the target instruction descriptor of this
+ /// MachineInstr.
+ const TargetInstrDescriptor *getInstrDescriptor() const { return TID; }
+
+ /// getOpcode - Returns the opcode of this MachineInstr.
+ ///
+ const int getOpcode() const;
+
+ /// Access to explicit operands of the instruction.
+ ///
+ unsigned getNumOperands() const { return Operands.size(); }
+
+ const MachineOperand& getOperand(unsigned i) const {
+ assert(i < getNumOperands() && "getOperand() out of range!");
+ return Operands[i];
+ }
+ MachineOperand& getOperand(unsigned i) {
+ assert(i < getNumOperands() && "getOperand() out of range!");
+ return Operands[i];
+ }
+
+ /// getNumExplicitOperands - Returns the number of non-implicit operands.
+ ///
+ unsigned getNumExplicitOperands() const;
+
+ /// isIdenticalTo - Return true if this instruction is identical to (same
+ /// opcode and same operands as) the specified instruction.
+ bool isIdenticalTo(const MachineInstr *Other) const {
+ if (Other->getOpcode() != getOpcode() ||
+ Other->getNumOperands() != getNumOperands())
+ return false;
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (!getOperand(i).isIdenticalTo(Other->getOperand(i)))
+ return false;
+ return true;
+ }
+
+ /// clone - Create a copy of 'this' instruction that is identical in
+ /// all ways except the the instruction has no parent, prev, or next.
+ MachineInstr* clone() const { return new MachineInstr(*this); }
+
+ /// removeFromParent - This method unlinks 'this' from the containing basic
+ /// block, and returns it, but does not delete it.
+ MachineInstr *removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing basic
+ /// block and deletes it.
+ void eraseFromParent() {
+ delete removeFromParent();
+ }
+
+ /// findRegisterUseOperandIdx() - Returns the operand index that is a use of
+ /// the specific register or -1 if it is not found. It further tightening
+ /// the search criteria to a use that kills the register if isKill is true.
+ int findRegisterUseOperandIdx(unsigned Reg, bool isKill = false) const;
+
+ /// findRegisterDefOperand() - Returns the MachineOperand that is a def of
+ /// the specific register or NULL if it is not found.
+ MachineOperand *findRegisterDefOperand(unsigned Reg);
+
+ /// findFirstPredOperandIdx() - Find the index of the first operand in the
+ /// operand list that is used to represent the predicate. It returns -1 if
+ /// none is found.
+ int findFirstPredOperandIdx() const;
+
+ /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
+ ///
+ void copyKillDeadInfo(const MachineInstr *MI);
+
+ /// copyPredicates - Copies predicate operand(s) from MI.
+ void copyPredicates(const MachineInstr *MI);
+
+ //
+ // Debugging support
+ //
+ void print(std::ostream *OS, const TargetMachine *TM) const {
+ if (OS) print(*OS, TM);
+ }
+ void print(std::ostream &OS, const TargetMachine *TM) const;
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ void dump() const;
+ friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr){
+ minstr.print(os);
+ return os;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Accessors to add operands when building up machine instructions.
+ //
+
+ /// addRegOperand - Add a register operand.
+ ///
+ void addRegOperand(unsigned Reg, bool IsDef, bool IsImp = false,
+ bool IsKill = false, bool IsDead = false) {
+ MachineOperand &Op = AddNewOperand(IsImp);
+ Op.opType = MachineOperand::MO_Register;
+ Op.IsDef = IsDef;
+ Op.IsImp = IsImp;
+ Op.IsKill = IsKill;
+ Op.IsDead = IsDead;
+ Op.contents.RegNo = Reg;
+ Op.auxInfo.subReg = 0;
+ }
+
+ /// addImmOperand - Add a zero extended constant argument to the
+ /// machine instruction.
+ ///
+ void addImmOperand(int64_t Val) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_Immediate;
+ Op.contents.immedVal = Val;
+ Op.auxInfo.offset = 0;
+ }
+
+ void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_MachineBasicBlock;
+ Op.contents.MBB = MBB;
+ Op.auxInfo.offset = 0;
+ }
+
+ /// addFrameIndexOperand - Add an abstract frame index to the instruction
+ ///
+ void addFrameIndexOperand(unsigned Idx) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_FrameIndex;
+ Op.contents.immedVal = Idx;
+ Op.auxInfo.offset = 0;
+ }
+
+ /// addConstantPoolndexOperand - Add a constant pool object index to the
+ /// instruction.
+ ///
+ void addConstantPoolIndexOperand(unsigned Idx, int Offset) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_ConstantPoolIndex;
+ Op.contents.immedVal = Idx;
+ Op.auxInfo.offset = Offset;
+ }
+
+ /// addJumpTableIndexOperand - Add a jump table object index to the
+ /// instruction.
+ ///
+ void addJumpTableIndexOperand(unsigned Idx) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_JumpTableIndex;
+ Op.contents.immedVal = Idx;
+ Op.auxInfo.offset = 0;
+ }
+
+ void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_GlobalAddress;
+ Op.contents.GV = GV;
+ Op.auxInfo.offset = Offset;
+ }
+
+ /// addExternalSymbolOperand - Add an external symbol operand to this instr
+ ///
+ void addExternalSymbolOperand(const char *SymName) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_ExternalSymbol;
+ Op.contents.SymbolName = SymName;
+ Op.auxInfo.offset = 0;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Accessors used to modify instructions in place.
+ //
+
+ /// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of
+ /// the current instruction with a new one.
+ ///
+ void setInstrDescriptor(const TargetInstrDescriptor &tid) { TID = &tid; }
+
+ /// RemoveOperand - Erase an operand from an instruction, leaving it with one
+ /// fewer operand than it started with.
+ ///
+ void RemoveOperand(unsigned i) {
+ Operands.erase(Operands.begin()+i);
+ }
+private:
+ MachineOperand &AddNewOperand(bool IsImp = false) {
+ assert((IsImp || !OperandsComplete()) &&
+ "Trying to add an operand to a machine instr that is already done!");
+ if (IsImp || NumImplicitOps == 0) { // This is true most of the time.
+ Operands.push_back(MachineOperand());
+ return Operands.back();
+ }
+ return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps,
+ MachineOperand());
+ }
+
+ /// addImplicitDefUseOperands - Add all implicit def and use operands to
+ /// this instruction.
+ void addImplicitDefUseOperands();
+};
+
+//===----------------------------------------------------------------------===//
+// Debugging Support
+
+std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI);
+std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
new file mode 100644
index 0000000..eb45b6e
--- /dev/null
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -0,0 +1,147 @@
+//===-- CodeGen/MachineInstBuilder.h - Simplify creation of MIs -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes a function named BuildMI, which is useful for dramatically
+// simplifying how MachineInstr's are created. It allows use of code like this:
+//
+// M = BuildMI(X86::ADDrr8, 2).addReg(argVal1).addReg(argVal2);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+
+class TargetInstrDescriptor;
+
+class MachineInstrBuilder {
+ MachineInstr *MI;
+public:
+ explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
+
+ /// Allow automatic conversion to the machine instruction we are working on.
+ ///
+ operator MachineInstr*() const { return MI; }
+ operator MachineBasicBlock::iterator() const { return MI; }
+
+ /// addReg - Add a new virtual register operand...
+ ///
+ const
+ MachineInstrBuilder &addReg(int RegNo, bool isDef = false, bool isImp = false,
+ bool isKill = false, bool isDead = false) const {
+ MI->addRegOperand(RegNo, isDef, isImp, isKill, isDead);
+ return *this;
+ }
+
+ /// addImm - Add a new immediate operand.
+ ///
+ const MachineInstrBuilder &addImm(int64_t Val) const {
+ MI->addImmOperand(Val);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB) const {
+ MI->addMachineBasicBlockOperand(MBB);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addFrameIndex(unsigned Idx) const {
+ MI->addFrameIndexOperand(Idx);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
+ int Offset = 0) const {
+ MI->addConstantPoolIndexOperand(Idx, Offset);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addJumpTableIndex(unsigned Idx) const {
+ MI->addJumpTableIndexOperand(Idx);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
+ int Offset = 0) const {
+ MI->addGlobalAddressOperand(GV, Offset);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addExternalSymbol(const char *FnName) const{
+ MI->addExternalSymbolOperand(FnName);
+ return *this;
+ }
+};
+
+/// BuildMI - Builder interface. Specify how to create the initial instruction
+/// itself.
+///
+inline MachineInstrBuilder BuildMI(const TargetInstrDescriptor &TID) {
+ return MachineInstrBuilder(new MachineInstr(TID));
+}
+
+/// BuildMI - This version of the builder sets up the first operand as a
+/// destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(const TargetInstrDescriptor &TID,
+ unsigned DestReg) {
+ return MachineInstrBuilder(new MachineInstr(TID)).addReg(DestReg, true);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction before the given position in the given MachineBasicBlock, and
+/// sets up the first operand as a destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ const TargetInstrDescriptor &TID,
+ unsigned DestReg) {
+ MachineInstr *MI = new MachineInstr(TID);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI).addReg(DestReg, true);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction before the given position in the given MachineBasicBlock, and
+/// does NOT take a destination register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ const TargetInstrDescriptor &TID) {
+ MachineInstr *MI = new MachineInstr(TID);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction at the end of the given MachineBasicBlock, and does NOT take a
+/// destination register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+ const TargetInstrDescriptor &TID) {
+ return BuildMI(*BB, BB->end(), TID);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction at the end of the given MachineBasicBlock, and sets up the first
+/// operand as a destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+ const TargetInstrDescriptor &TID,
+ unsigned DestReg) {
+ return BuildMI(*BB, BB->end(), TID, DestReg);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
new file mode 100644
index 0000000..d440268
--- /dev/null
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -0,0 +1,103 @@
+//===-- CodeGen/MachineJumpTableInfo.h - Abstract Jump Tables --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The MachineJumpTableInfo class keeps track of jump tables referenced by
+// lowered switch instructions in the MachineFunction.
+//
+// Instructions reference the address of these jump tables through the use of
+// MO_JumpTableIndex values. When emitting assembly or machine code, these
+// virtual address references are converted to refer to the address of the
+// function jump tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
+#define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
+
+#include <vector>
+#include <iosfwd>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class TargetData;
+
+/// MachineJumpTableEntry - One jump table in the jump table info.
+///
+struct MachineJumpTableEntry {
+ /// MBBs - The vector of basic blocks from which to create the jump table.
+ std::vector<MachineBasicBlock*> MBBs;
+
+ explicit MachineJumpTableEntry(const std::vector<MachineBasicBlock*> &M)
+ : MBBs(M) {}
+};
+
+class MachineJumpTableInfo {
+ unsigned EntrySize;
+ unsigned Alignment;
+ std::vector<MachineJumpTableEntry> JumpTables;
+public:
+ MachineJumpTableInfo(unsigned Size, unsigned Align)
+ : EntrySize(Size), Alignment(Align) {}
+
+ /// getJumpTableIndex - Create a new jump table or return an existing one.
+ ///
+ unsigned getJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
+
+ /// isEmpty - Return true if there are no jump tables.
+ ///
+ bool isEmpty() const { return JumpTables.empty(); }
+
+ const std::vector<MachineJumpTableEntry> &getJumpTables() const {
+ return JumpTables;
+ }
+
+ /// RemoveJumpTable - Mark the specific index as being dead. This will cause
+ /// it to not be emitted.
+ void RemoveJumpTable(unsigned Idx) {
+ JumpTables[Idx].MBBs.clear();
+ }
+
+ /// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
+ /// the jump tables to branch to New instead.
+ bool ReplaceMBBInJumpTables(MachineBasicBlock *Old, MachineBasicBlock *New) {
+ assert(Old != New && "Not making a change?");
+ bool MadeChange = false;
+ for (unsigned i = 0, e = JumpTables.size(); i != e; ++i) {
+ MachineJumpTableEntry &JTE = JumpTables[i];
+ for (unsigned j = 0, e = JTE.MBBs.size(); j != e; ++j)
+ if (JTE.MBBs[j] == Old) {
+ JTE.MBBs[j] = New;
+ MadeChange = true;
+ }
+ }
+ return MadeChange;
+ }
+
+ /// 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
+ ///
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// dump - Call print(std::cerr) to be called from the debugger.
+ ///
+ void dump() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineLocation.h b/include/llvm/CodeGen/MachineLocation.h
new file mode 100644
index 0000000..c0a78ae
--- /dev/null
+++ b/include/llvm/CodeGen/MachineLocation.h
@@ -0,0 +1,106 @@
+//===-- llvm/CodeGen/MachineLocation.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// The MachineLocation class is used to represent a simple location in a machine
+// frame. Locations will be one of two forms; a register or an address formed
+// from a base address plus an offset. Register indirection can be specified by
+// using an offset of zero.
+//
+// The MachineMove class is used to represent abstract move operations in the
+// prolog/epilog of a compiled function. A collection of these objects can be
+// used by a debug consumer to track the location of values when unwinding stack
+// frames.
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_MACHINELOCATION_H
+#define LLVM_CODEGEN_MACHINELOCATION_H
+
+namespace llvm {
+
+class MachineLocation {
+private:
+ bool IsRegister; // True if location is a register.
+ unsigned Register; // gcc/gdb register number.
+ int Offset; // Displacement if not register.
+
+public:
+ enum {
+ // The target register number for an abstract frame pointer. The value is
+ // an arbitrary value greater than MRegisterInfo::FirstVirtualRegister.
+ VirtualFP = ~0U
+ };
+ MachineLocation()
+ : IsRegister(false)
+ , Register(0)
+ , Offset(0)
+ {}
+ explicit MachineLocation(unsigned R)
+ : IsRegister(true)
+ , Register(R)
+ , Offset(0)
+ {}
+ MachineLocation(unsigned R, int O)
+ : IsRegister(false)
+ , Register(R)
+ , Offset(O)
+ {}
+
+ // Accessors
+ bool isRegister() const { return IsRegister; }
+ unsigned getRegister() const { return Register; }
+ int getOffset() const { return Offset; }
+ void setIsRegister(bool Is) { IsRegister = Is; }
+ void setRegister(unsigned R) { Register = R; }
+ void setOffset(int O) { Offset = O; }
+ void set(unsigned R) {
+ IsRegister = true;
+ Register = R;
+ Offset = 0;
+ }
+ void set(unsigned R, int O) {
+ IsRegister = false;
+ Register = R;
+ Offset = O;
+ }
+
+#ifndef NDEBUG
+ void dump();
+#endif
+};
+
+class MachineMove {
+private:
+ unsigned LabelID; // Label ID number for post-instruction
+ // address when result of move takes
+ // effect.
+ MachineLocation Destination; // Move to location.
+ MachineLocation Source; // Move from location.
+
+public:
+ MachineMove()
+ : LabelID(0)
+ , Destination()
+ , Source()
+ {}
+
+ MachineMove(unsigned ID, MachineLocation &D, MachineLocation &S)
+ : LabelID(ID)
+ , Destination(D)
+ , Source(S)
+ {}
+
+ // Accessors
+ unsigned getLabelID() const { return LabelID; }
+ const MachineLocation &getDestination() const { return Destination; }
+ const MachineLocation &getSource() const { return Source; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
new file mode 100644
index 0000000..778b75c
--- /dev/null
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -0,0 +1,1280 @@
+//===-- llvm/CodeGen/MachineModuleInfo.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect meta information for a module. This information should be in a
+// neutral form that can be used by different debugging and exception handling
+// schemes.
+//
+// The organization of information is primarily clustered around the source
+// compile units. The main exception is source line correspondence where
+// inlining may interleave code from various compile units.
+//
+// The following information can be retrieved from the MachineModuleInfo.
+//
+// -- Source directories - Directories are uniqued based on their canonical
+// string and assigned a sequential numeric ID (base 1.)
+// -- Source files - Files are also uniqued based on their name and directory
+// ID. A file ID is sequential number (base 1.)
+// -- Source line correspondence - A vector of file ID, line#, column# triples.
+// A DEBUG_LOCATION instruction is generated by the DAG Legalizer
+// corresponding to each entry in the source line list. This allows a debug
+// emitter to generate labels referenced by debug information tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H
+#define LLVM_CODEGEN_MACHINEMODULEINFO_H
+
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/UniqueVector.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Forward declarations.
+class Constant;
+class DebugInfoDesc;
+class GlobalVariable;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineMove;
+class Module;
+class PointerType;
+class StructType;
+
+//===----------------------------------------------------------------------===//
+// Debug info constants.
+
+enum {
+ LLVMDebugVersion = (6 << 16), // Current version of debug information.
+ LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
+ LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
+ LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
+};
+
+//===----------------------------------------------------------------------===//
+/// DIVisitor - Subclasses of this class apply steps to each of the fields in
+/// the supplied DebugInfoDesc.
+class DIVisitor {
+public:
+ DIVisitor() {}
+ virtual ~DIVisitor() {}
+
+ /// ApplyToFields - Target the visitor to each field of the debug information
+ /// descriptor.
+ void ApplyToFields(DebugInfoDesc *DD);
+
+ /// Apply - Subclasses override each of these methods to perform the
+ /// appropriate action for the type of field.
+ virtual void Apply(int &Field) = 0;
+ virtual void Apply(unsigned &Field) = 0;
+ virtual void Apply(int64_t &Field) = 0;
+ virtual void Apply(uint64_t &Field) = 0;
+ virtual void Apply(bool &Field) = 0;
+ virtual void Apply(std::string &Field) = 0;
+ virtual void Apply(DebugInfoDesc *&Field) = 0;
+ virtual void Apply(GlobalVariable *&Field) = 0;
+ virtual void Apply(std::vector<DebugInfoDesc *> &Field) = 0;
+};
+
+//===----------------------------------------------------------------------===//
+/// DebugInfoDesc - This class is the base class for debug info descriptors.
+///
+class DebugInfoDesc {
+private:
+ unsigned Tag; // Content indicator. Dwarf values are
+ // used but that does not limit use to
+ // Dwarf writers.
+
+protected:
+ explicit DebugInfoDesc(unsigned T) : Tag(T | LLVMDebugVersion) {}
+
+public:
+ virtual ~DebugInfoDesc() {}
+
+ // Accessors
+ unsigned getTag() const { return Tag & ~LLVMDebugVersionMask; }
+ unsigned getVersion() const { return Tag & LLVMDebugVersionMask; }
+ void setTag(unsigned T) { Tag = T | LLVMDebugVersion; }
+
+ /// TagFromGlobal - Returns the tag number from a debug info descriptor
+ /// GlobalVariable. Return DIIValid if operand is not an unsigned int.
+ static unsigned TagFromGlobal(GlobalVariable *GV);
+
+ /// VersionFromGlobal - Returns the version number from a debug info
+ /// descriptor GlobalVariable. Return DIIValid if operand is not an unsigned
+ /// int.
+ static unsigned VersionFromGlobal(GlobalVariable *GV);
+
+ /// DescFactory - Create an instance of debug info descriptor based on Tag.
+ /// Return NULL if not a recognized Tag.
+ static DebugInfoDesc *DescFactory(unsigned Tag);
+
+ /// getLinkage - get linkage appropriate for this type of descriptor.
+ ///
+ virtual GlobalValue::LinkageTypes getLinkage() const;
+
+ //===--------------------------------------------------------------------===//
+ // Subclasses should supply the following static methods.
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DebugInfoDesc *) { return true; }
+
+ //===--------------------------------------------------------------------===//
+ // Subclasses should supply the following virtual methods.
+
+ /// ApplyToFields - Target the vistor to the fields of the descriptor.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const = 0;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const = 0;
+
+#ifndef NDEBUG
+ virtual void dump() = 0;
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// AnchorDesc - Descriptors of this class act as markers for identifying
+/// descriptors of certain groups.
+class AnchoredDesc;
+class AnchorDesc : public DebugInfoDesc {
+private:
+ unsigned AnchorTag; // Tag number of descriptors anchored
+ // by this object.
+
+public:
+ AnchorDesc();
+ AnchorDesc(AnchoredDesc *D);
+
+ // Accessors
+ unsigned getAnchorTag() const { return AnchorTag; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const AnchorDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// getLinkage - get linkage appropriate for this type of descriptor.
+ ///
+ virtual GlobalValue::LinkageTypes getLinkage() const;
+
+ /// ApplyToFields - Target the visitor to the fields of the AnchorDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// AnchoredDesc - This class manages anchors for a variety of top level
+/// descriptors.
+class AnchoredDesc : public DebugInfoDesc {
+private:
+ DebugInfoDesc *Anchor; // Anchor for all descriptors of the
+ // same type.
+
+protected:
+
+ AnchoredDesc(unsigned T);
+
+public:
+ // Accessors.
+ AnchorDesc *getAnchor() const { return static_cast<AnchorDesc *>(Anchor); }
+ void setAnchor(AnchorDesc *A) { Anchor = static_cast<DebugInfoDesc *>(A); }
+
+ //===--------------------------------------------------------------------===//
+ // Subclasses should supply the following virtual methods.
+
+ /// getAnchorString - Return a string used to label descriptor's anchor.
+ ///
+ virtual const char *getAnchorString() const = 0;
+
+ /// ApplyToFields - Target the visitor to the fields of the AnchoredDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+};
+
+//===----------------------------------------------------------------------===//
+/// CompileUnitDesc - This class packages debug information associated with a
+/// source/header file.
+class CompileUnitDesc : public AnchoredDesc {
+private:
+ unsigned Language; // Language number (ex. DW_LANG_C89.)
+ std::string FileName; // Source file name.
+ std::string Directory; // Source file directory.
+ std::string Producer; // Compiler string.
+
+public:
+ CompileUnitDesc();
+
+
+ // Accessors
+ unsigned getLanguage() const { return Language; }
+ const std::string &getFileName() const { return FileName; }
+ const std::string &getDirectory() const { return Directory; }
+ const std::string &getProducer() const { return Producer; }
+ void setLanguage(unsigned L) { Language = L; }
+ void setFileName(const std::string &FN) { FileName = FN; }
+ void setDirectory(const std::string &D) { Directory = D; }
+ void setProducer(const std::string &P) { Producer = P; }
+
+ // FIXME - Need translation unit getter/setter.
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const CompileUnitDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+ /// getAnchorString - Return a string used to label this descriptor's anchor.
+ ///
+ static const char *AnchorString;
+ virtual const char *getAnchorString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// TypeDesc - This class packages debug information associated with a type.
+///
+class TypeDesc : public DebugInfoDesc {
+private:
+ enum {
+ FlagPrivate = 1 << 0,
+ FlagProtected = 1 << 1
+ };
+ DebugInfoDesc *Context; // Context debug descriptor.
+ std::string Name; // Type name (may be empty.)
+ DebugInfoDesc *File; // Defined compile unit (may be NULL.)
+ unsigned Line; // Defined line# (may be zero.)
+ uint64_t Size; // Type bit size (may be zero.)
+ uint64_t Align; // Type bit alignment (may be zero.)
+ uint64_t Offset; // Type bit offset (may be zero.)
+ unsigned Flags; // Miscellaneous flags.
+
+public:
+ TypeDesc(unsigned T);
+
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ const std::string &getName() const { return Name; }
+ CompileUnitDesc *getFile() const {
+ return static_cast<CompileUnitDesc *>(File);
+ }
+ unsigned getLine() const { return Line; }
+ uint64_t getSize() const { return Size; }
+ uint64_t getAlign() const { return Align; }
+ uint64_t getOffset() const { return Offset; }
+ bool isPrivate() const {
+ return (Flags & FlagPrivate) != 0;
+ }
+ bool isProtected() const {
+ return (Flags & FlagProtected) != 0;
+ }
+ void setContext(DebugInfoDesc *C) { Context = C; }
+ void setName(const std::string &N) { Name = N; }
+ void setFile(CompileUnitDesc *U) {
+ File = static_cast<DebugInfoDesc *>(U);
+ }
+ void setLine(unsigned L) { Line = L; }
+ void setSize(uint64_t S) { Size = S; }
+ void setAlign(uint64_t A) { Align = A; }
+ void setOffset(uint64_t O) { Offset = O; }
+ void setIsPrivate() { Flags |= FlagPrivate; }
+ void setIsProtected() { Flags |= FlagProtected; }
+
+ /// ApplyToFields - Target the visitor to the fields of the TypeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// BasicTypeDesc - This class packages debug information associated with a
+/// basic type (eg. int, bool, double.)
+class BasicTypeDesc : public TypeDesc {
+private:
+ unsigned Encoding; // Type encoding.
+
+public:
+ BasicTypeDesc();
+
+ // Accessors
+ unsigned getEncoding() const { return Encoding; }
+ void setEncoding(unsigned E) { Encoding = E; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const BasicTypeDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+
+//===----------------------------------------------------------------------===//
+/// DerivedTypeDesc - This class packages debug information associated with a
+/// derived types (eg., typedef, pointer, reference.)
+class DerivedTypeDesc : public TypeDesc {
+private:
+ DebugInfoDesc *FromType; // Type derived from.
+
+public:
+ DerivedTypeDesc(unsigned T);
+
+ // Accessors
+ TypeDesc *getFromType() const {
+ return static_cast<TypeDesc *>(FromType);
+ }
+ void setFromType(TypeDesc *F) {
+ FromType = static_cast<DebugInfoDesc *>(F);
+ }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DerivedTypeDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// CompositeTypeDesc - This class packages debug information associated with a
+/// array/struct types (eg., arrays, struct, union, enums.)
+class CompositeTypeDesc : public DerivedTypeDesc {
+private:
+ std::vector<DebugInfoDesc *> Elements;// Information used to compose type.
+
+public:
+ CompositeTypeDesc(unsigned T);
+
+ // Accessors
+ std::vector<DebugInfoDesc *> &getElements() { return Elements; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const CompositeTypeDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// SubrangeDesc - This class packages debug information associated with integer
+/// value ranges.
+class SubrangeDesc : public DebugInfoDesc {
+private:
+ int64_t Lo; // Low value of range.
+ int64_t Hi; // High value of range.
+
+public:
+ SubrangeDesc();
+
+ // Accessors
+ int64_t getLo() const { return Lo; }
+ int64_t getHi() const { return Hi; }
+ void setLo(int64_t L) { Lo = L; }
+ void setHi(int64_t H) { Hi = H; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const SubrangeDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the SubrangeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// EnumeratorDesc - This class packages debug information associated with
+/// named integer constants.
+class EnumeratorDesc : public DebugInfoDesc {
+private:
+ std::string Name; // Enumerator name.
+ int64_t Value; // Enumerator value.
+
+public:
+ EnumeratorDesc();
+
+ // Accessors
+ const std::string &getName() const { return Name; }
+ int64_t getValue() const { return Value; }
+ void setName(const std::string &N) { Name = N; }
+ void setValue(int64_t V) { Value = V; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const EnumeratorDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// VariableDesc - This class packages debug information associated with a
+/// subprogram variable.
+///
+class VariableDesc : public DebugInfoDesc {
+private:
+ DebugInfoDesc *Context; // Context debug descriptor.
+ std::string Name; // Type name (may be empty.)
+ DebugInfoDesc *File; // Defined compile unit (may be NULL.)
+ unsigned Line; // Defined line# (may be zero.)
+ DebugInfoDesc *TyDesc; // Type of variable.
+
+public:
+ VariableDesc(unsigned T);
+
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ const std::string &getName() const { return Name; }
+ CompileUnitDesc *getFile() const {
+ return static_cast<CompileUnitDesc *>(File);
+ }
+ unsigned getLine() const { return Line; }
+ TypeDesc *getType() const {
+ return static_cast<TypeDesc *>(TyDesc);
+ }
+ void setContext(DebugInfoDesc *C) { Context = C; }
+ void setName(const std::string &N) { Name = N; }
+ void setFile(CompileUnitDesc *U) {
+ File = static_cast<DebugInfoDesc *>(U);
+ }
+ void setLine(unsigned L) { Line = L; }
+ void setType(TypeDesc *T) {
+ TyDesc = static_cast<DebugInfoDesc *>(T);
+ }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const VariableDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the VariableDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// GlobalDesc - This class is the base descriptor for global functions and
+/// variables.
+class GlobalDesc : public AnchoredDesc {
+private:
+ DebugInfoDesc *Context; // Context debug descriptor.
+ std::string Name; // Global name.
+ std::string FullName; // Fully qualified name.
+ std::string LinkageName; // Name for binding to MIPS linkage.
+ DebugInfoDesc *File; // Defined compile unit (may be NULL.)
+ unsigned Line; // Defined line# (may be zero.)
+ DebugInfoDesc *TyDesc; // Type debug descriptor.
+ bool IsStatic; // Is the global a static.
+ bool IsDefinition; // Is the global defined in context.
+
+protected:
+ GlobalDesc(unsigned T);
+
+public:
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ const std::string &getName() const { return Name; }
+ const std::string &getFullName() const { return FullName; }
+ const std::string &getLinkageName() const { return LinkageName; }
+ CompileUnitDesc *getFile() const {
+ return static_cast<CompileUnitDesc *>(File);
+ }
+ unsigned getLine() const { return Line; }
+ TypeDesc *getType() const {
+ return static_cast<TypeDesc *>(TyDesc);
+ }
+ bool isStatic() const { return IsStatic; }
+ bool isDefinition() const { return IsDefinition; }
+ void setContext(DebugInfoDesc *C) { Context = C; }
+ void setName(const std::string &N) { Name = N; }
+ void setFullName(const std::string &N) { FullName = N; }
+ void setLinkageName(const std::string &N) { LinkageName = N; }
+ void setFile(CompileUnitDesc *U) {
+ File = static_cast<DebugInfoDesc *>(U);
+ }
+ void setLine(unsigned L) { Line = L; }
+ void setType(TypeDesc *T) {
+ TyDesc = static_cast<DebugInfoDesc *>(T);
+ }
+ void setIsStatic(bool IS) { IsStatic = IS; }
+ void setIsDefinition(bool ID) { IsDefinition = ID; }
+
+ /// ApplyToFields - Target the visitor to the fields of the GlobalDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+};
+
+//===----------------------------------------------------------------------===//
+/// GlobalVariableDesc - This class packages debug information associated with a
+/// GlobalVariable.
+class GlobalVariableDesc : public GlobalDesc {
+private:
+ GlobalVariable *Global; // llvm global.
+
+public:
+ GlobalVariableDesc();
+
+ // Accessors.
+ GlobalVariable *getGlobalVariable() const { return Global; }
+ void setGlobalVariable(GlobalVariable *GV) { Global = GV; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const GlobalVariableDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the
+ /// GlobalVariableDesc.
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+ /// getAnchorString - Return a string used to label this descriptor's anchor.
+ ///
+ static const char *AnchorString;
+ virtual const char *getAnchorString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// SubprogramDesc - This class packages debug information associated with a
+/// subprogram/function.
+class SubprogramDesc : public GlobalDesc {
+private:
+
+public:
+ SubprogramDesc();
+
+ // Accessors
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const SubprogramDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the SubprogramDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+ /// getAnchorString - Return a string used to label this descriptor's anchor.
+ ///
+ static const char *AnchorString;
+ virtual const char *getAnchorString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// BlockDesc - This descriptor groups variables and blocks nested in a block.
+///
+class BlockDesc : public DebugInfoDesc {
+private:
+ DebugInfoDesc *Context; // Context debug descriptor.
+
+public:
+ BlockDesc();
+
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ void setContext(DebugInfoDesc *C) { Context = C; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const BlockDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the BlockDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// DIDeserializer - This class is responsible for casting GlobalVariables
+/// into DebugInfoDesc objects.
+class DIDeserializer {
+private:
+ std::map<GlobalVariable *, DebugInfoDesc *> GlobalDescs;
+ // Previously defined gloabls.
+
+public:
+ DIDeserializer() {}
+ ~DIDeserializer() {}
+
+ /// Deserialize - Reconstitute a GlobalVariable into it's component
+ /// DebugInfoDesc objects.
+ DebugInfoDesc *Deserialize(Value *V);
+ DebugInfoDesc *Deserialize(GlobalVariable *GV);
+};
+
+//===----------------------------------------------------------------------===//
+/// DISerializer - This class is responsible for casting DebugInfoDesc objects
+/// into GlobalVariables.
+class DISerializer {
+private:
+ Module *M; // Definition space module.
+ PointerType *StrPtrTy; // A "sbyte *" type. Created lazily.
+ PointerType *EmptyStructPtrTy; // A "{ }*" type. Created lazily.
+ std::map<unsigned, StructType *> TagTypes;
+ // Types per Tag. Created lazily.
+ std::map<DebugInfoDesc *, GlobalVariable *> DescGlobals;
+ // Previously defined descriptors.
+ std::map<const std::string, Constant *> StringCache;
+ // Previously defined strings.
+
+public:
+ DISerializer()
+ : M(NULL)
+ , StrPtrTy(NULL)
+ , EmptyStructPtrTy(NULL)
+ , TagTypes()
+ , DescGlobals()
+ , StringCache()
+ {}
+ ~DISerializer() {}
+
+ // Accessors
+ Module *getModule() const { return M; };
+ void setModule(Module *module) { M = module; }
+
+ /// getStrPtrType - Return a "sbyte *" type.
+ ///
+ const PointerType *getStrPtrType();
+
+ /// getEmptyStructPtrType - Return a "{ }*" type.
+ ///
+ const PointerType *getEmptyStructPtrType();
+
+ /// getTagType - Return the type describing the specified descriptor (via
+ /// tag.)
+ const StructType *getTagType(DebugInfoDesc *DD);
+
+ /// getString - Construct the string as constant string global.
+ ///
+ Constant *getString(const std::string &String);
+
+ /// Serialize - Recursively cast the specified descriptor into a
+ /// GlobalVariable so that it can be serialized to a .bc or .ll file.
+ GlobalVariable *Serialize(DebugInfoDesc *DD);
+};
+
+//===----------------------------------------------------------------------===//
+/// DIVerifier - This class is responsible for verifying the given network of
+/// GlobalVariables are valid as DebugInfoDesc objects.
+class DIVerifier {
+private:
+ enum {
+ Unknown = 0,
+ Invalid,
+ Valid
+ };
+ std::map<GlobalVariable *, unsigned> Validity;// Tracks prior results.
+ std::map<unsigned, unsigned> Counts; // Count of fields per Tag type.
+
+public:
+ DIVerifier()
+ : Validity()
+ , Counts()
+ {}
+ ~DIVerifier() {}
+
+ /// Verify - Return true if the GlobalVariable appears to be a valid
+ /// serialization of a DebugInfoDesc.
+ bool Verify(Value *V);
+ bool Verify(GlobalVariable *GV);
+};
+
+//===----------------------------------------------------------------------===//
+/// SourceLineInfo - This class is used to record source line correspondence.
+///
+class SourceLineInfo {
+private:
+ unsigned Line; // Source line number.
+ unsigned Column; // Source column.
+ unsigned SourceID; // Source ID number.
+ unsigned LabelID; // Label in code ID number.
+
+public:
+ SourceLineInfo(unsigned L, unsigned C, unsigned S, unsigned I)
+ : Line(L), Column(C), SourceID(S), LabelID(I) {}
+
+ // Accessors
+ unsigned getLine() const { return Line; }
+ unsigned getColumn() const { return Column; }
+ unsigned getSourceID() const { return SourceID; }
+ unsigned getLabelID() const { return LabelID; }
+};
+
+//===----------------------------------------------------------------------===//
+/// SourceFileInfo - This class is used to track source information.
+///
+class SourceFileInfo {
+private:
+ unsigned DirectoryID; // Directory ID number.
+ std::string Name; // File name (not including directory.)
+
+public:
+ SourceFileInfo(unsigned D, const std::string &N) : DirectoryID(D), Name(N) {}
+
+ // Accessors
+ unsigned getDirectoryID() const { return DirectoryID; }
+ const std::string &getName() const { return Name; }
+
+ /// operator== - Used by UniqueVector to locate entry.
+ ///
+ bool operator==(const SourceFileInfo &SI) const {
+ return getDirectoryID() == SI.getDirectoryID() && getName() == SI.getName();
+ }
+
+ /// operator< - Used by UniqueVector to locate entry.
+ ///
+ bool operator<(const SourceFileInfo &SI) const {
+ return getDirectoryID() < SI.getDirectoryID() ||
+ (getDirectoryID() == SI.getDirectoryID() && getName() < SI.getName());
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// DebugVariable - This class is used to track local variable information.
+///
+class DebugVariable {
+private:
+ VariableDesc *Desc; // Variable Descriptor.
+ unsigned FrameIndex; // Variable frame index.
+
+public:
+ DebugVariable(VariableDesc *D, unsigned I)
+ : Desc(D)
+ , FrameIndex(I)
+ {}
+
+ // Accessors.
+ VariableDesc *getDesc() const { return Desc; }
+ unsigned getFrameIndex() const { return FrameIndex; }
+};
+
+//===----------------------------------------------------------------------===//
+/// DebugScope - This class is used to track scope information.
+///
+class DebugScope {
+private:
+ DebugScope *Parent; // Parent to this scope.
+ DebugInfoDesc *Desc; // Debug info descriptor for scope.
+ // Either subprogram or block.
+ unsigned StartLabelID; // Label ID of the beginning of scope.
+ unsigned EndLabelID; // Label ID of the end of scope.
+ std::vector<DebugScope *> Scopes; // Scopes defined in scope.
+ std::vector<DebugVariable *> Variables;// Variables declared in scope.
+
+public:
+ DebugScope(DebugScope *P, DebugInfoDesc *D)
+ : Parent(P)
+ , Desc(D)
+ , StartLabelID(0)
+ , EndLabelID(0)
+ , Scopes()
+ , Variables()
+ {}
+ ~DebugScope();
+
+ // Accessors.
+ DebugScope *getParent() const { return Parent; }
+ DebugInfoDesc *getDesc() const { return Desc; }
+ unsigned getStartLabelID() const { return StartLabelID; }
+ unsigned getEndLabelID() const { return EndLabelID; }
+ std::vector<DebugScope *> &getScopes() { return Scopes; }
+ std::vector<DebugVariable *> &getVariables() { return Variables; }
+ void setStartLabelID(unsigned S) { StartLabelID = S; }
+ void setEndLabelID(unsigned E) { EndLabelID = E; }
+
+ /// AddScope - Add a scope to the scope.
+ ///
+ void AddScope(DebugScope *S) { Scopes.push_back(S); }
+
+ /// AddVariable - Add a variable to the scope.
+ ///
+ void AddVariable(DebugVariable *V) { Variables.push_back(V); }
+};
+
+//===----------------------------------------------------------------------===//
+/// LandingPadInfo - This structure is used to retain landing pad info for
+/// the current function.
+///
+struct LandingPadInfo {
+ MachineBasicBlock *LandingPadBlock; // Landing pad block.
+ SmallVector<unsigned, 1> BeginLabels; // Labels prior to invoke.
+ SmallVector<unsigned, 1> EndLabels; // Labels after invoke.
+ unsigned LandingPadLabel; // Label at beginning of landing pad.
+ Function *Personality; // Personality function.
+ std::vector<int> TypeIds; // List of type ids (filters negative)
+
+ LandingPadInfo(MachineBasicBlock *MBB)
+ : LandingPadBlock(MBB)
+ , LandingPadLabel(0)
+ , Personality(NULL)
+ , TypeIds(1, 0) // Always have cleanups
+ {}
+};
+
+//===----------------------------------------------------------------------===//
+/// MachineModuleInfo - This class contains meta information specific to a
+/// module. Queries can be made by different debugging and exception handling
+/// schemes and reformated for specific use.
+///
+class MachineModuleInfo : public ImmutablePass {
+private:
+ // Use the same deserializer/verifier for the module.
+ DIDeserializer DR;
+ DIVerifier VR;
+
+ // CompileUnits - Uniquing vector for compile units.
+ UniqueVector<CompileUnitDesc *> CompileUnits;
+
+ // Directories - Uniquing vector for directories.
+ UniqueVector<std::string> Directories;
+
+ // SourceFiles - Uniquing vector for source files.
+ UniqueVector<SourceFileInfo> SourceFiles;
+
+ // Lines - List of of source line correspondence.
+ std::vector<SourceLineInfo> Lines;
+
+ // LabelIDList - One entry per assigned label. Normally the entry is equal to
+ // the list index(+1). If the entry is zero then the label has been deleted.
+ // Any other value indicates the label has been deleted by is mapped to
+ // another label.
+ std::vector<unsigned> LabelIDList;
+
+ // ScopeMap - Tracks the scopes in the current function.
+ std::map<DebugInfoDesc *, DebugScope *> ScopeMap;
+
+ // RootScope - Top level scope for the current function.
+ //
+ DebugScope *RootScope;
+
+ // FrameMoves - List of moves done by a function's prolog. Used to construct
+ // frame maps by debug and exception handling consumers.
+ std::vector<MachineMove> FrameMoves;
+
+ // LandingPads - List of LandingPadInfo describing the landing pad information
+ // in the current function.
+ std::vector<LandingPadInfo> LandingPads;
+
+ // TypeInfos - List of C++ TypeInfo used in the current function.
+ //
+ std::vector<GlobalVariable *> TypeInfos;
+
+ // FilterIds - List of typeids encoding filters used in the current function.
+ //
+ std::vector<unsigned> FilterIds;
+
+ // FilterEnds - List of the indices in FilterIds corresponding to filter
+ // terminators.
+ //
+ std::vector<unsigned> FilterEnds;
+
+ // Personalities - Vector of all personality functions ever seen. Used to emit
+ // common EH frames.
+ std::vector<Function *> Personalities;
+
+ bool CallsEHReturn;
+ bool CallsUnwindInit;
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ MachineModuleInfo();
+ ~MachineModuleInfo();
+
+ /// doInitialization - Initialize the state for a new module.
+ ///
+ bool doInitialization();
+
+ /// doFinalization - Tear down the state after completion of a module.
+ ///
+ bool doFinalization();
+
+ /// BeginFunction - Begin gathering function meta information.
+ ///
+ void BeginFunction(MachineFunction *MF);
+
+ /// EndFunction - Discard function meta information.
+ ///
+ void EndFunction();
+
+ /// getDescFor - Convert a Value to a debug information descriptor.
+ ///
+ // FIXME - use new Value type when available.
+ DebugInfoDesc *getDescFor(Value *V);
+
+ /// Verify - Verify that a Value is debug information descriptor.
+ ///
+ bool Verify(Value *V);
+
+ /// AnalyzeModule - Scan the module for global debug information.
+ ///
+ void AnalyzeModule(Module &M);
+
+ /// hasDebugInfo - Returns true if valid debug info is present.
+ ///
+ bool hasDebugInfo() const { return !CompileUnits.empty(); }
+
+ /// needsFrameInfo - Returns true if we need to gather callee-saved register
+ /// move info for the frame.
+ bool needsFrameInfo() const;
+
+ bool callsEHReturn() const { return CallsEHReturn; }
+ void setCallsEHReturn(bool b) { CallsEHReturn = b; }
+
+ bool callsUnwindInit() const { return CallsUnwindInit; }
+ void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
+
+ /// NextLabelID - Return the next unique label id.
+ ///
+ unsigned NextLabelID() {
+ unsigned ID = LabelIDList.size() + 1;
+ LabelIDList.push_back(ID);
+ return ID;
+ }
+
+ /// RecordLabel - Records location information and associates it with a
+ /// label. Returns a unique label ID used to generate a label and
+ /// provide correspondence to the source line list.
+ unsigned RecordLabel(unsigned Line, unsigned Column, unsigned Source);
+
+ /// InvalidateLabel - Inhibit use of the specified label # from
+ /// MachineModuleInfo, for example because the code was deleted.
+ void InvalidateLabel(unsigned LabelID) {
+ // Remap to zero to indicate deletion.
+ RemapLabel(LabelID, 0);
+ }
+
+ /// RemapLabel - Indicate that a label has been merged into another.
+ ///
+ void RemapLabel(unsigned OldLabelID, unsigned NewLabelID) {
+ assert(0 < OldLabelID && OldLabelID <= LabelIDList.size() &&
+ "Old label ID out of range.");
+ assert(NewLabelID <= LabelIDList.size() &&
+ "New label ID out of range.");
+ LabelIDList[OldLabelID - 1] = NewLabelID;
+ }
+
+ /// MappedLabel - Find out the label's final ID. Zero indicates deletion.
+ /// ID != Mapped ID indicates that the label was folded into another label.
+ unsigned MappedLabel(unsigned LabelID) const {
+ assert(LabelID <= LabelIDList.size() && "Debug label ID out of range.");
+ return LabelID ? LabelIDList[LabelID - 1] : 0;
+ }
+
+ /// RecordSource - Register a source file with debug info. Returns an source
+ /// ID.
+ unsigned RecordSource(const std::string &Directory,
+ const std::string &Source);
+ unsigned RecordSource(const CompileUnitDesc *CompileUnit);
+
+ /// getDirectories - Return the UniqueVector of std::string representing
+ /// directories.
+ const UniqueVector<std::string> &getDirectories() const {
+ return Directories;
+ }
+
+ /// getSourceFiles - Return the UniqueVector of source files.
+ ///
+ const UniqueVector<SourceFileInfo> &getSourceFiles() const {
+ return SourceFiles;
+ }
+
+ /// getSourceLines - Return a vector of source lines.
+ ///
+ const std::vector<SourceLineInfo> &getSourceLines() const {
+ return Lines;
+ }
+
+ /// SetupCompileUnits - Set up the unique vector of compile units.
+ ///
+ void SetupCompileUnits(Module &M);
+
+ /// getCompileUnits - Return a vector of debug compile units.
+ ///
+ const UniqueVector<CompileUnitDesc *> getCompileUnits() const;
+
+ /// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
+ /// named GlobalVariable.
+ std::vector<GlobalVariable*>
+ getGlobalVariablesUsing(Module &M, const std::string &RootName);
+
+ /// getAnchoredDescriptors - Return a vector of anchored debug descriptors.
+ ///
+ template <class T>std::vector<T *> getAnchoredDescriptors(Module &M) {
+ T Desc;
+ std::vector<GlobalVariable *> Globals =
+ getGlobalVariablesUsing(M, Desc.getAnchorString());
+ std::vector<T *> AnchoredDescs;
+ for (unsigned i = 0, N = Globals.size(); i < N; ++i) {
+ GlobalVariable *GV = Globals[i];
+
+ // FIXME - In the short term, changes are too drastic to continue.
+ if (DebugInfoDesc::TagFromGlobal(GV) == Desc.getTag() &&
+ DebugInfoDesc::VersionFromGlobal(GV) == LLVMDebugVersion) {
+ AnchoredDescs.push_back(cast<T>(DR.Deserialize(GV)));
+ }
+ }
+
+ return AnchoredDescs;
+ }
+
+ /// RecordRegionStart - Indicate the start of a region.
+ ///
+ unsigned RecordRegionStart(Value *V);
+
+ /// RecordRegionEnd - Indicate the end of a region.
+ ///
+ unsigned RecordRegionEnd(Value *V);
+
+ /// RecordVariable - Indicate the declaration of a local variable.
+ ///
+ void RecordVariable(Value *V, unsigned FrameIndex);
+
+ /// getRootScope - Return current functions root scope.
+ ///
+ DebugScope *getRootScope() { return RootScope; }
+
+ /// getOrCreateScope - Returns the scope associated with the given descriptor.
+ ///
+ DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc);
+
+ /// getFrameMoves - Returns a reference to a list of moves done in the current
+ /// function's prologue. Used to construct frame maps for debug and exception
+ /// handling comsumers.
+ std::vector<MachineMove> &getFrameMoves() { return FrameMoves; }
+
+ //===-EH-----------------------------------------------------------------===//
+
+ /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
+ /// specified MachineBasicBlock.
+ LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
+
+ /// addInvoke - Provide the begin and end labels of an invoke style call and
+ /// associate it with a try landing pad block.
+ void addInvoke(MachineBasicBlock *LandingPad, unsigned BeginLabel,
+ unsigned EndLabel);
+
+ /// addLandingPad - Add a new panding pad. Returns the label ID for the
+ /// landing pad entry.
+ unsigned addLandingPad(MachineBasicBlock *LandingPad);
+
+ /// addPersonality - Provide the personality function for the exception
+ /// information.
+ void addPersonality(MachineBasicBlock *LandingPad, Function *Personality);
+
+ /// getPersonalityIndex - Get index of the current personality function inside
+ /// Personalitites array
+ unsigned getPersonalityIndex() const;
+
+ /// getPersonalities - Return array of personality functions ever seen.
+ const std::vector<Function *>& getPersonalities() const {
+ return Personalities;
+ }
+
+ /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
+ ///
+ void addCatchTypeInfo(MachineBasicBlock *LandingPad,
+ std::vector<GlobalVariable *> &TyInfo);
+
+ /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
+ ///
+ void addFilterTypeInfo(MachineBasicBlock *LandingPad,
+ std::vector<GlobalVariable *> &TyInfo);
+
+ /// getTypeIDFor - Return the type id for the specified typeinfo. This is
+ /// function wide.
+ unsigned getTypeIDFor(GlobalVariable *TI);
+
+ /// getFilterIDFor - Return the id of the filter encoded by TyIds. This is
+ /// function wide.
+ int getFilterIDFor(std::vector<unsigned> &TyIds);
+
+ /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
+ /// pads.
+ void TidyLandingPads();
+
+ /// getLandingPads - Return a reference to the landing pad info for the
+ /// current function.
+ const std::vector<LandingPadInfo> &getLandingPads() const {
+ return LandingPads;
+ }
+
+ /// getTypeInfos - Return a reference to the C++ typeinfo for the current
+ /// function.
+ const std::vector<GlobalVariable *> &getTypeInfos() const {
+ return TypeInfos;
+ }
+
+ /// getFilterIds - Return a reference to the typeids encoding filters used in
+ /// the current function.
+ const std::vector<unsigned> &getFilterIds() const {
+ return FilterIds;
+ }
+
+ /// getPersonality - Return a personality function if available. The presence
+ /// of one is required to emit exception handling info.
+ Function *getPersonality() const;
+
+}; // End class MachineModuleInfo
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h
new file mode 100644
index 0000000..4bb34b0
--- /dev/null
+++ b/include/llvm/CodeGen/MachinePassRegistry.h
@@ -0,0 +1,156 @@
+//===-- llvm/CodeGen/MachinePassRegistry.h ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the mechanics for machine function pass registries. A
+// function pass registry (MachinePassRegistry) is auto filled by the static
+// constructors of MachinePassRegistryNode. Further there is a command line
+// parser (RegisterPassParser) which listens to each registry for additions
+// and deletions, so that the appropriate command option is updated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+#define LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+
+typedef void *(*MachinePassCtor)();
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistryListener - Listener to adds and removals of nodes in
+/// registration list.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistryListener {
+public:
+ MachinePassRegistryListener() {}
+ virtual ~MachinePassRegistryListener() {}
+ virtual void NotifyAdd(const char *N, MachinePassCtor C, const char *D) = 0;
+ virtual void NotifyRemove(const char *N) = 0;
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistryNode - Machine pass node stored in registration list.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistryNode {
+
+private:
+
+ MachinePassRegistryNode *Next; // Next function pass in list.
+ const char *Name; // Name of function pass.
+ const char *Description; // Description string.
+ MachinePassCtor Ctor; // Function pass creator.
+
+public:
+
+ MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C)
+ : Next(NULL)
+ , Name(N)
+ , Description(D)
+ , Ctor(C)
+ {}
+
+ // Accessors
+ MachinePassRegistryNode *getNext() const { return Next; }
+ MachinePassRegistryNode **getNextAddress() { return &Next; }
+ const char *getName() const { return Name; }
+ const char *getDescription() const { return Description; }
+ MachinePassCtor getCtor() const { return Ctor; }
+ void setNext(MachinePassRegistryNode *N) { Next = N; }
+
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistry - Track the registration of machine passes.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistry {
+
+private:
+
+ MachinePassRegistryNode *List; // List of registry nodes.
+ MachinePassCtor Default; // Default function pass creator.
+ MachinePassRegistryListener* Listener;// Listener for list adds are removes.
+
+public:
+
+ // NO CONSTRUCTOR - we don't want static constructor ordering to mess
+ // with the registry.
+
+ // Accessors.
+ //
+ MachinePassRegistryNode *getList() { return List; }
+ MachinePassCtor getDefault() { return Default; }
+ void setDefault(MachinePassCtor C) { Default = C; }
+ void setListener(MachinePassRegistryListener *L) { Listener = L; }
+
+ /// Add - Adds a function pass to the registration list.
+ ///
+ void Add(MachinePassRegistryNode *Node);
+
+ /// Remove - Removes a function pass from the registration list.
+ ///
+ void Remove(MachinePassRegistryNode *Node);
+
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterPassParser class - Handle the addition of new machine passes.
+///
+//===----------------------------------------------------------------------===//
+template<class RegistryClass>
+class RegisterPassParser : public MachinePassRegistryListener,
+ public cl::parser<typename RegistryClass::FunctionPassCtor> {
+public:
+ RegisterPassParser() {}
+ ~RegisterPassParser() { RegistryClass::setListener(NULL); }
+
+ void initialize(cl::Option &O) {
+ cl::parser<typename RegistryClass::FunctionPassCtor>::initialize(O);
+
+ // Add existing passes to option.
+ for (RegistryClass *Node = RegistryClass::getList();
+ Node; Node = Node->getNext()) {
+ addLiteralOption(Node->getName(),
+ (typename RegistryClass::FunctionPassCtor)Node->getCtor(),
+ Node->getDescription());
+ }
+
+ // Make sure we listen for list changes.
+ RegistryClass::setListener(this);
+ }
+
+ // Implement the MachinePassRegistryListener callbacks.
+ //
+ virtual void NotifyAdd(const char *N,
+ MachinePassCtor C,
+ const char *D) {
+ this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D);
+ }
+ virtual void NotifyRemove(const char *N) {
+ this->removeLiteralOption(N);
+ }
+};
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h
new file mode 100644
index 0000000..364b8b1
--- /dev/null
+++ b/include/llvm/CodeGen/MachineRelocation.h
@@ -0,0 +1,298 @@
+//===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MachineRelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
+#define LLVM_CODEGEN_MACHINERELOCATION_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+class GlobalValue;
+class MachineBasicBlock;
+
+/// MachineRelocation - This represents a target-specific relocation value,
+/// produced by the code emitter. This relocation is resolved after the has
+/// been emitted, either to an object file or to memory, when the target of the
+/// relocation can be resolved.
+///
+/// A relocation is made up of the following logical portions:
+/// 1. An offset in the machine code buffer, the location to modify.
+/// 2. A target specific relocation type (a number from 0 to 63).
+/// 3. A symbol being referenced, either as a GlobalValue* or as a string.
+/// 4. An optional constant value to be added to the reference.
+/// 5. A bit, CanRewrite, which indicates to the JIT that a function stub is
+/// not needed for the relocation.
+/// 6. An index into the GOT, if the target uses a GOT
+///
+class MachineRelocation {
+ enum AddressType {
+ isResult, // Relocation has be transformed into its result pointer.
+ isGV, // The Target.GV field is valid.
+ isBB, // Relocation of BB address.
+ isExtSym, // The Target.ExtSym field is valid.
+ isConstPool, // Relocation of constant pool address.
+ isJumpTable, // Relocation of jump table address.
+ isGOTIndex // The Target.GOTIndex field is valid.
+ };
+
+ /// Offset - This is the offset from the start of the code buffer of the
+ /// relocation to perform.
+ intptr_t Offset;
+
+ /// ConstantVal - A field that may be used by the target relocation type.
+ intptr_t ConstantVal;
+
+ union {
+ void *Result; // If this has been resolved to a resolved pointer
+ GlobalValue *GV; // If this is a pointer to an LLVM global
+ MachineBasicBlock *MBB; // If this is a pointer to a LLVM BB
+ const char *ExtSym; // If this is a pointer to a named symbol
+ unsigned Index; // Constant pool / jump table index
+ unsigned GOTIndex; // Index in the GOT of this symbol/global
+ } Target;
+
+ unsigned TargetReloType : 6; // The target relocation ID.
+ AddressType AddrType : 4; // The field of Target to use.
+ bool DoesntNeedFnStub : 1; // True if we don't need a fn stub.
+ bool GOTRelative : 1; // Should this relocation be relative to the GOT?
+
+public:
+ // Relocation types used in a generic implementation. Currently, relocation
+ // entries for all things use the generic VANILLA type until they are refined
+ // into target relocation types.
+ enum RelocationType {
+ VANILLA
+ };
+
+ /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue.
+ ///
+ static MachineRelocation getGV(intptr_t offset, unsigned RelocationType,
+ GlobalValue *GV, intptr_t cst = 0,
+ bool DoesntNeedFunctionStub = 0,
+ bool GOTrelative = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isGV;
+ Result.DoesntNeedFnStub = DoesntNeedFunctionStub;
+ Result.GOTRelative = GOTrelative;
+ Result.Target.GV = GV;
+ return Result;
+ }
+
+ /// MachineRelocation::getBB - Return a relocation entry for a BB.
+ ///
+ static MachineRelocation getBB(intptr_t offset,unsigned RelocationType,
+ MachineBasicBlock *MBB, intptr_t cst = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isBB;
+ Result.DoesntNeedFnStub = false;
+ Result.GOTRelative = false;
+ Result.Target.MBB = MBB;
+ return Result;
+ }
+
+ /// MachineRelocation::getExtSym - Return a relocation entry for an external
+ /// symbol, like "free".
+ ///
+ static MachineRelocation getExtSym(intptr_t offset, unsigned RelocationType,
+ const char *ES, intptr_t cst = 0,
+ bool GOTrelative = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isExtSym;
+ Result.DoesntNeedFnStub = false;
+ Result.GOTRelative = GOTrelative;
+ Result.Target.ExtSym = ES;
+ return Result;
+ }
+
+ /// MachineRelocation::getConstPool - Return a relocation entry for a constant
+ /// pool entry.
+ ///
+ static MachineRelocation getConstPool(intptr_t offset,unsigned RelocationType,
+ unsigned CPI, intptr_t cst = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isConstPool;
+ Result.DoesntNeedFnStub = false;
+ Result.GOTRelative = false;
+ Result.Target.Index = CPI;
+ return Result;
+ }
+
+ /// MachineRelocation::getJumpTable - Return a relocation entry for a jump
+ /// table entry.
+ ///
+ static MachineRelocation getJumpTable(intptr_t offset,unsigned RelocationType,
+ unsigned JTI, intptr_t cst = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isJumpTable;
+ Result.DoesntNeedFnStub = false;
+ Result.GOTRelative = false;
+ Result.Target.Index = JTI;
+ return Result;
+ }
+
+ /// getMachineCodeOffset - Return the offset into the code buffer that the
+ /// relocation should be performed.
+ intptr_t getMachineCodeOffset() const {
+ return Offset;
+ }
+
+ /// getRelocationType - Return the target-specific relocation ID for this
+ /// relocation.
+ unsigned getRelocationType() const {
+ return TargetReloType;
+ }
+
+ /// getConstantVal - Get the constant value associated with this relocation.
+ /// This is often an offset from the symbol.
+ ///
+ intptr_t getConstantVal() const {
+ return ConstantVal;
+ }
+
+ /// setConstantVal - Set the constant value associated with this relocation.
+ /// This is often an offset from the symbol.
+ ///
+ void setConstantVal(intptr_t val) {
+ ConstantVal = val;
+ }
+
+ /// isGlobalValue - Return true if this relocation is a GlobalValue, as
+ /// opposed to a constant string.
+ bool isGlobalValue() const {
+ return AddrType == isGV;
+ }
+
+ /// isBasicBlock - Return true if this relocation is a basic block reference.
+ ///
+ bool isBasicBlock() const {
+ return AddrType == isBB;
+ }
+
+ /// isString - Return true if this is a constant string.
+ ///
+ bool isString() const {
+ return AddrType == isExtSym;
+ }
+
+ /// isConstantPoolIndex - Return true if this is a constant pool reference.
+ ///
+ bool isConstantPoolIndex() const {
+ return AddrType == isConstPool;
+ }
+
+ /// isJumpTableIndex - Return true if this is a jump table reference.
+ ///
+ bool isJumpTableIndex() const {
+ return AddrType == isJumpTable;
+ }
+
+ /// isGOTRelative - Return true the target wants the index into the GOT of
+ /// the symbol rather than the address of the symbol.
+ bool isGOTRelative() const {
+ return GOTRelative;
+ }
+
+ /// doesntNeedFunctionStub - This function returns true if the JIT for this
+ /// target is capable of directly handling the relocated instruction without
+ /// using a stub function. It is always conservatively correct for this flag
+ /// to be false, but targets can improve their compilation callback functions
+ /// to handle more general cases if they want improved performance.
+ bool doesntNeedFunctionStub() const {
+ return DoesntNeedFnStub;
+ }
+
+ /// getGlobalValue - If this is a global value reference, return the
+ /// referenced global.
+ GlobalValue *getGlobalValue() const {
+ assert(isGlobalValue() && "This is not a global value reference!");
+ return Target.GV;
+ }
+
+ MachineBasicBlock *getBasicBlock() const {
+ assert(isBasicBlock() && "This is not a basic block reference!");
+ return Target.MBB;
+ }
+
+ /// getString - If this is a string value, return the string reference.
+ ///
+ const char *getString() const {
+ assert(isString() && "This is not a string reference!");
+ return Target.ExtSym;
+ }
+
+ /// getConstantPoolIndex - If this is a const pool reference, return
+ /// the index into the constant pool.
+ unsigned getConstantPoolIndex() const {
+ assert(isConstantPoolIndex() && "This is not a constant pool reference!");
+ return Target.Index;
+ }
+
+ /// getJumpTableIndex - If this is a jump table reference, return
+ /// the index into the jump table.
+ unsigned getJumpTableIndex() const {
+ assert(isJumpTableIndex() && "This is not a jump table reference!");
+ return Target.Index;
+ }
+
+ /// getResultPointer - Once this has been resolved to point to an actual
+ /// address, this returns the pointer.
+ void *getResultPointer() const {
+ assert(AddrType == isResult && "Result pointer isn't set yet!");
+ return Target.Result;
+ }
+
+ /// setResultPointer - Set the result to the specified pointer value.
+ ///
+ void setResultPointer(void *Ptr) {
+ Target.Result = Ptr;
+ AddrType = isResult;
+ }
+
+ /// setGOTIndex - Set the GOT index to a specific value.
+ void setGOTIndex(unsigned idx) {
+ AddrType = isGOTIndex;
+ Target.GOTIndex = idx;
+ }
+
+ /// getGOTIndex - Once this has been resolved to an entry in the GOT,
+ /// this returns that index. The index is from the lowest address entry
+ /// in the GOT.
+ unsigned getGOTIndex() const {
+ assert(AddrType == isGOTIndex);
+ return Target.GOTIndex;
+ }
+};
+}
+
+#endif
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
new file mode 100644
index 0000000..eda6a5d
--- /dev/null
+++ b/include/llvm/CodeGen/Passes.h
@@ -0,0 +1,120 @@
+//===-- Passes.h - Target independent code generation passes ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces to access the target independent code generation
+// passes provided by the LLVM backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PASSES_H
+#define LLVM_CODEGEN_PASSES_H
+
+#include <iosfwd>
+#include <string>
+
+namespace llvm {
+
+ class FunctionPass;
+ class PassInfo;
+ class TargetMachine;
+
+ /// createUnreachableBlockEliminationPass - The LLVM code generator does not
+ /// work well with unreachable basic blocks (what live ranges make sense for a
+ /// block that cannot be reached?). As such, a code generator should either
+ /// not instruction select unreachable blocks, or it can run this pass as it's
+ /// last LLVM modifying pass to clean up blocks that are not reachable from
+ /// the entry block.
+ FunctionPass *createUnreachableBlockEliminationPass();
+
+ /// MachineFunctionPrinter pass - This pass prints out the machine function to
+ /// standard error, as a debugging tool.
+ FunctionPass *createMachineFunctionPrinterPass(std::ostream *OS,
+ const std::string &Banner ="");
+
+ /// PHIElimination pass - This pass eliminates machine instruction PHI nodes
+ /// by inserting copy instructions. This destroys SSA information, but is the
+ /// desired input for some register allocators. This pass is "required" by
+ /// these register allocator like this: AU.addRequiredID(PHIEliminationID);
+ ///
+ extern const PassInfo *PHIEliminationID;
+
+ /// SimpleRegisterCoalescing pass. Aggressively coalesces every register
+ /// copy it can.
+ ///
+ extern const PassInfo *SimpleRegisterCoalescingID;
+
+ /// TwoAddressInstruction pass - This pass reduces two-address instructions to
+ /// use two operands. This destroys SSA information but it is desired by
+ /// register allocators.
+ extern const PassInfo *TwoAddressInstructionPassID;
+
+ /// Creates a register allocator as the user specified on the command line.
+ ///
+ FunctionPass *createRegisterAllocator();
+
+ /// SimpleRegisterAllocation Pass - This pass converts the input machine code
+ /// from SSA form to use explicit registers by spilling every register. Wow,
+ /// great policy huh?
+ ///
+ FunctionPass *createSimpleRegisterAllocator();
+
+ /// LocalRegisterAllocation Pass - This pass register allocates the input code
+ /// a basic block at a time, yielding code better than the simple register
+ /// allocator, but not as good as a global allocator.
+ ///
+ FunctionPass *createLocalRegisterAllocator();
+
+ /// BigBlockRegisterAllocation Pass - The BigBlock register allocator
+ /// munches single basic blocks at a time, like the local register
+ /// allocator. While the BigBlock allocator is a little slower, and uses
+ /// somewhat more memory than the local register allocator, it tends to
+ /// yield the best allocations (of any of the allocators) for blocks that
+ /// have hundreds or thousands of instructions in sequence.
+ ///
+ FunctionPass *createBigBlockRegisterAllocator();
+
+ /// LinearScanRegisterAllocation Pass - This pass implements the linear scan
+ /// register allocation algorithm, a global register allocator.
+ ///
+ FunctionPass *createLinearScanRegisterAllocator();
+
+ /// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code,
+ /// and eliminates abstract frame references.
+ ///
+ FunctionPass *createPrologEpilogCodeInserter();
+
+ /// createPostRAScheduler - under development.
+ FunctionPass *createPostRAScheduler();
+
+ /// BranchFolding Pass - This pass performs machine code CFG based
+ /// optimizations to delete branches to branches, eliminate branches to
+ /// successor blocks (creating fall throughs), and eliminating branches over
+ /// branches.
+ FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge);
+
+ /// IfConverter Pass - This pass performs machine code if conversion.
+ FunctionPass *createIfConverterPass();
+
+ /// DebugLabelFoldingPass - This pass prunes out redundant debug labels. This
+ /// allows a debug emitter to determine if the range of two labels is empty,
+ /// by seeing if the labels map to the same reduced label.
+ FunctionPass *createDebugLabelFoldingPass();
+
+ /// MachineCodeDeletion Pass - This pass deletes all of the machine code for
+ /// the current function, which should happen after the function has been
+ /// emitted to a .s file or to memory.
+ FunctionPass *createMachineCodeDeleter();
+
+ /// getRegisterAllocator - This creates an instance of the register allocator
+ /// for the Sparc.
+ FunctionPass *getRegisterAllocator(TargetMachine &T);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/RegAllocRegistry.h b/include/llvm/CodeGen/RegAllocRegistry.h
new file mode 100644
index 0000000..ba6a879
--- /dev/null
+++ b/include/llvm/CodeGen/RegAllocRegistry.h
@@ -0,0 +1,64 @@
+//===-- llvm/CodeGen/RegAllocRegistry.h -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation for register allocator function
+// pass registry (RegisterRegAlloc).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGENREGALLOCREGISTRY_H
+#define LLVM_CODEGENREGALLOCREGISTRY_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterRegAlloc class - Track the registration of register allocators.
+///
+//===----------------------------------------------------------------------===//
+class RegisterRegAlloc : public MachinePassRegistryNode {
+
+public:
+
+ typedef FunctionPass *(*FunctionPassCtor)();
+
+ static MachinePassRegistry Registry;
+
+ RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
+ : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
+ { Registry.Add(this); }
+ ~RegisterRegAlloc() { Registry.Remove(this); }
+
+
+ // Accessors.
+ //
+ RegisterRegAlloc *getNext() const {
+ return (RegisterRegAlloc *)MachinePassRegistryNode::getNext();
+ }
+ static RegisterRegAlloc *getList() {
+ return (RegisterRegAlloc *)Registry.getList();
+ }
+ static FunctionPassCtor getDefault() {
+ return (FunctionPassCtor)Registry.getDefault();
+ }
+ static void setDefault(FunctionPassCtor C) {
+ Registry.setDefault((MachinePassCtor)C);
+ }
+ static void setListener(MachinePassRegistryListener *L) {
+ Registry.setListener(L);
+ }
+
+};
+
+} // end namespace llvm
+
+
+#endif
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
new file mode 100644
index 0000000..ec23e76
--- /dev/null
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -0,0 +1,148 @@
+//===-- RegisterScavenging.h - Machine register scavenging ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the Evan Cheng and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the machine register scavenger class. It can provide
+// information such as unused register at any point in a machine basic block.
+// It also provides a mechanism to make registers availbale by evicting them
+// to spill slots.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H
+#define LLVM_CODEGEN_REGISTER_SCAVENGING_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/ADT/BitVector.h"
+
+namespace llvm {
+
+class MRegisterInfo;
+class TargetInstrInfo;
+class TargetRegisterClass;
+
+class RegScavenger {
+ MachineBasicBlock *MBB;
+ MachineBasicBlock::iterator MBBI;
+ unsigned NumPhysRegs;
+
+ /// Tracking - True if RegScavenger is currently tracking the liveness of
+ /// registers.
+ bool Tracking;
+
+ /// ScavengingFrameIndex - Special spill slot used for scavenging a register
+ /// post register allocation.
+ int ScavengingFrameIndex;
+
+ /// ScavengedReg - If none zero, the specific register is currently being
+ /// scavenged. That is, it is spilled to the special scavenging stack slot.
+ unsigned ScavengedReg;
+
+ /// ScavengedRC - Register class of the scavenged register.
+ ///
+ const TargetRegisterClass *ScavengedRC;
+
+ /// RegsAvailable - The current state of all the physical registers immediately
+ /// before MBBI. One bit per physical register. If bit is set that means it's
+ /// available, unset means the register is currently being used.
+ BitVector RegsAvailable;
+
+public:
+ RegScavenger()
+ : MBB(NULL), NumPhysRegs(0), Tracking(false),
+ ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {};
+
+ explicit RegScavenger(MachineBasicBlock *mbb)
+ : MBB(mbb), NumPhysRegs(0), Tracking(false),
+ ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {};
+
+ /// enterBasicBlock - Start tracking liveness from the begin of the specific
+ /// basic block.
+ void enterBasicBlock(MachineBasicBlock *mbb);
+
+ /// forward / backward - Move the internal MBB iterator and update register
+ /// states.
+ void forward();
+ void backward();
+
+ /// forward / backward - Move the internal MBB iterator and update register
+ /// states until it has processed the specific iterator.
+ void forward(MachineBasicBlock::iterator I) {
+ while (MBBI != I) forward();
+ }
+ void backward(MachineBasicBlock::iterator I) {
+ while (MBBI != I) backward();
+ }
+
+ /// skipTo - Move the internal MBB iterator but do not update register states.
+ ///
+ void skipTo(MachineBasicBlock::iterator I) { MBBI = I; }
+
+ /// isReserved - Returns true if a register is reserved. It is never "unused".
+ bool isReserved(unsigned Reg) const { return ReservedRegs[Reg]; }
+
+ /// isUsed / isUsed - Test if a register is currently being used.
+ ///
+ bool isUsed(unsigned Reg) const { return !RegsAvailable[Reg]; }
+ bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
+
+ /// getRegsUsed - return all registers currently in use in used.
+ void getRegsUsed(BitVector &used, bool includeReserved);
+
+ /// setUsed / setUnused - Mark the state of one or a number of registers.
+ ///
+ void setUsed(unsigned Reg) { RegsAvailable.reset(Reg); }
+ void setUsed(BitVector Regs) { RegsAvailable &= ~Regs; }
+ void setUnused(unsigned Reg) { RegsAvailable.set(Reg); }
+ void setUnused(BitVector Regs) { RegsAvailable |= Regs; }
+
+ /// FindUnusedReg - Find a unused register of the specified register class
+ /// from the specified set of registers. It return 0 is none is found.
+ unsigned FindUnusedReg(const TargetRegisterClass *RegClass,
+ const BitVector &Candidates) const;
+
+ /// FindUnusedReg - Find a unused register of the specified register class.
+ /// Exclude callee saved registers if directed. It return 0 is none is found.
+ unsigned FindUnusedReg(const TargetRegisterClass *RegClass,
+ bool ExCalleeSaved = false) const;
+
+ /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of
+ /// ScavengingFrameIndex.
+ void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; }
+ int getScavengingFrameIndex() const { return ScavengingFrameIndex; }
+
+ /// scavengeRegister - Make a register of the specific register class
+ /// available and do the appropriate bookkeeping. SPAdj is the stack
+ /// adjustment due to call frame, it's passed along to eliminateFrameIndex().
+ /// Returns the scavenged register.
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass,
+ MachineBasicBlock::iterator I, int SPAdj);
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
+ return scavengeRegister(RegClass, MBBI, SPAdj);
+ }
+
+private:
+ const MRegisterInfo *RegInfo;
+ const TargetInstrInfo *TII;
+
+ /// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
+ ///
+ BitVector CalleeSavedRegs;
+
+ /// ReservedRegs - A bitvector of reserved registers.
+ ///
+ BitVector ReservedRegs;
+
+ /// restoreScavengedReg - Restore scavenged by loading it back from the
+ /// emergency spill slot. Mark it used.
+ void restoreScavengedReg();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
new file mode 100644
index 0000000..2609c55
--- /dev/null
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -0,0 +1,109 @@
+//===-- CodeGen/RuntimeLibcall.h - Runtime Library Calls --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the enum representing the list of runtime library calls
+// the backend may emit during code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_RUNTIMELIBCALLS_H
+#define LLVM_CODEGEN_RUNTIMELIBCALLS_H
+
+namespace llvm {
+namespace RTLIB {
+ /// RTLIB::Libcall enum - This enum defines all of the runtime library calls
+ /// the backend can emit.
+ ///
+ enum Libcall {
+ // Integer
+ SHL_I32,
+ SHL_I64,
+ SRL_I32,
+ SRL_I64,
+ SRA_I32,
+ SRA_I64,
+ MUL_I32,
+ MUL_I64,
+ SDIV_I32,
+ SDIV_I64,
+ UDIV_I32,
+ UDIV_I64,
+ SREM_I32,
+ SREM_I64,
+ UREM_I32,
+ UREM_I64,
+ NEG_I32,
+ NEG_I64,
+
+ // FLOATING POINT
+ ADD_F32,
+ ADD_F64,
+ SUB_F32,
+ SUB_F64,
+ MUL_F32,
+ MUL_F64,
+ DIV_F32,
+ DIV_F64,
+ REM_F32,
+ REM_F64,
+ NEG_F32,
+ NEG_F64,
+ POWI_F32,
+ POWI_F64,
+ SQRT_F32,
+ SQRT_F64,
+ SIN_F32,
+ SIN_F64,
+ COS_F32,
+ COS_F64,
+
+ // CONVERSION
+ FPEXT_F32_F64,
+ FPROUND_F64_F32,
+ FPTOSINT_F32_I32,
+ FPTOSINT_F32_I64,
+ FPTOSINT_F64_I32,
+ FPTOSINT_F64_I64,
+ FPTOUINT_F32_I32,
+ FPTOUINT_F32_I64,
+ FPTOUINT_F64_I32,
+ FPTOUINT_F64_I64,
+ SINTTOFP_I32_F32,
+ SINTTOFP_I32_F64,
+ SINTTOFP_I64_F32,
+ SINTTOFP_I64_F64,
+ UINTTOFP_I32_F32,
+ UINTTOFP_I32_F64,
+ UINTTOFP_I64_F32,
+ UINTTOFP_I64_F64,
+
+ // COMPARISON
+ OEQ_F32,
+ OEQ_F64,
+ UNE_F32,
+ UNE_F64,
+ OGE_F32,
+ OGE_F64,
+ OLT_F32,
+ OLT_F64,
+ OLE_F32,
+ OLE_F64,
+ OGT_F32,
+ OGT_F64,
+ UO_F32,
+ UO_F64,
+ O_F32,
+ O_F64,
+
+ UNKNOWN_LIBCALL
+ };
+}
+}
+
+#endif
diff --git a/include/llvm/CodeGen/SSARegMap.h b/include/llvm/CodeGen/SSARegMap.h
new file mode 100644
index 0000000..97d8d69
--- /dev/null
+++ b/include/llvm/CodeGen/SSARegMap.h
@@ -0,0 +1,55 @@
+//===-- llvm/CodeGen/SSARegMap.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Map register numbers to register classes that are correctly sized (typed) to
+// hold the information. Assists register allocation. Contained by
+// MachineFunction, should be deleted by register allocator when it is no
+// longer needed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SSAREGMAP_H
+#define LLVM_CODEGEN_SSAREGMAP_H
+
+#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/ADT/IndexedMap.h"
+
+namespace llvm {
+
+class TargetRegisterClass;
+
+class SSARegMap {
+ IndexedMap<const TargetRegisterClass*, VirtReg2IndexFunctor> RegClassMap;
+ unsigned NextRegNum;
+
+ public:
+ SSARegMap() : NextRegNum(MRegisterInfo::FirstVirtualRegister) { }
+
+ const TargetRegisterClass* getRegClass(unsigned Reg) {
+ return RegClassMap[Reg];
+ }
+
+ /// createVirtualRegister - Create and return a new virtual register in the
+ /// function with the specified register class.
+ ///
+ unsigned createVirtualRegister(const TargetRegisterClass *RegClass) {
+ assert(RegClass && "Cannot create register without RegClass!");
+ RegClassMap.grow(NextRegNum);
+ RegClassMap[NextRegNum] = RegClass;
+ return NextRegNum++;
+ }
+
+ unsigned getLastVirtReg() const {
+ return NextRegNum - 1;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/SchedGraphCommon.h b/include/llvm/CodeGen/SchedGraphCommon.h
new file mode 100644
index 0000000..4fcd9ac
--- /dev/null
+++ b/include/llvm/CodeGen/SchedGraphCommon.h
@@ -0,0 +1,289 @@
+//===-- SchedGraphCommon.h - Scheduling Base Graph --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A common graph class that is based on the SSA graph. It includes
+// extra dependencies that are caused by machine resources.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDGRAPHCOMMON_H
+#define LLVM_CODEGEN_SCHEDGRAPHCOMMON_H
+
+#include "llvm/Value.h"
+#include "llvm/ADT/iterator"
+#include "llvm/Support/Streams.h"
+#include <vector>
+
+namespace llvm {
+
+class SchedGraphEdge;
+class SchedGraphNode;
+
+/******************** Exported Data Types and Constants ********************/
+
+typedef int ResourceId;
+const ResourceId InvalidRID = -1;
+const ResourceId MachineCCRegsRID = -2; // use +ve numbers for actual regs
+const ResourceId MachineIntRegsRID = -3; // use +ve numbers for actual regs
+const ResourceId MachineFPRegsRID = -4; // use +ve numbers for actual regs
+
+
+//*********************** Public Class Declarations ************************/
+class SchedGraphNodeCommon {
+protected:
+ unsigned ID;
+ std::vector<SchedGraphEdge*> inEdges;
+ std::vector<SchedGraphEdge*> outEdges;
+ int latency;
+ int origIndexInBB; // original position of instr in BB
+
+public:
+ typedef std::vector<SchedGraphEdge*>::iterator iterator;
+ typedef std::vector<SchedGraphEdge*>::const_iterator const_iterator;
+ typedef std::vector<SchedGraphEdge*>::reverse_iterator reverse_iterator;
+ typedef std::vector<SchedGraphEdge*>::const_reverse_iterator const_reverse_iterator;
+
+ // Accessor methods
+ unsigned getNodeId() const { return ID; }
+ int getLatency() const { return latency; }
+ unsigned getNumInEdges() const { return inEdges.size(); }
+ unsigned getNumOutEdges() const { return outEdges.size(); }
+ int getOrigIndexInBB() const { return origIndexInBB; }
+
+ // Iterators
+ iterator beginInEdges() { return inEdges.begin(); }
+ iterator endInEdges() { return inEdges.end(); }
+ iterator beginOutEdges() { return outEdges.begin(); }
+ iterator endOutEdges() { return outEdges.end(); }
+
+ const_iterator beginInEdges() const { return inEdges.begin(); }
+ const_iterator endInEdges() const { return inEdges.end(); }
+ const_iterator beginOutEdges() const { return outEdges.begin(); }
+ const_iterator endOutEdges() const { return outEdges.end(); }
+
+ void dump(int indent=0) const;
+
+ // Debugging support
+ virtual void print(std::ostream &os) const = 0;
+ void print(std::ostream *os) const { if (os) print(*os); }
+
+protected:
+ friend class SchedGraphCommon;
+ friend class SchedGraphEdge; // give access for adding edges
+
+
+ // disable default constructor and provide a ctor for single-block graphs
+ SchedGraphNodeCommon(); // DO NOT IMPLEMENT
+
+ inline SchedGraphNodeCommon(unsigned Id, int index, int late=0) : ID(Id), latency(late), origIndexInBB(index) {}
+
+ virtual ~SchedGraphNodeCommon();
+
+ //Functions to add and remove edges
+ inline void addInEdge(SchedGraphEdge* edge) { inEdges.push_back(edge); }
+ inline void addOutEdge(SchedGraphEdge* edge) { outEdges.push_back(edge); }
+ void removeInEdge(const SchedGraphEdge* edge);
+ void removeOutEdge(const SchedGraphEdge* edge);
+
+};
+
+// ostream << operator for SchedGraphNode class
+inline std::ostream &operator<<(std::ostream &os,
+ const SchedGraphNodeCommon &node) {
+ node.print(os);
+ return os;
+}
+
+//
+// SchedGraphEdge - Edge class to represent dependencies
+//
+class SchedGraphEdge {
+public:
+ enum SchedGraphEdgeDepType {
+ CtrlDep, MemoryDep, ValueDep, MachineRegister, MachineResource
+ };
+ enum DataDepOrderType {
+ TrueDep = 0x1, AntiDep=0x2, OutputDep=0x4, NonDataDep=0x8
+ };
+
+protected:
+ SchedGraphNodeCommon* src;
+ SchedGraphNodeCommon* sink;
+ SchedGraphEdgeDepType depType;
+ unsigned int depOrderType;
+ int minDelay; // cached latency (assumes fixed target arch)
+ int iteDiff;
+
+ union {
+ const Value* val;
+ int machineRegNum;
+ ResourceId resourceId;
+ };
+
+public:
+ // For all constructors, if minDelay is unspecified, minDelay is
+ // set to _src->getLatency().
+
+ // constructor for CtrlDep or MemoryDep edges, selected by 3rd argument
+ SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink,
+ SchedGraphEdgeDepType _depType, unsigned int _depOrderType,
+ int _minDelay = -1);
+
+ // constructor for explicit value dependence (may be true/anti/output)
+ SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink,
+ const Value* _val, unsigned int _depOrderType,
+ int _minDelay = -1);
+
+ // constructor for machine register dependence
+ SchedGraphEdge(SchedGraphNodeCommon* _src,SchedGraphNodeCommon* _sink,
+ unsigned int _regNum, unsigned int _depOrderType,
+ int _minDelay = -1);
+
+ // constructor for any other machine resource dependences.
+ // DataDepOrderType is always NonDataDep. It it not an argument to
+ // avoid overloading ambiguity with previous constructor.
+ SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink,
+ ResourceId _resourceId, int _minDelay = -1);
+
+ ~SchedGraphEdge() {}
+
+ SchedGraphNodeCommon* getSrc() const { return src; }
+ SchedGraphNodeCommon* getSink() const { return sink; }
+ int getMinDelay() const { return minDelay; }
+ SchedGraphEdgeDepType getDepType() const { return depType; }
+ unsigned int getDepOrderType() const { return depOrderType; }
+
+ const Value* getValue() const {
+ assert(depType == ValueDep); return val;
+ }
+
+ int getMachineReg() const {
+ assert(depType == MachineRegister); return machineRegNum;
+ }
+
+ int getResourceId() const {
+ assert(depType == MachineResource); return resourceId;
+ }
+
+ void setIteDiff(int _iteDiff) {
+ iteDiff = _iteDiff;
+ }
+
+ int getIteDiff() {
+ return iteDiff;
+ }
+
+public:
+ // Debugging support
+ void print(std::ostream &os) const;
+ void print(std::ostream *os) const { if (os) print(*os); }
+ void dump(int indent=0) const;
+
+private:
+ // disable default ctor
+ SchedGraphEdge(); // DO NOT IMPLEMENT
+};
+
+// ostream << operator for SchedGraphNode class
+inline std::ostream &operator<<(std::ostream &os, const SchedGraphEdge &edge) {
+ edge.print(os);
+ return os;
+}
+
+class SchedGraphCommon {
+
+protected:
+ SchedGraphNodeCommon* graphRoot; // the root and leaf are not inserted
+ SchedGraphNodeCommon* graphLeaf; // in the hash_map (see getNumNodes())
+
+public:
+ //
+ // Accessor methods
+ //
+ SchedGraphNodeCommon* getRoot() const { return graphRoot; }
+ SchedGraphNodeCommon* getLeaf() const { return graphLeaf; }
+
+ //
+ // Delete nodes or edges from the graph.
+ //
+ void eraseNode(SchedGraphNodeCommon* node);
+ void eraseIncomingEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true);
+ void eraseOutgoingEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true);
+ void eraseIncidentEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true);
+
+ SchedGraphCommon() {}
+ ~SchedGraphCommon();
+};
+
+
+//********************** Sched Graph Iterators *****************************/
+
+// Ok to make it a template because it shd get instantiated at most twice:
+// for <SchedGraphNode, SchedGraphNode::iterator> and
+// for <const SchedGraphNode, SchedGraphNode::const_iterator>.
+//
+template <class _NodeType, class _EdgeType, class _EdgeIter>
+class SGPredIterator: public bidirectional_iterator<_NodeType, ptrdiff_t> {
+protected:
+ _EdgeIter oi;
+public:
+ typedef SGPredIterator<_NodeType, _EdgeType, _EdgeIter> _Self;
+
+ inline SGPredIterator(_EdgeIter startEdge) : oi(startEdge) {}
+
+ inline bool operator==(const _Self& x) const { return oi == x.oi; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ // operator*() differs for pred or succ iterator
+ inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSrc(); }
+ inline _NodeType* operator->() const { return operator*(); }
+
+ inline _EdgeType* getEdge() const { return *(oi); }
+
+ inline _Self &operator++() { ++oi; return *this; } // Preincrement
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp(*this); ++*this; return tmp;
+ }
+
+ inline _Self &operator--() { --oi; return *this; } // Predecrement
+ inline _Self operator--(int) { // Postdecrement
+ _Self tmp = *this; --*this; return tmp;
+ }
+};
+
+template <class _NodeType, class _EdgeType, class _EdgeIter>
+class SGSuccIterator : public bidirectional_iterator<_NodeType, ptrdiff_t> {
+protected:
+ _EdgeIter oi;
+public:
+ typedef SGSuccIterator<_NodeType, _EdgeType, _EdgeIter> _Self;
+
+ inline SGSuccIterator(_EdgeIter startEdge) : oi(startEdge) {}
+
+ inline bool operator==(const _Self& x) const { return oi == x.oi; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSink(); }
+ inline _NodeType* operator->() const { return operator*(); }
+
+ inline _EdgeType* getEdge() const { return *(oi); }
+
+ inline _Self &operator++() { ++oi; return *this; } // Preincrement
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp(*this); ++*this; return tmp;
+ }
+
+ inline _Self &operator--() { --oi; return *this; } // Predecrement
+ inline _Self operator--(int) { // Postdecrement
+ _Self tmp = *this; --*this; return tmp;
+ }
+};
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
new file mode 100644
index 0000000..06d2f2e
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -0,0 +1,306 @@
+//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ScheduleDAG class, which is used as the common
+// base class for SelectionDAG-based instruction scheduler.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
+#define LLVM_CODEGEN_SCHEDULEDAG_H
+
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
+
+namespace llvm {
+ struct InstrStage;
+ class MachineConstantPool;
+ class MachineModuleInfo;
+ class MachineInstr;
+ class MRegisterInfo;
+ class SelectionDAG;
+ class SelectionDAGISel;
+ class SSARegMap;
+ class TargetInstrInfo;
+ class TargetInstrDescriptor;
+ class TargetMachine;
+
+ /// HazardRecognizer - This determines whether or not an instruction can be
+ /// issued this cycle, and whether or not a noop needs to be inserted to handle
+ /// the hazard.
+ class HazardRecognizer {
+ public:
+ virtual ~HazardRecognizer();
+
+ enum HazardType {
+ NoHazard, // This instruction can be emitted at this cycle.
+ Hazard, // This instruction can't be emitted at this cycle.
+ NoopHazard // This instruction can't be emitted, and needs noops.
+ };
+
+ /// getHazardType - Return the hazard type of emitting this node. There are
+ /// three possible results. Either:
+ /// * NoHazard: it is legal to issue this instruction on this cycle.
+ /// * Hazard: issuing this instruction would stall the machine. If some
+ /// other instruction is available, issue it first.
+ /// * NoopHazard: issuing this instruction would break the program. If
+ /// some other instruction can be issued, do so, otherwise issue a noop.
+ virtual HazardType getHazardType(SDNode *Node) {
+ return NoHazard;
+ }
+
+ /// EmitInstruction - This callback is invoked when an instruction is
+ /// emitted, to advance the hazard state.
+ virtual void EmitInstruction(SDNode *Node) {
+ }
+
+ /// AdvanceCycle - This callback is invoked when no instructions can be
+ /// issued on this cycle without a hazard. This should increment the
+ /// internal state of the hazard recognizer so that previously "Hazard"
+ /// instructions will now not be hazards.
+ virtual void AdvanceCycle() {
+ }
+
+ /// EmitNoop - This callback is invoked when a noop was added to the
+ /// instruction stream.
+ virtual void EmitNoop() {
+ }
+ };
+
+ /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
+ /// a group of nodes flagged together.
+ struct SUnit {
+ SDNode *Node; // Representative node.
+ SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
+
+ // Preds/Succs - The SUnits before/after us in the graph. The boolean value
+ // is true if the edge is a token chain edge, false if it is a value edge.
+ SmallVector<std::pair<SUnit*,bool>, 4> Preds; // All sunit predecessors.
+ SmallVector<std::pair<SUnit*,bool>, 4> Succs; // All sunit successors.
+
+ typedef SmallVector<std::pair<SUnit*,bool>, 4>::iterator pred_iterator;
+ typedef SmallVector<std::pair<SUnit*,bool>, 4>::iterator succ_iterator;
+ typedef SmallVector<std::pair<SUnit*,bool>, 4>::const_iterator
+ const_pred_iterator;
+ typedef SmallVector<std::pair<SUnit*,bool>, 4>::const_iterator
+ const_succ_iterator;
+
+ short NumPreds; // # of preds.
+ short NumSuccs; // # of sucss.
+ short NumPredsLeft; // # of preds not scheduled.
+ short NumSuccsLeft; // # of succs not scheduled.
+ short NumChainPredsLeft; // # of chain preds not scheduled.
+ short NumChainSuccsLeft; // # of chain succs not scheduled.
+ bool isTwoAddress : 1; // Is a two-address instruction.
+ bool isCommutable : 1; // Is a commutable instruction.
+ bool isPending : 1; // True once pending.
+ bool isAvailable : 1; // True once available.
+ bool isScheduled : 1; // True once scheduled.
+ unsigned short Latency; // Node latency.
+ unsigned CycleBound; // Upper/lower cycle to be scheduled at.
+ unsigned Cycle; // Once scheduled, the cycle of the op.
+ unsigned Depth; // Node depth;
+ unsigned Height; // Node height;
+ unsigned NodeNum; // Entry # of node in the node vector.
+
+ SUnit(SDNode *node, unsigned nodenum)
+ : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
+ NumChainPredsLeft(0), NumChainSuccsLeft(0),
+ isTwoAddress(false), isCommutable(false),
+ isPending(false), isAvailable(false), isScheduled(false),
+ Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0),
+ NodeNum(nodenum) {}
+
+ /// addPred - This adds the specified node as a pred of the current node if
+ /// not already. This returns true if this is a new pred.
+ bool addPred(SUnit *N, bool isChain) {
+ for (unsigned i = 0, e = Preds.size(); i != e; ++i)
+ if (Preds[i].first == N && Preds[i].second == isChain)
+ return false;
+ Preds.push_back(std::make_pair(N, isChain));
+ return true;
+ }
+
+ /// addSucc - This adds the specified node as a succ of the current node if
+ /// not already. This returns true if this is a new succ.
+ bool addSucc(SUnit *N, bool isChain) {
+ for (unsigned i = 0, e = Succs.size(); i != e; ++i)
+ if (Succs[i].first == N && Succs[i].second == isChain)
+ return false;
+ Succs.push_back(std::make_pair(N, isChain));
+ return true;
+ }
+
+ void dump(const SelectionDAG *G) const;
+ void dumpAll(const SelectionDAG *G) const;
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SchedulingPriorityQueue - This interface is used to plug different
+ /// priorities computation algorithms into the list scheduler. It implements
+ /// the interface of a standard priority queue, where nodes are inserted in
+ /// arbitrary order and returned in priority order. The computation of the
+ /// priority and the representation of the queue are totally up to the
+ /// implementation to decide.
+ ///
+ class SchedulingPriorityQueue {
+ public:
+ virtual ~SchedulingPriorityQueue() {}
+
+ virtual void initNodes(DenseMap<SDNode*, SUnit*> &SUMap,
+ std::vector<SUnit> &SUnits) = 0;
+ virtual void releaseState() = 0;
+
+ virtual bool empty() const = 0;
+ virtual void push(SUnit *U) = 0;
+
+ virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
+ virtual SUnit *pop() = 0;
+
+ /// ScheduledNode - As each node is scheduled, this method is invoked. This
+ /// allows the priority function to adjust the priority of node that have
+ /// already been emitted.
+ virtual void ScheduledNode(SUnit *Node) {}
+ };
+
+ class ScheduleDAG {
+ public:
+ SelectionDAG &DAG; // DAG of the current basic block
+ MachineBasicBlock *BB; // Current basic block
+ const TargetMachine &TM; // Target processor
+ const TargetInstrInfo *TII; // Target instruction information
+ const MRegisterInfo *MRI; // Target processor register info
+ SSARegMap *RegMap; // Virtual/real register map
+ MachineConstantPool *ConstPool; // Target constant pool
+ std::vector<SUnit*> Sequence; // The schedule. Null SUnit*'s
+ // represent noop instructions.
+ DenseMap<SDNode*, SUnit*> SUnitMap; // SDNode to SUnit mapping (n -> 1).
+ std::vector<SUnit> SUnits; // The scheduling units.
+ SmallSet<SDNode*, 16> CommuteSet; // Nodes the should be commuted.
+
+ ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
+ const TargetMachine &tm)
+ : DAG(dag), BB(bb), TM(tm) {}
+
+ virtual ~ScheduleDAG() {}
+
+ /// Run - perform scheduling.
+ ///
+ MachineBasicBlock *Run();
+
+ /// isPassiveNode - Return true if the node is a non-scheduled leaf.
+ ///
+ static bool isPassiveNode(SDNode *Node) {
+ if (isa<ConstantSDNode>(Node)) return true;
+ if (isa<RegisterSDNode>(Node)) return true;
+ if (isa<GlobalAddressSDNode>(Node)) return true;
+ if (isa<BasicBlockSDNode>(Node)) return true;
+ if (isa<FrameIndexSDNode>(Node)) return true;
+ if (isa<ConstantPoolSDNode>(Node)) return true;
+ if (isa<JumpTableSDNode>(Node)) return true;
+ if (isa<ExternalSymbolSDNode>(Node)) return true;
+ return false;
+ }
+
+ /// NewSUnit - Creates a new SUnit and return a ptr to it.
+ ///
+ SUnit *NewSUnit(SDNode *N) {
+ SUnits.push_back(SUnit(N, SUnits.size()));
+ return &SUnits.back();
+ }
+
+ /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
+ /// This SUnit graph is similar to the SelectionDAG, but represents flagged
+ /// together nodes with a single SUnit.
+ void BuildSchedUnits();
+
+ /// CalculateDepths, CalculateHeights - Calculate node depth / height.
+ ///
+ void CalculateDepths();
+ void CalculateHeights();
+
+ /// CountResults - The results of target nodes have register or immediate
+ /// operands first, then an optional chain, and optional flag operands
+ /// (which do not go into the machine instrs.)
+ static unsigned CountResults(SDNode *Node);
+
+ /// CountOperands The inputs to target nodes have any actual inputs first,
+ /// followed by an optional chain operand, then flag operands. Compute the
+ /// number of actual operands that will go into the machine instr.
+ static unsigned CountOperands(SDNode *Node);
+
+ /// EmitNode - Generate machine code for an node and needed dependencies.
+ /// VRBaseMap contains, for each already emitted node, the first virtual
+ /// register number for the results of the node.
+ ///
+ void EmitNode(SDNode *Node, DenseMap<SDOperand, unsigned> &VRBaseMap);
+
+ /// EmitNoop - Emit a noop instruction.
+ ///
+ void EmitNoop();
+
+ void EmitSchedule();
+
+ void dumpSchedule() const;
+
+ /// Schedule - Order nodes according to selected style.
+ ///
+ virtual void Schedule() {}
+
+ private:
+ void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
+ const TargetInstrDescriptor *II,
+ DenseMap<SDOperand, unsigned> &VRBaseMap);
+ };
+
+ /// createBFS_DAGScheduler - This creates a simple breadth first instruction
+ /// scheduler.
+ ScheduleDAG *createBFS_DAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createSimpleDAGScheduler - This creates a simple two pass instruction
+ /// scheduler using instruction itinerary.
+ ScheduleDAG* createSimpleDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createNoItinsDAGScheduler - This creates a simple two pass instruction
+ /// scheduler without using instruction itinerary.
+ ScheduleDAG* createNoItinsDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createBURRListDAGScheduler - This creates a bottom up register usage
+ /// reduction list scheduler.
+ ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createTDRRListDAGScheduler - This creates a top down register usage
+ /// reduction list scheduler.
+ ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createTDListDAGScheduler - This creates a top-down list scheduler with
+ /// a hazard recognizer.
+ ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createDefaultScheduler - This creates an instruction scheduler appropriate
+ /// for the target.
+ ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+}
+
+#endif
diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h
new file mode 100644
index 0000000..ed5e0ba
--- /dev/null
+++ b/include/llvm/CodeGen/SchedulerRegistry.h
@@ -0,0 +1,71 @@
+//===-- llvm/CodeGen/SchedulerRegistry.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation for instruction scheduler function
+// pass registry (RegisterScheduler).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGENSCHEDULERREGISTRY_H
+#define LLVM_CODEGENSCHEDULERREGISTRY_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterScheduler class - Track the registration of instruction schedulers.
+///
+//===----------------------------------------------------------------------===//
+
+class SelectionDAGISel;
+class ScheduleDAG;
+class SelectionDAG;
+class MachineBasicBlock;
+
+class RegisterScheduler : public MachinePassRegistryNode {
+
+public:
+
+ typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, SelectionDAG*,
+ MachineBasicBlock*);
+
+ static MachinePassRegistry Registry;
+
+ RegisterScheduler(const char *N, const char *D, FunctionPassCtor C)
+ : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
+ { Registry.Add(this); }
+ ~RegisterScheduler() { Registry.Remove(this); }
+
+
+ // Accessors.
+ //
+ RegisterScheduler *getNext() const {
+ return (RegisterScheduler *)MachinePassRegistryNode::getNext();
+ }
+ static RegisterScheduler *getList() {
+ return (RegisterScheduler *)Registry.getList();
+ }
+ static FunctionPassCtor getDefault() {
+ return (FunctionPassCtor)Registry.getDefault();
+ }
+ static void setDefault(FunctionPassCtor C) {
+ Registry.setDefault((MachinePassCtor)C);
+ }
+ static void setListener(MachinePassRegistryListener *L) {
+ Registry.setListener(L);
+ }
+
+};
+
+} // end namespace llvm
+
+
+#endif
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
new file mode 100644
index 0000000..9388df1
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -0,0 +1,524 @@
+//===-- llvm/CodeGen/SelectionDAG.h - InstSelection DAG ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SelectionDAG class, and transitively defines the
+// SDNode class and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAG_H
+#define LLVM_CODEGEN_SELECTIONDAG_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ilist"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+#include <list>
+#include <vector>
+#include <map>
+#include <set>
+#include <string>
+
+namespace llvm {
+ class AliasAnalysis;
+ class TargetLowering;
+ class TargetMachine;
+ class MachineModuleInfo;
+ class MachineFunction;
+ class MachineConstantPoolValue;
+
+/// SelectionDAG class - This is used to represent a portion of an LLVM function
+/// in a low-level Data Dependence DAG representation suitable for instruction
+/// selection. This DAG is constructed as the first step of instruction
+/// selection in order to allow implementation of machine specific optimizations
+/// and code simplifications.
+///
+/// The representation used by the SelectionDAG is a target-independent
+/// representation, which has some similarities to the GCC RTL representation,
+/// but is significantly more simple, powerful, and is a graph form instead of a
+/// linear form.
+///
+class SelectionDAG {
+ TargetLowering &TLI;
+ MachineFunction &MF;
+ MachineModuleInfo *MMI;
+
+ /// Root - The root of the entire DAG. EntryNode - The starting token.
+ SDOperand Root, EntryNode;
+
+ /// AllNodes - A linked list of nodes in the current DAG.
+ ilist<SDNode> AllNodes;
+
+ /// CSEMap - This structure is used to memoize nodes, automatically performing
+ /// CSE with existing nodes with a duplicate is requested.
+ FoldingSet<SDNode> CSEMap;
+
+public:
+ SelectionDAG(TargetLowering &tli, MachineFunction &mf, MachineModuleInfo *mmi)
+ : TLI(tli), MF(mf), MMI(mmi) {
+ EntryNode = Root = getNode(ISD::EntryToken, MVT::Other);
+ }
+ ~SelectionDAG();
+
+ MachineFunction &getMachineFunction() const { return MF; }
+ const TargetMachine &getTarget() const;
+ TargetLowering &getTargetLoweringInfo() const { return TLI; }
+ MachineModuleInfo *getMachineModuleInfo() const { return MMI; }
+
+ /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
+ ///
+ void viewGraph();
+
+#ifndef NDEBUG
+ std::map<const SDNode *, std::string> NodeGraphAttrs;
+#endif
+
+ /// clearGraphAttrs - Clear all previously defined node graph attributes.
+ /// Intended to be used from a debugging tool (eg. gdb).
+ void clearGraphAttrs();
+
+ /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
+ ///
+ void setGraphAttrs(const SDNode *N, const char *Attrs);
+
+ /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
+ /// Used from getNodeAttributes.
+ const std::string getGraphAttrs(const SDNode *N) const;
+
+ /// setGraphColor - Convenience for setting node color attribute.
+ ///
+ void setGraphColor(const SDNode *N, const char *Color);
+
+ typedef ilist<SDNode>::const_iterator allnodes_const_iterator;
+ allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); }
+ allnodes_const_iterator allnodes_end() const { return AllNodes.end(); }
+ typedef ilist<SDNode>::iterator allnodes_iterator;
+ allnodes_iterator allnodes_begin() { return AllNodes.begin(); }
+ allnodes_iterator allnodes_end() { return AllNodes.end(); }
+
+ /// getRoot - Return the root tag of the SelectionDAG.
+ ///
+ const SDOperand &getRoot() const { return Root; }
+
+ /// getEntryNode - Return the token chain corresponding to the entry of the
+ /// function.
+ const SDOperand &getEntryNode() const { return EntryNode; }
+
+ /// setRoot - Set the current root tag of the SelectionDAG.
+ ///
+ const SDOperand &setRoot(SDOperand N) { return Root = N; }
+
+ /// Combine - This iterates over the nodes in the SelectionDAG, folding
+ /// certain types of nodes together, or eliminating superfluous nodes. When
+ /// the AfterLegalize argument is set to 'true', Combine takes care not to
+ /// generate any nodes that will be illegal on the target.
+ void Combine(bool AfterLegalize, AliasAnalysis &AA);
+
+ /// Legalize - This transforms the SelectionDAG into a SelectionDAG that is
+ /// compatible with the target instruction selector, as indicated by the
+ /// TargetLowering object.
+ ///
+ /// Note that this is an involved process that may invalidate pointers into
+ /// the graph.
+ void Legalize();
+
+ /// RemoveDeadNodes - This method deletes all unreachable nodes in the
+ /// SelectionDAG.
+ void RemoveDeadNodes();
+
+ /// RemoveDeadNode - Remove the specified node from the system. If any of its
+ /// operands then becomes dead, remove them as well. The vector Deleted is
+ /// populated with nodes that are deleted.
+ void RemoveDeadNode(SDNode *N, std::vector<SDNode*> &Deleted);
+
+ /// DeleteNode - Remove the specified node from the system. This node must
+ /// have no referrers.
+ void DeleteNode(SDNode *N);
+
+ /// getVTList - Return an SDVTList that represents the list of values
+ /// specified.
+ SDVTList getVTList(MVT::ValueType VT);
+ SDVTList getVTList(MVT::ValueType VT1, MVT::ValueType VT2);
+ SDVTList getVTList(MVT::ValueType VT1, MVT::ValueType VT2,MVT::ValueType VT3);
+ SDVTList getVTList(const MVT::ValueType *VTs, unsigned NumVTs);
+
+ /// getNodeValueTypes - These are obsolete, use getVTList instead.
+ const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT) {
+ return getVTList(VT).VTs;
+ }
+ const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT1,
+ MVT::ValueType VT2) {
+ return getVTList(VT1, VT2).VTs;
+ }
+ const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT1,MVT::ValueType VT2,
+ MVT::ValueType VT3) {
+ return getVTList(VT1, VT2, VT3).VTs;
+ }
+ const MVT::ValueType *getNodeValueTypes(std::vector<MVT::ValueType> &VTList) {
+ return getVTList(&VTList[0], VTList.size()).VTs;
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Node creation methods.
+ //
+ SDOperand getString(const std::string &Val);
+ SDOperand getConstant(uint64_t Val, MVT::ValueType VT, bool isTarget = false);
+ SDOperand getTargetConstant(uint64_t Val, MVT::ValueType VT) {
+ return getConstant(Val, VT, true);
+ }
+ SDOperand getConstantFP(double Val, MVT::ValueType VT, bool isTarget = false);
+ SDOperand getTargetConstantFP(double Val, MVT::ValueType VT) {
+ return getConstantFP(Val, VT, true);
+ }
+ SDOperand getGlobalAddress(const GlobalValue *GV, MVT::ValueType VT,
+ int offset = 0, bool isTargetGA = false);
+ SDOperand getTargetGlobalAddress(const GlobalValue *GV, MVT::ValueType VT,
+ int offset = 0) {
+ return getGlobalAddress(GV, VT, offset, true);
+ }
+ SDOperand getFrameIndex(int FI, MVT::ValueType VT, bool isTarget = false);
+ SDOperand getTargetFrameIndex(int FI, MVT::ValueType VT) {
+ return getFrameIndex(FI, VT, true);
+ }
+ SDOperand getJumpTable(int JTI, MVT::ValueType VT, bool isTarget = false);
+ SDOperand getTargetJumpTable(int JTI, MVT::ValueType VT) {
+ return getJumpTable(JTI, VT, true);
+ }
+ SDOperand getConstantPool(Constant *C, MVT::ValueType VT,
+ unsigned Align = 0, int Offs = 0, bool isT=false);
+ SDOperand getTargetConstantPool(Constant *C, MVT::ValueType VT,
+ unsigned Align = 0, int Offset = 0) {
+ return getConstantPool(C, VT, Align, Offset, true);
+ }
+ SDOperand getConstantPool(MachineConstantPoolValue *C, MVT::ValueType VT,
+ unsigned Align = 0, int Offs = 0, bool isT=false);
+ SDOperand getTargetConstantPool(MachineConstantPoolValue *C,
+ MVT::ValueType VT, unsigned Align = 0,
+ int Offset = 0) {
+ return getConstantPool(C, VT, Align, Offset, true);
+ }
+ SDOperand getBasicBlock(MachineBasicBlock *MBB);
+ SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT);
+ SDOperand getTargetExternalSymbol(const char *Sym, MVT::ValueType VT);
+ SDOperand getValueType(MVT::ValueType);
+ SDOperand getRegister(unsigned Reg, MVT::ValueType VT);
+
+ SDOperand getCopyToReg(SDOperand Chain, unsigned Reg, SDOperand N) {
+ return getNode(ISD::CopyToReg, MVT::Other, Chain,
+ getRegister(Reg, N.getValueType()), N);
+ }
+
+ // This version of the getCopyToReg method takes an extra operand, which
+ // indicates that there is potentially an incoming flag value (if Flag is not
+ // null) and that there should be a flag result.
+ SDOperand getCopyToReg(SDOperand Chain, unsigned Reg, SDOperand N,
+ SDOperand Flag) {
+ const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDOperand Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Flag };
+ return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.Val ? 4 : 3);
+ }
+
+ // Similar to last getCopyToReg() except parameter Reg is a SDOperand
+ SDOperand getCopyToReg(SDOperand Chain, SDOperand Reg, SDOperand N,
+ SDOperand Flag) {
+ const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDOperand Ops[] = { Chain, Reg, N, Flag };
+ return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.Val ? 4 : 3);
+ }
+
+ SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT) {
+ const MVT::ValueType *VTs = getNodeValueTypes(VT, MVT::Other);
+ SDOperand Ops[] = { Chain, getRegister(Reg, VT) };
+ return getNode(ISD::CopyFromReg, VTs, 2, Ops, 2);
+ }
+
+ // This version of the getCopyFromReg method takes an extra operand, which
+ // indicates that there is potentially an incoming flag value (if Flag is not
+ // null) and that there should be a flag result.
+ SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT,
+ SDOperand Flag) {
+ const MVT::ValueType *VTs = getNodeValueTypes(VT, MVT::Other, MVT::Flag);
+ SDOperand Ops[] = { Chain, getRegister(Reg, VT), Flag };
+ return getNode(ISD::CopyFromReg, VTs, 3, Ops, Flag.Val ? 3 : 2);
+ }
+
+ SDOperand getCondCode(ISD::CondCode Cond);
+
+ /// getZeroExtendInReg - Return the expression required to zero extend the Op
+ /// value assuming it was the smaller SrcTy value.
+ SDOperand getZeroExtendInReg(SDOperand Op, MVT::ValueType SrcTy);
+
+ /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have
+ /// a flag result (to ensure it's not CSE'd).
+ SDOperand getCALLSEQ_START(SDOperand Chain, SDOperand Op) {
+ const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDOperand Ops[] = { Chain, Op };
+ return getNode(ISD::CALLSEQ_START, VTs, 2, Ops, 2);
+ }
+
+ /// getNode - Gets or creates the specified node.
+ ///
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand N1, SDOperand N2);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand N1, SDOperand N2, SDOperand N3);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4,
+ SDOperand N5);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ const SDOperand *Ops, unsigned NumOps);
+ SDOperand getNode(unsigned Opcode, std::vector<MVT::ValueType> &ResultTys,
+ const SDOperand *Ops, unsigned NumOps);
+ SDOperand getNode(unsigned Opcode, const MVT::ValueType *VTs, unsigned NumVTs,
+ const SDOperand *Ops, unsigned NumOps);
+ SDOperand getNode(unsigned Opcode, SDVTList VTs,
+ const SDOperand *Ops, unsigned NumOps);
+
+ /// getSetCC - Helper function to make it easier to build SetCC's if you just
+ /// have an ISD::CondCode instead of an SDOperand.
+ ///
+ SDOperand getSetCC(MVT::ValueType VT, SDOperand LHS, SDOperand RHS,
+ ISD::CondCode Cond) {
+ return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond));
+ }
+
+ /// getSelectCC - Helper function to make it easier to build SelectCC's if you
+ /// just have an ISD::CondCode instead of an SDOperand.
+ ///
+ SDOperand getSelectCC(SDOperand LHS, SDOperand RHS,
+ SDOperand True, SDOperand False, ISD::CondCode Cond) {
+ return getNode(ISD::SELECT_CC, True.getValueType(), LHS, RHS, True, False,
+ getCondCode(Cond));
+ }
+
+ /// getVAArg - VAArg produces a result and token chain, and takes a pointer
+ /// and a source value as input.
+ SDOperand getVAArg(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr,
+ SDOperand SV);
+
+ /// getLoad - Loads are not normal binary operators: their result type is not
+ /// determined by their operands, and they produce a value AND a token chain.
+ ///
+ SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr,
+ const Value *SV, int SVOffset, bool isVolatile=false,
+ unsigned Alignment=0);
+ SDOperand getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
+ SDOperand Chain, SDOperand Ptr, const Value *SV,
+ int SVOffset, MVT::ValueType EVT, bool isVolatile=false,
+ unsigned Alignment=0);
+ SDOperand getIndexedLoad(SDOperand OrigLoad, SDOperand Base,
+ SDOperand Offset, ISD::MemIndexedMode AM);
+
+ /// getStore - Helper function to build ISD::STORE nodes.
+ ///
+ SDOperand getStore(SDOperand Chain, SDOperand Val, SDOperand Ptr,
+ const Value *SV, int SVOffset, bool isVolatile=false,
+ unsigned Alignment=0);
+ SDOperand getTruncStore(SDOperand Chain, SDOperand Val, SDOperand Ptr,
+ const Value *SV, int SVOffset, MVT::ValueType TVT,
+ bool isVolatile=false, unsigned Alignment=0);
+ SDOperand getIndexedStore(SDOperand OrigStoe, SDOperand Base,
+ SDOperand Offset, ISD::MemIndexedMode AM);
+
+ // getSrcValue - construct a node to track a Value* through the backend
+ SDOperand getSrcValue(const Value* I, int offset = 0);
+
+ /// UpdateNodeOperands - *Mutate* the specified node in-place to have the
+ /// specified operands. If the resultant node already exists in the DAG,
+ /// this does not modify the specified node, instead it returns the node that
+ /// already exists. If the resultant node does not exist in the DAG, the
+ /// input node is returned. As a degenerate case, if you specify the same
+ /// input operands as the node already has, the input node is returned.
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3, SDOperand Op4);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3, SDOperand Op4, SDOperand Op5);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand *Ops, unsigned NumOps);
+
+ /// SelectNodeTo - These are used for target selectors to *mutate* the
+ /// specified node to have the specified return type, Target opcode, and
+ /// operands. Note that target opcodes are stored as
+ /// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field. The 0th value
+ /// of the resultant node is returned.
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT,
+ SDOperand Op1);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT,
+ SDOperand Op1, SDOperand Op2);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT,
+ SDOperand Op1, SDOperand Op2, SDOperand Op3);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT,
+ const SDOperand *Ops, unsigned NumOps);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1, SDOperand Op2);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3);
+
+
+ /// getTargetNode - These are used for target selectors to create a new node
+ /// with specified return type(s), target opcode, and operands.
+ ///
+ /// Note that getTargetNode returns the resultant node. If there is already a
+ /// node of the specified opcode and operands, it returns that node instead of
+ /// the current one.
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand Op1);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand Op1, SDOperand Op2);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand Op1, SDOperand Op2, SDOperand Op3);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT,
+ const SDOperand *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1, SDOperand Op2);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2,
+ const SDOperand *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, MVT::ValueType VT3,
+ SDOperand Op1, SDOperand Op2);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, MVT::ValueType VT3,
+ SDOperand Op1, SDOperand Op2, SDOperand Op3);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, MVT::ValueType VT3,
+ const SDOperand *Ops, unsigned NumOps);
+
+ /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
+ /// This can cause recursive merging of nodes in the DAG. Use the first
+ /// version if 'From' is known to have a single result, use the second
+ /// if you have two nodes with identical results, use the third otherwise.
+ ///
+ /// These methods all take an optional vector, which (if not null) is
+ /// populated with any nodes that are deleted from the SelectionDAG, due to
+ /// new equivalences that are discovered.
+ ///
+ void ReplaceAllUsesWith(SDOperand From, SDOperand Op,
+ std::vector<SDNode*> *Deleted = 0);
+ void ReplaceAllUsesWith(SDNode *From, SDNode *To,
+ std::vector<SDNode*> *Deleted = 0);
+ void ReplaceAllUsesWith(SDNode *From, const SDOperand *To,
+ std::vector<SDNode*> *Deleted = 0);
+
+ /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
+ /// uses of other values produced by From.Val alone. The Deleted vector is
+ /// handled the same was as for ReplaceAllUsesWith, but it is required for
+ /// this method.
+ void ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To,
+ std::vector<SDNode*> &Deleted);
+
+ /// AssignNodeIds - Assign a unique node id for each node in the DAG based on
+ /// their allnodes order. It returns the maximum id.
+ unsigned AssignNodeIds();
+
+ /// AssignTopologicalOrder - Assign a unique node id for each node in the DAG
+ /// based on their topological order. It returns the maximum id and a vector
+ /// of the SDNodes* in assigned order by reference.
+ unsigned AssignTopologicalOrder(std::vector<SDNode*> &TopOrder);
+
+ /// isCommutativeBinOp - Returns true if the opcode is a commutative binary
+ /// operation.
+ static bool isCommutativeBinOp(unsigned Opcode) {
+ switch (Opcode) {
+ case ISD::ADD:
+ case ISD::MUL:
+ case ISD::MULHU:
+ case ISD::MULHS:
+ case ISD::FADD:
+ case ISD::FMUL:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::ADDC:
+ case ISD::ADDE: return true;
+ default: return false;
+ }
+ }
+
+ void dump() const;
+
+ /// FoldSetCC - Constant fold a setcc to true or false.
+ SDOperand FoldSetCC(MVT::ValueType VT, SDOperand N1,
+ SDOperand N2, ISD::CondCode Cond);
+
+ /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We
+ /// use this predicate to simplify operations downstream. Op and Mask are
+ /// known to be the same type.
+ bool MaskedValueIsZero(SDOperand Op, uint64_t Mask, unsigned Depth = 0)
+ const;
+
+ /// ComputeMaskedBits - Determine which of the bits specified in Mask are
+ /// known to be either zero or one and return them in the KnownZero/KnownOne
+ /// bitsets. This code only analyzes bits in Mask, in order to short-circuit
+ /// processing. Targets can implement the computeMaskedBitsForTargetNode
+ /// method in the TargetLowering class to allow target nodes to be understood.
+ void ComputeMaskedBits(SDOperand Op, uint64_t Mask, uint64_t &KnownZero,
+ uint64_t &KnownOne, unsigned Depth = 0) const;
+
+ /// ComputeNumSignBits - Return the number of times the sign bit of the
+ /// register is replicated into the other bits. We know that at least 1 bit
+ /// is always equal to the sign bit (itself), but other cases can give us
+ /// information. For example, immediately after an "SRA X, 2", we know that
+ /// the top 3 bits are all equal to each other, so we return 3. Targets can
+ /// implement the ComputeNumSignBitsForTarget method in the TargetLowering
+ /// class to allow target nodes to be understood.
+ unsigned ComputeNumSignBits(SDOperand Op, unsigned Depth = 0) const;
+
+private:
+ void RemoveNodeFromCSEMaps(SDNode *N);
+ SDNode *AddNonLeafNodeToCSEMaps(SDNode *N);
+ SDNode *FindModifiedNodeSlot(SDNode *N, SDOperand Op, void *&InsertPos);
+ SDNode *FindModifiedNodeSlot(SDNode *N, SDOperand Op1, SDOperand Op2,
+ void *&InsertPos);
+ SDNode *FindModifiedNodeSlot(SDNode *N, const SDOperand *Ops, unsigned NumOps,
+ void *&InsertPos);
+
+ void DeleteNodeNotInCSEMaps(SDNode *N);
+
+ // List of non-single value types.
+ std::list<std::vector<MVT::ValueType> > VTList;
+
+ // Maps to auto-CSE operations.
+ std::vector<CondCodeSDNode*> CondCodeNodes;
+
+ std::vector<SDNode*> ValueTypeNodes;
+ std::map<std::string, SDNode*> ExternalSymbols;
+ std::map<std::string, SDNode*> TargetExternalSymbols;
+ std::map<std::string, StringSDNode*> StringNodes;
+};
+
+template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
+ typedef SelectionDAG::allnodes_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(SelectionDAG *G) {
+ return G->allnodes_begin();
+ }
+ static nodes_iterator nodes_end(SelectionDAG *G) {
+ return G->allnodes_end();
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
new file mode 100644
index 0000000..497040d
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -0,0 +1,194 @@
+//===-- llvm/CodeGen/SelectionDAGISel.h - Common Base Class------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SelectionDAGISel class, which is used as the common
+// base class for SelectionDAG-based instruction selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAG_ISEL_H
+#define LLVM_CODEGEN_SELECTIONDAG_ISEL_H
+
+#include "llvm/Pass.h"
+#include "llvm/Constant.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+namespace llvm {
+ class SelectionDAGLowering;
+ class SDOperand;
+ class SSARegMap;
+ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineInstr;
+ class TargetLowering;
+ class FunctionLoweringInfo;
+ class HazardRecognizer;
+
+/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
+/// pattern-matching instruction selectors.
+class SelectionDAGISel : public FunctionPass {
+public:
+ TargetLowering &TLI;
+ SSARegMap *RegMap;
+ SelectionDAG *CurDAG;
+ MachineBasicBlock *BB;
+ std::vector<SDNode*> TopOrder;
+ unsigned DAGSize;
+ static char ID;
+
+ explicit SelectionDAGISel(TargetLowering &tli) :
+ FunctionPass((intptr_t)&ID), TLI(tli), DAGSize(0) {}
+
+ TargetLowering &getTargetLowering() { return TLI; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ virtual bool runOnFunction(Function &Fn);
+
+ unsigned MakeReg(MVT::ValueType VT);
+
+ virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {}
+ virtual void InstructionSelectBasicBlock(SelectionDAG &SD) = 0;
+ virtual void SelectRootInit() {
+ DAGSize = CurDAG->AssignTopologicalOrder(TopOrder);
+ }
+
+ /// SelectInlineAsmMemoryOperand - Select the specified address as a target
+ /// addressing mode, according to the specified constraint code. If this does
+ /// not match or is not implemented, return true. The resultant operands
+ /// (which will appear in the machine instruction) should be added to the
+ /// OutOps vector.
+ virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
+ char ConstraintCode,
+ std::vector<SDOperand> &OutOps,
+ SelectionDAG &DAG) {
+ return true;
+ }
+
+ /// CanBeFoldedBy - Returns true if the specific operand node N of U can be
+ /// folded during instruction selection that starts at Root?
+ virtual bool CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) { return true;}
+
+ /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
+ /// to use for this target when scheduling the DAG.
+ virtual HazardRecognizer *CreateTargetHazardRecognizer();
+
+ /// CaseBlock - This structure is used to communicate between SDLowering and
+ /// SDISel for the code generation of additional basic blocks needed by multi-
+ /// case switch statements.
+ struct CaseBlock {
+ CaseBlock(ISD::CondCode cc, Value *cmplhs, Value *cmprhs, Value *cmpmiddle,
+ MachineBasicBlock *truebb, MachineBasicBlock *falsebb,
+ MachineBasicBlock *me)
+ : CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs),
+ TrueBB(truebb), FalseBB(falsebb), ThisBB(me) {}
+ // CC - the condition code to use for the case block's setcc node
+ ISD::CondCode CC;
+ // CmpLHS/CmpRHS/CmpMHS - The LHS/MHS/RHS of the comparison to emit.
+ // Emit by default LHS op RHS. MHS is used for range comparisons:
+ // If MHS is not null: (LHS <= MHS) and (MHS <= RHS).
+ Value *CmpLHS, *CmpMHS, *CmpRHS;
+ // TrueBB/FalseBB - the block to branch to if the setcc is true/false.
+ MachineBasicBlock *TrueBB, *FalseBB;
+ // ThisBB - the block into which to emit the code for the setcc and branches
+ MachineBasicBlock *ThisBB;
+ };
+ struct JumpTable {
+ JumpTable(unsigned R, unsigned J, MachineBasicBlock *M,
+ MachineBasicBlock *D): Reg(R), JTI(J), MBB(M), Default(D) {};
+
+ /// Reg - the virtual register containing the index of the jump table entry
+ //. to jump to.
+ unsigned Reg;
+ /// JTI - the JumpTableIndex for this jump table in the function.
+ unsigned JTI;
+ /// MBB - the MBB into which to emit the code for the indirect jump.
+ MachineBasicBlock *MBB;
+ /// Default - the MBB of the default bb, which is a successor of the range
+ /// check MBB. This is when updating PHI nodes in successors.
+ MachineBasicBlock *Default;
+ };
+ struct JumpTableHeader {
+ JumpTableHeader(uint64_t F, uint64_t L, Value* SV, MachineBasicBlock* H,
+ bool E = false):
+ First(F), Last(L), SValue(SV), HeaderBB(H), Emitted(E) {};
+ uint64_t First;
+ uint64_t Last;
+ Value *SValue;
+ MachineBasicBlock *HeaderBB;
+ bool Emitted;
+ };
+ typedef std::pair<JumpTableHeader, JumpTable> JumpTableBlock;
+
+ struct BitTestCase {
+ BitTestCase(uint64_t M, MachineBasicBlock* T, MachineBasicBlock* Tr):
+ Mask(M), ThisBB(T), TargetBB(Tr) { };
+ uint64_t Mask;
+ MachineBasicBlock* ThisBB;
+ MachineBasicBlock* TargetBB;
+ };
+
+ typedef SmallVector<BitTestCase, 3> BitTestInfo;
+
+ struct BitTestBlock {
+ BitTestBlock(uint64_t F, uint64_t R, Value* SV,
+ unsigned Rg, bool E,
+ MachineBasicBlock* P, MachineBasicBlock* D,
+ const BitTestInfo& C):
+ First(F), Range(R), SValue(SV), Reg(Rg), Emitted(E),
+ Parent(P), Default(D), Cases(C) { };
+ uint64_t First;
+ uint64_t Range;
+ Value *SValue;
+ unsigned Reg;
+ bool Emitted;
+ MachineBasicBlock *Parent;
+ MachineBasicBlock *Default;
+ BitTestInfo Cases;
+ };
+protected:
+ /// Pick a safe ordering and emit instructions for each target node in the
+ /// graph.
+ void ScheduleAndEmitDAG(SelectionDAG &DAG);
+
+ /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
+ /// by tblgen. Others should not call it.
+ void SelectInlineAsmMemoryOperands(std::vector<SDOperand> &Ops,
+ SelectionDAG &DAG);
+
+ // Calls to these predicates are generated by tblgen.
+ bool CheckAndMask(SDOperand LHS, ConstantSDNode *RHS, int64_t DesiredMaskS);
+ bool CheckOrMask(SDOperand LHS, ConstantSDNode *RHS, int64_t DesiredMaskS);
+
+private:
+ void SelectBasicBlock(BasicBlock *BB, MachineFunction &MF,
+ FunctionLoweringInfo &FuncInfo);
+
+ void BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
+ std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
+ FunctionLoweringInfo &FuncInfo);
+ void CodeGenAndEmitDAG(SelectionDAG &DAG);
+ void LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL,
+ std::vector<SDOperand> &UnorderedChains);
+
+ /// SwitchCases - Vector of CaseBlock structures used to communicate
+ /// SwitchInst code generation information.
+ std::vector<CaseBlock> SwitchCases;
+
+ /// JTCases - Vector of JumpTable structures which holds necessary information
+ /// for emitting a jump tables during SwitchInst code generation.
+ std::vector<JumpTableBlock> JTCases;
+
+ std::vector<BitTestBlock> BitTestCases;
+};
+
+}
+
+#endif /* LLVM_CODEGEN_SELECTIONDAG_ISEL_H */
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
new file mode 100644
index 0000000..c96d516
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -0,0 +1,1641 @@
+//===-- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SDNode class and derived classes, which are used to
+// represent the nodes and operations present in a SelectionDAG. These nodes
+// and operations are machine code level operations, with some similarities to
+// the GCC RTL representation.
+//
+// Clients should include the SelectionDAG.h file instead of this file directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
+#define LLVM_CODEGEN_SELECTIONDAGNODES_H
+
+#include "llvm/Value.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+class SelectionDAG;
+class GlobalValue;
+class MachineBasicBlock;
+class MachineConstantPoolValue;
+class SDNode;
+template <typename T> struct DenseMapKeyInfo;
+template <typename T> struct simplify_type;
+template <typename T> struct ilist_traits;
+template<typename NodeTy, typename Traits> class iplist;
+template<typename NodeTy> class ilist_iterator;
+
+/// SDVTList - This represents a list of ValueType's that has been intern'd by
+/// a SelectionDAG. Instances of this simple value class are returned by
+/// SelectionDAG::getVTList(...).
+///
+struct SDVTList {
+ const MVT::ValueType *VTs;
+ unsigned short NumVTs;
+};
+
+/// ISD namespace - This namespace contains an enum which represents all of the
+/// SelectionDAG node types and value types.
+///
+namespace ISD {
+ namespace ParamFlags {
+ enum Flags {
+ NoFlagSet = 0,
+ ZExt = 1<<0, ///< Parameter should be zero extended
+ ZExtOffs = 0,
+ SExt = 1<<1, ///< Parameter should be sign extended
+ SExtOffs = 1,
+ InReg = 1<<2, ///< Parameter should be passed in register
+ InRegOffs = 2,
+ StructReturn = 1<<3, ///< Hidden struct-return pointer
+ StructReturnOffs = 3,
+ ByVal = 1<<4, ///< Struct passed by value
+ ByValOffs = 4,
+ OrigAlignment = 0x1F<<27,
+ OrigAlignmentOffs = 27
+ };
+ }
+
+ //===--------------------------------------------------------------------===//
+ /// ISD::NodeType enum - This enum defines all of the operators valid in a
+ /// SelectionDAG.
+ ///
+ enum NodeType {
+ // DELETED_NODE - This is an illegal flag value that is used to catch
+ // errors. This opcode is not a legal opcode for any node.
+ DELETED_NODE,
+
+ // EntryToken - This is the marker used to indicate the start of the region.
+ EntryToken,
+
+ // Token factor - This node takes multiple tokens as input and produces a
+ // single token result. This is used to represent the fact that the operand
+ // operators are independent of each other.
+ TokenFactor,
+
+ // AssertSext, AssertZext - These nodes record if a register contains a
+ // value that has already been zero or sign extended from a narrower type.
+ // These nodes take two operands. The first is the node that has already
+ // been extended, and the second is a value type node indicating the width
+ // of the extension
+ AssertSext, AssertZext,
+
+ // Various leaf nodes.
+ STRING, BasicBlock, VALUETYPE, CONDCODE, Register,
+ Constant, ConstantFP,
+ GlobalAddress, GlobalTLSAddress, FrameIndex,
+ JumpTable, ConstantPool, ExternalSymbol,
+
+ // The address of the GOT
+ GLOBAL_OFFSET_TABLE,
+
+ // FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
+ // llvm.returnaddress on the DAG. These nodes take one operand, the index
+ // of the frame or return address to return. An index of zero corresponds
+ // to the current function's frame or return address, an index of one to the
+ // parent's frame or return address, and so on.
+ FRAMEADDR, RETURNADDR,
+
+ // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
+ // first (possible) on-stack argument. This is needed for correct stack
+ // adjustment during unwind.
+ FRAME_TO_ARGS_OFFSET,
+
+ // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
+ // address of the exception block on entry to an landing pad block.
+ EXCEPTIONADDR,
+
+ // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents
+ // the selection index of the exception thrown.
+ EHSELECTION,
+
+ // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
+ // 'eh_return' gcc dwarf builtin, which is used to return from
+ // exception. The general meaning is: adjust stack by OFFSET and pass
+ // execution to HANDLER. Many platform-related details also :)
+ EH_RETURN,
+
+ // TargetConstant* - Like Constant*, but the DAG does not do any folding or
+ // simplification of the constant.
+ TargetConstant,
+ TargetConstantFP,
+
+ // TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
+ // anything else with this node, and this is valid in the target-specific
+ // dag, turning into a GlobalAddress operand.
+ TargetGlobalAddress,
+ TargetGlobalTLSAddress,
+ TargetFrameIndex,
+ TargetJumpTable,
+ TargetConstantPool,
+ TargetExternalSymbol,
+
+ /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with no side effects.
+ /// The first operand is the ID number of the intrinsic from the
+ /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The
+ /// node has returns the result of the intrinsic.
+ INTRINSIC_WO_CHAIN,
+
+ /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// returns a result. The first operand is a chain pointer. The second is
+ /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The
+ /// operands to the intrinsic follow. The node has two results, the result
+ /// of the intrinsic and an output chain.
+ INTRINSIC_W_CHAIN,
+
+ /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// does not return a result. The first operand is a chain pointer. The
+ /// second is the ID number of the intrinsic from the llvm::Intrinsic
+ /// namespace. The operands to the intrinsic follow.
+ INTRINSIC_VOID,
+
+ // CopyToReg - This node has three operands: a chain, a register number to
+ // set to this value, and a value.
+ CopyToReg,
+
+ // CopyFromReg - This node indicates that the input value is a virtual or
+ // physical register that is defined outside of the scope of this
+ // SelectionDAG. The register is available from the RegSDNode object.
+ CopyFromReg,
+
+ // UNDEF - An undefined node
+ UNDEF,
+
+ /// FORMAL_ARGUMENTS(CHAIN, CC#, ISVARARG, FLAG0, ..., FLAGn) - This node
+ /// represents the formal arguments for a function. CC# is a Constant value
+ /// indicating the calling convention of the function, and ISVARARG is a
+ /// flag that indicates whether the function is varargs or not. This node
+ /// has one result value for each incoming argument, plus one for the output
+ /// chain. It must be custom legalized. See description of CALL node for
+ /// FLAG argument contents explanation.
+ ///
+ FORMAL_ARGUMENTS,
+
+ /// RV1, RV2...RVn, CHAIN = CALL(CHAIN, CC#, ISVARARG, ISTAILCALL, CALLEE,
+ /// ARG0, FLAG0, ARG1, FLAG1, ... ARGn, FLAGn)
+ /// This node represents a fully general function call, before the legalizer
+ /// runs. This has one result value for each argument / flag pair, plus
+ /// a chain result. It must be custom legalized. Flag argument indicates
+ /// misc. argument attributes. Currently:
+ /// Bit 0 - signness
+ /// Bit 1 - 'inreg' attribute
+ /// Bit 2 - 'sret' attribute
+ /// Bits 31:27 - argument ABI alignment in the first argument piece and
+ /// alignment '1' in other argument pieces.
+ CALL,
+
+ // EXTRACT_ELEMENT - This is used to get the first or second (determined by
+ // a Constant, which is required to be operand #1), element of the aggregate
+ // value specified as operand #0. This is only for use before legalization,
+ // for values that will be broken into multiple registers.
+ EXTRACT_ELEMENT,
+
+ // BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given
+ // two values of the same integer value type, this produces a value twice as
+ // big. Like EXTRACT_ELEMENT, this can only be used before legalization.
+ BUILD_PAIR,
+
+ // MERGE_VALUES - This node takes multiple discrete operands and returns
+ // them all as its individual results. This nodes has exactly the same
+ // number of inputs and outputs, and is only valid before legalization.
+ // This node is useful for some pieces of the code generator that want to
+ // think about a single node with multiple results, not multiple nodes.
+ MERGE_VALUES,
+
+ // Simple integer binary arithmetic operators.
+ ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
+
+ // CARRY_FALSE - This node is used when folding other nodes,
+ // like ADDC/SUBC, which indicate the carry result is always false.
+ CARRY_FALSE,
+
+ // Carry-setting nodes for multiple precision addition and subtraction.
+ // These nodes take two operands of the same value type, and produce two
+ // results. The first result is the normal add or sub result, the second
+ // result is the carry flag result.
+ ADDC, SUBC,
+
+ // Carry-using nodes for multiple precision addition and subtraction. These
+ // nodes take three operands: The first two are the normal lhs and rhs to
+ // the add or sub, and the third is the input carry flag. These nodes
+ // produce two results; the normal result of the add or sub, and the output
+ // carry flag. These nodes both read and write a carry flag to allow them
+ // to them to be chained together for add and sub of arbitrarily large
+ // values.
+ ADDE, SUBE,
+
+ // Simple binary floating point operators.
+ FADD, FSUB, FMUL, FDIV, FREM,
+
+ // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
+ // DAG node does not require that X and Y have the same type, just that they
+ // are both floating point. X and the result must have the same type.
+ // FCOPYSIGN(f32, f64) is allowed.
+ FCOPYSIGN,
+
+ /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector
+ /// with the specified, possibly variable, elements. The number of elements
+ /// is required to be a power of two.
+ BUILD_VECTOR,
+
+ /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
+ /// at IDX replaced with VAL.
+ INSERT_VECTOR_ELT,
+
+ /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
+ /// identified by the (potentially variable) element number IDX.
+ EXTRACT_VECTOR_ELT,
+
+ /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
+ /// vector type with the same length and element type, this produces a
+ /// concatenated vector result value, with length equal to the sum of the
+ /// lengths of the input vectors.
+ CONCAT_VECTORS,
+
+ /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
+ /// vector value) starting with the (potentially variable) element number
+ /// IDX, which must be a multiple of the result vector length.
+ EXTRACT_SUBVECTOR,
+
+ /// VECTOR_SHUFFLE(VEC1, VEC2, SHUFFLEVEC) - Returns a vector, of the same
+ /// type as VEC1/VEC2. SHUFFLEVEC is a BUILD_VECTOR of constant int values
+ /// (regardless of whether its datatype is legal or not) that indicate
+ /// which value each result element will get. The elements of VEC1/VEC2 are
+ /// enumerated in order. This is quite similar to the Altivec 'vperm'
+ /// instruction, except that the indices must be constants and are in terms
+ /// of the element size of VEC1/VEC2, not in terms of bytes.
+ VECTOR_SHUFFLE,
+
+ /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
+ /// scalar value into the low element of the resultant vector type. The top
+ /// elements of the vector are undefined.
+ SCALAR_TO_VECTOR,
+
+ // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
+ // an unsigned/signed value of type i[2*n], then return the top part.
+ MULHU, MULHS,
+
+ // Bitwise operators - logical and, logical or, logical xor, shift left,
+ // shift right algebraic (shift in sign bits), shift right logical (shift in
+ // zeroes), rotate left, rotate right, and byteswap.
+ AND, OR, XOR, SHL, SRA, SRL, ROTL, ROTR, BSWAP,
+
+ // Counting operators
+ CTTZ, CTLZ, CTPOP,
+
+ // Select(COND, TRUEVAL, FALSEVAL)
+ SELECT,
+
+ // Select with condition operator - This selects between a true value and
+ // a false value (ops #2 and #3) based on the boolean result of comparing
+ // the lhs and rhs (ops #0 and #1) of a conditional expression with the
+ // condition code in op #4, a CondCodeSDNode.
+ SELECT_CC,
+
+ // SetCC operator - This evaluates to a boolean (i1) true value if the
+ // condition is true. The operands to this are the left and right operands
+ // to compare (ops #0, and #1) and the condition code to compare them with
+ // (op #2) as a CondCodeSDNode.
+ SETCC,
+
+ // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
+ // integer shift operations, just like ADD/SUB_PARTS. The operation
+ // ordering is:
+ // [Lo,Hi] = op [LoLHS,HiLHS], Amt
+ SHL_PARTS, SRA_PARTS, SRL_PARTS,
+
+ // Conversion operators. These are all single input single output
+ // operations. For all of these, the result type must be strictly
+ // wider or narrower (depending on the operation) than the source
+ // type.
+
+ // SIGN_EXTEND - Used for integer types, replicating the sign bit
+ // into new bits.
+ SIGN_EXTEND,
+
+ // ZERO_EXTEND - Used for integer types, zeroing the new bits.
+ ZERO_EXTEND,
+
+ // ANY_EXTEND - Used for integer types. The high bits are undefined.
+ ANY_EXTEND,
+
+ // TRUNCATE - Completely drop the high bits.
+ TRUNCATE,
+
+ // [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
+ // depends on the first letter) to floating point.
+ SINT_TO_FP,
+ UINT_TO_FP,
+
+ // SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
+ // sign extend a small value in a large integer register (e.g. sign
+ // extending the low 8 bits of a 32-bit register to fill the top 24 bits
+ // with the 7th bit). The size of the smaller type is indicated by the 1th
+ // operand, a ValueType node.
+ SIGN_EXTEND_INREG,
+
+ // FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
+ // integer.
+ FP_TO_SINT,
+ FP_TO_UINT,
+
+ // FP_ROUND - Perform a rounding operation from the current
+ // precision down to the specified precision (currently always 64->32).
+ FP_ROUND,
+
+ // FP_ROUND_INREG - This operator takes a floating point register, and
+ // rounds it to a floating point value. It then promotes it and returns it
+ // in a register of the same size. This operation effectively just discards
+ // excess precision. The type to round down to is specified by the 1th
+ // operation, a VTSDNode (currently always 64->32->64).
+ FP_ROUND_INREG,
+
+ // FP_EXTEND - Extend a smaller FP type into a larger FP type.
+ FP_EXTEND,
+
+ // BIT_CONVERT - Theis operator converts between integer and FP values, as
+ // if one was stored to memory as integer and the other was loaded from the
+ // same address (or equivalently for vector format conversions, etc). The
+ // source and result are required to have the same bit size (e.g.
+ // f32 <-> i32). This can also be used for int-to-int or fp-to-fp
+ // conversions, but that is a noop, deleted by getNode().
+ BIT_CONVERT,
+
+ // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI - Perform unary floating point
+ // negation, absolute value, square root, sine and cosine, and powi
+ // operations.
+ FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI,
+
+ // LOAD and STORE have token chains as their first operand, then the same
+ // operands as an LLVM load/store instruction, then an offset node that
+ // is added / subtracted from the base pointer to form the address (for
+ // indexed memory ops).
+ LOAD, STORE,
+
+ // TRUNCSTORE - This operators truncates (for integer) or rounds (for FP) a
+ // value and stores it to memory in one operation. This can be used for
+ // either integer or floating point operands. The first four operands of
+ // this are the same as a standard store. The fifth is the ValueType to
+ // store it as (which will be smaller than the source value).
+ TRUNCSTORE,
+
+ // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
+ // to a specified boundary. This node always has two return values: a new
+ // stack pointer value and a chain. The first operand is the token chain,
+ // the second is the number of bytes to allocate, and the third is the
+ // alignment boundary. The size is guaranteed to be a multiple of the stack
+ // alignment, and the alignment is guaranteed to be bigger than the stack
+ // alignment (if required) or 0 to get standard stack alignment.
+ DYNAMIC_STACKALLOC,
+
+ // Control flow instructions. These all have token chains.
+
+ // BR - Unconditional branch. The first operand is the chain
+ // operand, the second is the MBB to branch to.
+ BR,
+
+ // BRIND - Indirect branch. The first operand is the chain, the second
+ // is the value to branch to, which must be of the same type as the target's
+ // pointer type.
+ BRIND,
+
+ // BR_JT - Jumptable branch. The first operand is the chain, the second
+ // is the jumptable index, the last one is the jumptable entry index.
+ BR_JT,
+
+ // BRCOND - Conditional branch. The first operand is the chain,
+ // the second is the condition, the third is the block to branch
+ // to if the condition is true.
+ BRCOND,
+
+ // BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
+ // that the condition is represented as condition code, and two nodes to
+ // compare, rather than as a combined SetCC node. The operands in order are
+ // chain, cc, lhs, rhs, block to branch to if condition is true.
+ BR_CC,
+
+ // RET - Return from function. The first operand is the chain,
+ // and any subsequent operands are pairs of return value and return value
+ // signness for the function. This operation can have variable number of
+ // operands.
+ RET,
+
+ // INLINEASM - Represents an inline asm block. This node always has two
+ // return values: a chain and a flag result. The inputs are as follows:
+ // Operand #0 : Input chain.
+ // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
+ // Operand #2n+2: A RegisterNode.
+ // Operand #2n+3: A TargetConstant, indicating if the reg is a use/def
+ // Operand #last: Optional, an incoming flag.
+ INLINEASM,
+
+ // LABEL - Represents a label in mid basic block used to track
+ // locations needed for debug and exception handling tables. This node
+ // returns a chain.
+ // Operand #0 : input chain.
+ // Operand #1 : module unique number use to identify the label.
+ LABEL,
+
+ // STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
+ // value, the same type as the pointer type for the system, and an output
+ // chain.
+ STACKSAVE,
+
+ // STACKRESTORE has two operands, an input chain and a pointer to restore to
+ // it returns an output chain.
+ STACKRESTORE,
+
+ // MEMSET/MEMCPY/MEMMOVE - The first operand is the chain, and the rest
+ // correspond to the operands of the LLVM intrinsic functions. The only
+ // result is a token chain. The alignment argument is guaranteed to be a
+ // Constant node.
+ MEMSET,
+ MEMMOVE,
+ MEMCPY,
+
+ // CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of
+ // a call sequence, and carry arbitrary information that target might want
+ // to know. The first operand is a chain, the rest are specified by the
+ // target and not touched by the DAG optimizers.
+ CALLSEQ_START, // Beginning of a call sequence
+ CALLSEQ_END, // End of a call sequence
+
+ // VAARG - VAARG has three operands: an input chain, a pointer, and a
+ // SRCVALUE. It returns a pair of values: the vaarg value and a new chain.
+ VAARG,
+
+ // VACOPY - VACOPY has five operands: an input chain, a destination pointer,
+ // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
+ // source.
+ VACOPY,
+
+ // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a
+ // pointer, and a SRCVALUE.
+ VAEND, VASTART,
+
+ // SRCVALUE - This corresponds to a Value*, and is used to associate memory
+ // locations with their value. This allows one use alias analysis
+ // information in the backend.
+ SRCVALUE,
+
+ // PCMARKER - This corresponds to the pcmarker intrinsic.
+ PCMARKER,
+
+ // READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
+ // The only operand is a chain and a value and a chain are produced. The
+ // value is the contents of the architecture specific cycle counter like
+ // register (or other high accuracy low latency clock source)
+ READCYCLECOUNTER,
+
+ // HANDLENODE node - Used as a handle for various purposes.
+ HANDLENODE,
+
+ // LOCATION - This node is used to represent a source location for debug
+ // info. It takes token chain as input, then a line number, then a column
+ // number, then a filename, then a working dir. It produces a token chain
+ // as output.
+ LOCATION,
+
+ // DEBUG_LOC - This node is used to represent source line information
+ // embedded in the code. It takes a token chain as input, then a line
+ // number, then a column then a file id (provided by MachineModuleInfo.) It
+ // produces a token chain as output.
+ DEBUG_LOC,
+
+ // BUILTIN_OP_END - This must be the last enum value in this list.
+ BUILTIN_OP_END
+ };
+
+ /// Node predicates
+
+ /// isBuildVectorAllOnes - Return true if the specified node is a
+ /// BUILD_VECTOR where all of the elements are ~0 or undef.
+ bool isBuildVectorAllOnes(const SDNode *N);
+
+ /// isBuildVectorAllZeros - Return true if the specified node is a
+ /// BUILD_VECTOR where all of the elements are 0 or undef.
+ bool isBuildVectorAllZeros(const SDNode *N);
+
+ //===--------------------------------------------------------------------===//
+ /// MemIndexedMode enum - This enum defines the load / store indexed
+ /// addressing modes.
+ ///
+ /// UNINDEXED "Normal" load / store. The effective address is already
+ /// computed and is available in the base pointer. The offset
+ /// operand is always undefined. In addition to producing a
+ /// chain, an unindexed load produces one value (result of the
+ /// load); an unindexed store does not produces a value.
+ ///
+ /// PRE_INC Similar to the unindexed mode where the effective address is
+ /// PRE_DEC the value of the base pointer add / subtract the offset.
+ /// It considers the computation as being folded into the load /
+ /// store operation (i.e. the load / store does the address
+ /// computation as well as performing the memory transaction).
+ /// The base operand is always undefined. In addition to
+ /// producing a chain, pre-indexed load produces two values
+ /// (result of the load and the result of the address
+ /// computation); a pre-indexed store produces one value (result
+ /// of the address computation).
+ ///
+ /// POST_INC The effective address is the value of the base pointer. The
+ /// POST_DEC value of the offset operand is then added to / subtracted
+ /// from the base after memory transaction. In addition to
+ /// producing a chain, post-indexed load produces two values
+ /// (the result of the load and the result of the base +/- offset
+ /// computation); a post-indexed store produces one value (the
+ /// the result of the base +/- offset computation).
+ ///
+ enum MemIndexedMode {
+ UNINDEXED = 0,
+ PRE_INC,
+ PRE_DEC,
+ POST_INC,
+ POST_DEC,
+ LAST_INDEXED_MODE
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// LoadExtType enum - This enum defines the three variants of LOADEXT
+ /// (load with extension).
+ ///
+ /// SEXTLOAD loads the integer operand and sign extends it to a larger
+ /// integer result type.
+ /// ZEXTLOAD loads the integer operand and zero extends it to a larger
+ /// integer result type.
+ /// EXTLOAD is used for three things: floating point extending loads,
+ /// integer extending loads [the top bits are undefined], and vector
+ /// extending loads [load into low elt].
+ ///
+ enum LoadExtType {
+ NON_EXTLOAD = 0,
+ EXTLOAD,
+ SEXTLOAD,
+ ZEXTLOAD,
+ LAST_LOADX_TYPE
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// ISD::CondCode enum - These are ordered carefully to make the bitfields
+ /// below work out, when considering SETFALSE (something that never exists
+ /// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered
+ /// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
+ /// to. If the "N" column is 1, the result of the comparison is undefined if
+ /// the input is a NAN.
+ ///
+ /// All of these (except for the 'always folded ops') should be handled for
+ /// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
+ /// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
+ ///
+ /// Note that these are laid out in a specific order to allow bit-twiddling
+ /// to transform conditions.
+ enum CondCode {
+ // Opcode N U L G E Intuitive operation
+ SETFALSE, // 0 0 0 0 Always false (always folded)
+ SETOEQ, // 0 0 0 1 True if ordered and equal
+ SETOGT, // 0 0 1 0 True if ordered and greater than
+ SETOGE, // 0 0 1 1 True if ordered and greater than or equal
+ SETOLT, // 0 1 0 0 True if ordered and less than
+ SETOLE, // 0 1 0 1 True if ordered and less than or equal
+ SETONE, // 0 1 1 0 True if ordered and operands are unequal
+ SETO, // 0 1 1 1 True if ordered (no nans)
+ SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ SETUEQ, // 1 0 0 1 True if unordered or equal
+ SETUGT, // 1 0 1 0 True if unordered or greater than
+ SETUGE, // 1 0 1 1 True if unordered, greater than, or equal
+ SETULT, // 1 1 0 0 True if unordered or less than
+ SETULE, // 1 1 0 1 True if unordered, less than, or equal
+ SETUNE, // 1 1 1 0 True if unordered or not equal
+ SETTRUE, // 1 1 1 1 Always true (always folded)
+ // Don't care operations: undefined if the input is a nan.
+ SETFALSE2, // 1 X 0 0 0 Always false (always folded)
+ SETEQ, // 1 X 0 0 1 True if equal
+ SETGT, // 1 X 0 1 0 True if greater than
+ SETGE, // 1 X 0 1 1 True if greater than or equal
+ SETLT, // 1 X 1 0 0 True if less than
+ SETLE, // 1 X 1 0 1 True if less than or equal
+ SETNE, // 1 X 1 1 0 True if not equal
+ SETTRUE2, // 1 X 1 1 1 Always true (always folded)
+
+ SETCC_INVALID // Marker value.
+ };
+
+ /// isSignedIntSetCC - Return true if this is a setcc instruction that
+ /// performs a signed comparison when used with integer operands.
+ inline bool isSignedIntSetCC(CondCode Code) {
+ return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
+ }
+
+ /// isUnsignedIntSetCC - Return true if this is a setcc instruction that
+ /// performs an unsigned comparison when used with integer operands.
+ inline bool isUnsignedIntSetCC(CondCode Code) {
+ return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
+ }
+
+ /// isTrueWhenEqual - Return true if the specified condition returns true if
+ /// the two operands to the condition are equal. Note that if one of the two
+ /// operands is a NaN, this value is meaningless.
+ inline bool isTrueWhenEqual(CondCode Cond) {
+ return ((int)Cond & 1) != 0;
+ }
+
+ /// getUnorderedFlavor - This function returns 0 if the condition is always
+ /// false if an operand is a NaN, 1 if the condition is always true if the
+ /// operand is a NaN, and 2 if the condition is undefined if the operand is a
+ /// NaN.
+ inline unsigned getUnorderedFlavor(CondCode Cond) {
+ return ((int)Cond >> 3) & 3;
+ }
+
+ /// getSetCCInverse - Return the operation corresponding to !(X op Y), where
+ /// 'op' is a valid SetCC operation.
+ CondCode getSetCCInverse(CondCode Operation, bool isInteger);
+
+ /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
+ /// when given the operation for (X op Y).
+ CondCode getSetCCSwappedOperands(CondCode Operation);
+
+ /// getSetCCOrOperation - Return the result of a logical OR between different
+ /// comparisons of identical values: ((X op1 Y) | (X op2 Y)). This
+ /// function returns SETCC_INVALID if it is not possible to represent the
+ /// resultant comparison.
+ CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger);
+
+ /// getSetCCAndOperation - Return the result of a logical AND between
+ /// different comparisons of identical values: ((X op1 Y) & (X op2 Y)). This
+ /// function returns SETCC_INVALID if it is not possible to represent the
+ /// resultant comparison.
+ CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
+} // end llvm::ISD namespace
+
+
+//===----------------------------------------------------------------------===//
+/// SDOperand - Unlike LLVM values, Selection DAG nodes may return multiple
+/// values as the result of a computation. Many nodes return multiple values,
+/// from loads (which define a token and a return value) to ADDC (which returns
+/// a result and a carry value), to calls (which may return an arbitrary number
+/// of values).
+///
+/// As such, each use of a SelectionDAG computation must indicate the node that
+/// computes it as well as which return value to use from that node. This pair
+/// of information is represented with the SDOperand value type.
+///
+class SDOperand {
+public:
+ SDNode *Val; // The node defining the value we are using.
+ unsigned ResNo; // Which return value of the node we are using.
+
+ SDOperand() : Val(0), ResNo(0) {}
+ SDOperand(SDNode *val, unsigned resno) : Val(val), ResNo(resno) {}
+
+ bool operator==(const SDOperand &O) const {
+ return Val == O.Val && ResNo == O.ResNo;
+ }
+ bool operator!=(const SDOperand &O) const {
+ return !operator==(O);
+ }
+ bool operator<(const SDOperand &O) const {
+ return Val < O.Val || (Val == O.Val && ResNo < O.ResNo);
+ }
+
+ SDOperand getValue(unsigned R) const {
+ return SDOperand(Val, R);
+ }
+
+ // isOperand - Return true if this node is an operand of N.
+ bool isOperand(SDNode *N) const;
+
+ /// getValueType - Return the ValueType of the referenced return value.
+ ///
+ inline MVT::ValueType getValueType() const;
+
+ // Forwarding methods - These forward to the corresponding methods in SDNode.
+ inline unsigned getOpcode() const;
+ inline unsigned getNumOperands() const;
+ inline const SDOperand &getOperand(unsigned i) const;
+ inline uint64_t getConstantOperandVal(unsigned i) const;
+ inline bool isTargetOpcode() const;
+ inline unsigned getTargetOpcode() const;
+
+ /// hasOneUse - Return true if there is exactly one operation using this
+ /// result value of the defining operator.
+ inline bool hasOneUse() const;
+};
+
+
+template<> struct DenseMapKeyInfo<SDOperand> {
+ static inline SDOperand getEmptyKey() { return SDOperand((SDNode*)-1, -1U); }
+ static inline SDOperand getTombstoneKey() { return SDOperand((SDNode*)-1, 0);}
+ static unsigned getHashValue(const SDOperand &Val) {
+ return (unsigned)((uintptr_t)Val.Val >> 4) ^
+ (unsigned)((uintptr_t)Val.Val >> 9) + Val.ResNo;
+ }
+ static bool isPod() { return true; }
+};
+
+/// simplify_type specializations - Allow casting operators to work directly on
+/// SDOperands as if they were SDNode*'s.
+template<> struct simplify_type<SDOperand> {
+ typedef SDNode* SimpleType;
+ static SimpleType getSimplifiedValue(const SDOperand &Val) {
+ return static_cast<SimpleType>(Val.Val);
+ }
+};
+template<> struct simplify_type<const SDOperand> {
+ typedef SDNode* SimpleType;
+ static SimpleType getSimplifiedValue(const SDOperand &Val) {
+ return static_cast<SimpleType>(Val.Val);
+ }
+};
+
+
+/// SDNode - Represents one node in the SelectionDAG.
+///
+class SDNode : public FoldingSetNode {
+ /// NodeType - The operation that this node performs.
+ ///
+ unsigned short NodeType;
+
+ /// OperandsNeedDelete - This is true if OperandList was new[]'d. If true,
+ /// then they will be delete[]'d when the node is destroyed.
+ bool OperandsNeedDelete : 1;
+
+ /// NodeId - Unique id per SDNode in the DAG.
+ int NodeId;
+
+ /// OperandList - The values that are used by this operation.
+ ///
+ SDOperand *OperandList;
+
+ /// ValueList - The types of the values this node defines. SDNode's may
+ /// define multiple values simultaneously.
+ const MVT::ValueType *ValueList;
+
+ /// NumOperands/NumValues - The number of entries in the Operand/Value list.
+ unsigned short NumOperands, NumValues;
+
+ /// Prev/Next pointers - These pointers form the linked list of of the
+ /// AllNodes list in the current DAG.
+ SDNode *Prev, *Next;
+ friend struct ilist_traits<SDNode>;
+
+ /// Uses - These are all of the SDNode's that use a value produced by this
+ /// node.
+ SmallVector<SDNode*,3> Uses;
+
+ // Out-of-line virtual method to give class a home.
+ virtual void ANCHOR();
+public:
+ virtual ~SDNode() {
+ assert(NumOperands == 0 && "Operand list not cleared before deletion");
+ NodeType = ISD::DELETED_NODE;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Accessors
+ //
+ unsigned getOpcode() const { return NodeType; }
+ bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
+ unsigned getTargetOpcode() const {
+ assert(isTargetOpcode() && "Not a target opcode!");
+ return NodeType - ISD::BUILTIN_OP_END;
+ }
+
+ size_t use_size() const { return Uses.size(); }
+ bool use_empty() const { return Uses.empty(); }
+ bool hasOneUse() const { return Uses.size() == 1; }
+
+ /// getNodeId - Return the unique node id.
+ ///
+ int getNodeId() const { return NodeId; }
+
+ typedef SmallVector<SDNode*,3>::const_iterator use_iterator;
+ use_iterator use_begin() const { return Uses.begin(); }
+ use_iterator use_end() const { return Uses.end(); }
+
+ /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
+ /// indicated value. This method ignores uses of other values defined by this
+ /// operation.
+ bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
+
+ /// isOnlyUse - Return true if this node is the only use of N.
+ ///
+ bool isOnlyUse(SDNode *N) const;
+
+ /// isOperand - Return true if this node is an operand of N.
+ ///
+ bool isOperand(SDNode *N) const;
+
+ /// isPredecessor - Return true if this node is a predecessor of N. This node
+ /// is either an operand of N or it can be reached by recursively traversing
+ /// up the operands.
+ /// NOTE: this is an expensive method. Use it carefully.
+ bool isPredecessor(SDNode *N) const;
+
+ /// getNumOperands - Return the number of values used by this operation.
+ ///
+ unsigned getNumOperands() const { return NumOperands; }
+
+ /// getConstantOperandVal - Helper method returns the integer value of a
+ /// ConstantSDNode operand.
+ uint64_t getConstantOperandVal(unsigned Num) const;
+
+ const SDOperand &getOperand(unsigned Num) const {
+ assert(Num < NumOperands && "Invalid child # of SDNode!");
+ return OperandList[Num];
+ }
+
+ typedef const SDOperand* op_iterator;
+ op_iterator op_begin() const { return OperandList; }
+ op_iterator op_end() const { return OperandList+NumOperands; }
+
+
+ SDVTList getVTList() const {
+ SDVTList X = { ValueList, NumValues };
+ return X;
+ };
+
+ /// getNumValues - Return the number of values defined/returned by this
+ /// operator.
+ ///
+ unsigned getNumValues() const { return NumValues; }
+
+ /// getValueType - Return the type of a specified result.
+ ///
+ MVT::ValueType getValueType(unsigned ResNo) const {
+ assert(ResNo < NumValues && "Illegal result number!");
+ return ValueList[ResNo];
+ }
+
+ typedef const MVT::ValueType* value_iterator;
+ value_iterator value_begin() const { return ValueList; }
+ value_iterator value_end() const { return ValueList+NumValues; }
+
+ /// getOperationName - Return the opcode of this operation for printing.
+ ///
+ std::string getOperationName(const SelectionDAG *G = 0) const;
+ static const char* getIndexedModeName(ISD::MemIndexedMode AM);
+ void dump() const;
+ void dump(const SelectionDAG *G) const;
+
+ static bool classof(const SDNode *) { return true; }
+
+ /// Profile - Gather unique data for the node.
+ ///
+ void Profile(FoldingSetNodeID &ID);
+
+protected:
+ friend class SelectionDAG;
+
+ /// getValueTypeList - Return a pointer to the specified value type.
+ ///
+ static MVT::ValueType *getValueTypeList(MVT::ValueType VT);
+ static SDVTList getSDVTList(MVT::ValueType VT) {
+ SDVTList Ret = { getValueTypeList(VT), 1 };
+ return Ret;
+ }
+
+ SDNode(unsigned Opc, SDVTList VTs, const SDOperand *Ops, unsigned NumOps)
+ : NodeType(Opc), NodeId(-1) {
+ OperandsNeedDelete = true;
+ NumOperands = NumOps;
+ OperandList = NumOps ? new SDOperand[NumOperands] : 0;
+
+ for (unsigned i = 0; i != NumOps; ++i) {
+ OperandList[i] = Ops[i];
+ Ops[i].Val->Uses.push_back(this);
+ }
+
+ ValueList = VTs.VTs;
+ NumValues = VTs.NumVTs;
+ Prev = 0; Next = 0;
+ }
+ SDNode(unsigned Opc, SDVTList VTs) : NodeType(Opc), NodeId(-1) {
+ OperandsNeedDelete = false; // Operands set with InitOperands.
+ NumOperands = 0;
+ OperandList = 0;
+
+ ValueList = VTs.VTs;
+ NumValues = VTs.NumVTs;
+ Prev = 0; Next = 0;
+ }
+
+ /// InitOperands - Initialize the operands list of this node with the
+ /// specified values, which are part of the node (thus they don't need to be
+ /// copied in or allocated).
+ void InitOperands(SDOperand *Ops, unsigned NumOps) {
+ assert(OperandList == 0 && "Operands already set!");
+ NumOperands = NumOps;
+ OperandList = Ops;
+
+ for (unsigned i = 0; i != NumOps; ++i)
+ Ops[i].Val->Uses.push_back(this);
+ }
+
+ /// MorphNodeTo - This frees the operands of the current node, resets the
+ /// opcode, types, and operands to the specified value. This should only be
+ /// used by the SelectionDAG class.
+ void MorphNodeTo(unsigned Opc, SDVTList L,
+ const SDOperand *Ops, unsigned NumOps);
+
+ void addUser(SDNode *User) {
+ Uses.push_back(User);
+ }
+ void removeUser(SDNode *User) {
+ // Remove this user from the operand's use list.
+ for (unsigned i = Uses.size(); ; --i) {
+ assert(i != 0 && "Didn't find user!");
+ if (Uses[i-1] == User) {
+ Uses[i-1] = Uses.back();
+ Uses.pop_back();
+ return;
+ }
+ }
+ }
+
+ void setNodeId(int Id) {
+ NodeId = Id;
+ }
+};
+
+
+// Define inline functions from the SDOperand class.
+
+inline unsigned SDOperand::getOpcode() const {
+ return Val->getOpcode();
+}
+inline MVT::ValueType SDOperand::getValueType() const {
+ return Val->getValueType(ResNo);
+}
+inline unsigned SDOperand::getNumOperands() const {
+ return Val->getNumOperands();
+}
+inline const SDOperand &SDOperand::getOperand(unsigned i) const {
+ return Val->getOperand(i);
+}
+inline uint64_t SDOperand::getConstantOperandVal(unsigned i) const {
+ return Val->getConstantOperandVal(i);
+}
+inline bool SDOperand::isTargetOpcode() const {
+ return Val->isTargetOpcode();
+}
+inline unsigned SDOperand::getTargetOpcode() const {
+ return Val->getTargetOpcode();
+}
+inline bool SDOperand::hasOneUse() const {
+ return Val->hasNUsesOfValue(1, ResNo);
+}
+
+/// UnarySDNode - This class is used for single-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class UnarySDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Op;
+public:
+ UnarySDNode(unsigned Opc, SDVTList VTs, SDOperand X)
+ : SDNode(Opc, VTs), Op(X) {
+ InitOperands(&Op, 1);
+ }
+};
+
+/// BinarySDNode - This class is used for two-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class BinarySDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[2];
+public:
+ BinarySDNode(unsigned Opc, SDVTList VTs, SDOperand X, SDOperand Y)
+ : SDNode(Opc, VTs) {
+ Ops[0] = X;
+ Ops[1] = Y;
+ InitOperands(Ops, 2);
+ }
+};
+
+/// TernarySDNode - This class is used for three-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class TernarySDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[3];
+public:
+ TernarySDNode(unsigned Opc, SDVTList VTs, SDOperand X, SDOperand Y,
+ SDOperand Z)
+ : SDNode(Opc, VTs) {
+ Ops[0] = X;
+ Ops[1] = Y;
+ Ops[2] = Z;
+ InitOperands(Ops, 3);
+ }
+};
+
+
+/// HandleSDNode - This class is used to form a handle around another node that
+/// is persistant and is updated across invocations of replaceAllUsesWith on its
+/// operand. This node should be directly created by end-users and not added to
+/// the AllNodes list.
+class HandleSDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Op;
+public:
+ explicit HandleSDNode(SDOperand X)
+ : SDNode(ISD::HANDLENODE, getSDVTList(MVT::Other)), Op(X) {
+ InitOperands(&Op, 1);
+ }
+ ~HandleSDNode();
+ SDOperand getValue() const { return Op; }
+};
+
+class StringSDNode : public SDNode {
+ std::string Value;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit StringSDNode(const std::string &val)
+ : SDNode(ISD::STRING, getSDVTList(MVT::Other)), Value(val) {
+ }
+public:
+ const std::string &getValue() const { return Value; }
+ static bool classof(const StringSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::STRING;
+ }
+};
+
+class ConstantSDNode : public SDNode {
+ uint64_t Value;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ ConstantSDNode(bool isTarget, uint64_t val, MVT::ValueType VT)
+ : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, getSDVTList(VT)),
+ Value(val) {
+ }
+public:
+
+ uint64_t getValue() const { return Value; }
+
+ int64_t getSignExtended() const {
+ unsigned Bits = MVT::getSizeInBits(getValueType(0));
+ return ((int64_t)Value << (64-Bits)) >> (64-Bits);
+ }
+
+ bool isNullValue() const { return Value == 0; }
+ bool isAllOnesValue() const {
+ return Value == MVT::getIntVTBitMask(getValueType(0));
+ }
+
+ static bool classof(const ConstantSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::Constant ||
+ N->getOpcode() == ISD::TargetConstant;
+ }
+};
+
+class ConstantFPSDNode : public SDNode {
+ double Value;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ ConstantFPSDNode(bool isTarget, double val, MVT::ValueType VT)
+ : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
+ getSDVTList(VT)), Value(val) {
+ }
+public:
+
+ double getValue() const { return Value; }
+
+ /// isExactlyValue - We don't rely on operator== working on double values, as
+ /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
+ /// As such, this method can be used to do an exact bit-for-bit comparison of
+ /// two floating point values.
+ bool isExactlyValue(double V) const;
+
+ static bool classof(const ConstantFPSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::ConstantFP ||
+ N->getOpcode() == ISD::TargetConstantFP;
+ }
+};
+
+class GlobalAddressSDNode : public SDNode {
+ GlobalValue *TheGlobal;
+ int Offset;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT,
+ int o = 0);
+public:
+
+ GlobalValue *getGlobal() const { return TheGlobal; }
+ int getOffset() const { return Offset; }
+
+ static bool classof(const GlobalAddressSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::GlobalAddress ||
+ N->getOpcode() == ISD::TargetGlobalAddress ||
+ N->getOpcode() == ISD::GlobalTLSAddress ||
+ N->getOpcode() == ISD::TargetGlobalTLSAddress;
+ }
+};
+
+class FrameIndexSDNode : public SDNode {
+ int FI;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ FrameIndexSDNode(int fi, MVT::ValueType VT, bool isTarg)
+ : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, getSDVTList(VT)),
+ FI(fi) {
+ }
+public:
+
+ int getIndex() const { return FI; }
+
+ static bool classof(const FrameIndexSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::FrameIndex ||
+ N->getOpcode() == ISD::TargetFrameIndex;
+ }
+};
+
+class JumpTableSDNode : public SDNode {
+ int JTI;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ JumpTableSDNode(int jti, MVT::ValueType VT, bool isTarg)
+ : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, getSDVTList(VT)),
+ JTI(jti) {
+ }
+public:
+
+ int getIndex() const { return JTI; }
+
+ static bool classof(const JumpTableSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::JumpTable ||
+ N->getOpcode() == ISD::TargetJumpTable;
+ }
+};
+
+class ConstantPoolSDNode : public SDNode {
+ union {
+ Constant *ConstVal;
+ MachineConstantPoolValue *MachineCPVal;
+ } Val;
+ int Offset; // It's a MachineConstantPoolValue if top bit is set.
+ unsigned Alignment;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT,
+ int o=0)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ getSDVTList(VT)), Offset(o), Alignment(0) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.ConstVal = c;
+ }
+ ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT, int o,
+ unsigned Align)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ getSDVTList(VT)), Offset(o), Alignment(Align) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.ConstVal = c;
+ }
+ ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
+ MVT::ValueType VT, int o=0)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ getSDVTList(VT)), Offset(o), Alignment(0) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.MachineCPVal = v;
+ Offset |= 1 << (sizeof(unsigned)*8-1);
+ }
+ ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
+ MVT::ValueType VT, int o, unsigned Align)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ getSDVTList(VT)), Offset(o), Alignment(Align) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.MachineCPVal = v;
+ Offset |= 1 << (sizeof(unsigned)*8-1);
+ }
+public:
+
+ bool isMachineConstantPoolEntry() const {
+ return (int)Offset < 0;
+ }
+
+ Constant *getConstVal() const {
+ assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
+ return Val.ConstVal;
+ }
+
+ MachineConstantPoolValue *getMachineCPVal() const {
+ assert(isMachineConstantPoolEntry() && "Wrong constantpool type");
+ return Val.MachineCPVal;
+ }
+
+ int getOffset() const {
+ return Offset & ~(1 << (sizeof(unsigned)*8-1));
+ }
+
+ // Return the alignment of this constant pool object, which is either 0 (for
+ // default alignment) or log2 of the desired value.
+ unsigned getAlignment() const { return Alignment; }
+
+ const Type *getType() const;
+
+ static bool classof(const ConstantPoolSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::ConstantPool ||
+ N->getOpcode() == ISD::TargetConstantPool;
+ }
+};
+
+class BasicBlockSDNode : public SDNode {
+ MachineBasicBlock *MBB;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit BasicBlockSDNode(MachineBasicBlock *mbb)
+ : SDNode(ISD::BasicBlock, getSDVTList(MVT::Other)), MBB(mbb) {
+ }
+public:
+
+ MachineBasicBlock *getBasicBlock() const { return MBB; }
+
+ static bool classof(const BasicBlockSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::BasicBlock;
+ }
+};
+
+class SrcValueSDNode : public SDNode {
+ const Value *V;
+ int offset;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ SrcValueSDNode(const Value* v, int o)
+ : SDNode(ISD::SRCVALUE, getSDVTList(MVT::Other)), V(v), offset(o) {
+ }
+
+public:
+ const Value *getValue() const { return V; }
+ int getOffset() const { return offset; }
+
+ static bool classof(const SrcValueSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::SRCVALUE;
+ }
+};
+
+
+class RegisterSDNode : public SDNode {
+ unsigned Reg;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ RegisterSDNode(unsigned reg, MVT::ValueType VT)
+ : SDNode(ISD::Register, getSDVTList(VT)), Reg(reg) {
+ }
+public:
+
+ unsigned getReg() const { return Reg; }
+
+ static bool classof(const RegisterSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::Register;
+ }
+};
+
+class ExternalSymbolSDNode : public SDNode {
+ const char *Symbol;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT::ValueType VT)
+ : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
+ getSDVTList(VT)), Symbol(Sym) {
+ }
+public:
+
+ const char *getSymbol() const { return Symbol; }
+
+ static bool classof(const ExternalSymbolSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::ExternalSymbol ||
+ N->getOpcode() == ISD::TargetExternalSymbol;
+ }
+};
+
+class CondCodeSDNode : public SDNode {
+ ISD::CondCode Condition;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit CondCodeSDNode(ISD::CondCode Cond)
+ : SDNode(ISD::CONDCODE, getSDVTList(MVT::Other)), Condition(Cond) {
+ }
+public:
+
+ ISD::CondCode get() const { return Condition; }
+
+ static bool classof(const CondCodeSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::CONDCODE;
+ }
+};
+
+/// VTSDNode - This class is used to represent MVT::ValueType's, which are used
+/// to parameterize some operations.
+class VTSDNode : public SDNode {
+ MVT::ValueType ValueType;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit VTSDNode(MVT::ValueType VT)
+ : SDNode(ISD::VALUETYPE, getSDVTList(MVT::Other)), ValueType(VT) {
+ }
+public:
+
+ MVT::ValueType getVT() const { return ValueType; }
+
+ static bool classof(const VTSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::VALUETYPE;
+ }
+};
+
+/// LoadSDNode - This class is used to represent ISD::LOAD nodes.
+///
+class LoadSDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[3];
+
+ // AddrMode - unindexed, pre-indexed, post-indexed.
+ ISD::MemIndexedMode AddrMode;
+
+ // ExtType - non-ext, anyext, sext, zext.
+ ISD::LoadExtType ExtType;
+
+ // LoadedVT - VT of loaded value before extension.
+ MVT::ValueType LoadedVT;
+
+ // SrcValue - Memory location for alias analysis.
+ const Value *SrcValue;
+
+ // SVOffset - Memory location offset.
+ int SVOffset;
+
+ // Alignment - Alignment of memory location in bytes.
+ unsigned Alignment;
+
+ // IsVolatile - True if the load is volatile.
+ bool IsVolatile;
+protected:
+ friend class SelectionDAG;
+ LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs,
+ ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT,
+ const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
+ : SDNode(ISD::LOAD, VTs),
+ AddrMode(AM), ExtType(ETy), LoadedVT(LVT), SrcValue(SV), SVOffset(O),
+ Alignment(Align), IsVolatile(Vol) {
+ Ops[0] = ChainPtrOff[0]; // Chain
+ Ops[1] = ChainPtrOff[1]; // Ptr
+ Ops[2] = ChainPtrOff[2]; // Off
+ InitOperands(Ops, 3);
+ assert(Align != 0 && "Loads should have non-zero aligment");
+ assert((getOffset().getOpcode() == ISD::UNDEF ||
+ AddrMode != ISD::UNINDEXED) &&
+ "Only indexed load has a non-undef offset operand");
+ }
+public:
+
+ const SDOperand getChain() const { return getOperand(0); }
+ const SDOperand getBasePtr() const { return getOperand(1); }
+ const SDOperand getOffset() const { return getOperand(2); }
+ ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
+ ISD::LoadExtType getExtensionType() const { return ExtType; }
+ MVT::ValueType getLoadedVT() const { return LoadedVT; }
+ const Value *getSrcValue() const { return SrcValue; }
+ int getSrcValueOffset() const { return SVOffset; }
+ unsigned getAlignment() const { return Alignment; }
+ bool isVolatile() const { return IsVolatile; }
+
+ static bool classof(const LoadSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD;
+ }
+};
+
+/// StoreSDNode - This class is used to represent ISD::STORE nodes.
+///
+class StoreSDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[4];
+
+ // AddrMode - unindexed, pre-indexed, post-indexed.
+ ISD::MemIndexedMode AddrMode;
+
+ // IsTruncStore - True is the op does a truncation before store.
+ bool IsTruncStore;
+
+ // StoredVT - VT of the value after truncation.
+ MVT::ValueType StoredVT;
+
+ // SrcValue - Memory location for alias analysis.
+ const Value *SrcValue;
+
+ // SVOffset - Memory location offset.
+ int SVOffset;
+
+ // Alignment - Alignment of memory location in bytes.
+ unsigned Alignment;
+
+ // IsVolatile - True if the store is volatile.
+ bool IsVolatile;
+protected:
+ friend class SelectionDAG;
+ StoreSDNode(SDOperand *ChainValuePtrOff, SDVTList VTs,
+ ISD::MemIndexedMode AM, bool isTrunc, MVT::ValueType SVT,
+ const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
+ : SDNode(ISD::STORE, VTs),
+ AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT), SrcValue(SV),
+ SVOffset(O), Alignment(Align), IsVolatile(Vol) {
+ Ops[0] = ChainValuePtrOff[0]; // Chain
+ Ops[1] = ChainValuePtrOff[1]; // Value
+ Ops[2] = ChainValuePtrOff[2]; // Ptr
+ Ops[3] = ChainValuePtrOff[3]; // Off
+ InitOperands(Ops, 4);
+ assert(Align != 0 && "Stores should have non-zero aligment");
+ assert((getOffset().getOpcode() == ISD::UNDEF ||
+ AddrMode != ISD::UNINDEXED) &&
+ "Only indexed store has a non-undef offset operand");
+ }
+public:
+
+ const SDOperand getChain() const { return getOperand(0); }
+ const SDOperand getValue() const { return getOperand(1); }
+ const SDOperand getBasePtr() const { return getOperand(2); }
+ const SDOperand getOffset() const { return getOperand(3); }
+ ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
+ bool isTruncatingStore() const { return IsTruncStore; }
+ MVT::ValueType getStoredVT() const { return StoredVT; }
+ const Value *getSrcValue() const { return SrcValue; }
+ int getSrcValueOffset() const { return SVOffset; }
+ unsigned getAlignment() const { return Alignment; }
+ bool isVolatile() const { return IsVolatile; }
+
+ static bool classof(const StoreSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::STORE;
+ }
+};
+
+
+class SDNodeIterator : public forward_iterator<SDNode, ptrdiff_t> {
+ SDNode *Node;
+ unsigned Operand;
+
+ SDNodeIterator(SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
+public:
+ bool operator==(const SDNodeIterator& x) const {
+ return Operand == x.Operand;
+ }
+ bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
+
+ const SDNodeIterator &operator=(const SDNodeIterator &I) {
+ assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
+ Operand = I.Operand;
+ return *this;
+ }
+
+ pointer operator*() const {
+ return Node->getOperand(Operand).Val;
+ }
+ pointer operator->() const { return operator*(); }
+
+ SDNodeIterator& operator++() { // Preincrement
+ ++Operand;
+ return *this;
+ }
+ SDNodeIterator operator++(int) { // Postincrement
+ SDNodeIterator tmp = *this; ++*this; return tmp;
+ }
+
+ static SDNodeIterator begin(SDNode *N) { return SDNodeIterator(N, 0); }
+ static SDNodeIterator end (SDNode *N) {
+ return SDNodeIterator(N, N->getNumOperands());
+ }
+
+ unsigned getOperand() const { return Operand; }
+ const SDNode *getNode() const { return Node; }
+};
+
+template <> struct GraphTraits<SDNode*> {
+ typedef SDNode NodeType;
+ typedef SDNodeIterator ChildIteratorType;
+ static inline NodeType *getEntryNode(SDNode *N) { return N; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return SDNodeIterator::begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return SDNodeIterator::end(N);
+ }
+};
+
+template<>
+struct ilist_traits<SDNode> {
+ static SDNode *getPrev(const SDNode *N) { return N->Prev; }
+ static SDNode *getNext(const SDNode *N) { return N->Next; }
+
+ static void setPrev(SDNode *N, SDNode *Prev) { N->Prev = Prev; }
+ static void setNext(SDNode *N, SDNode *Next) { N->Next = Next; }
+
+ static SDNode *createSentinel() {
+ return new SDNode(ISD::EntryToken, SDNode::getSDVTList(MVT::Other));
+ }
+ static void destroySentinel(SDNode *N) { delete N; }
+ //static SDNode *createNode(const SDNode &V) { return new SDNode(V); }
+
+
+ void addNodeToList(SDNode *NTy) {}
+ void removeNodeFromList(SDNode *NTy) {}
+ void transferNodesFromList(iplist<SDNode, ilist_traits> &L2,
+ const ilist_iterator<SDNode> &X,
+ const ilist_iterator<SDNode> &Y) {}
+};
+
+namespace ISD {
+ /// isNON_EXTLoad - Returns true if the specified node is a non-extending
+ /// load.
+ inline bool isNON_EXTLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
+ }
+
+ /// isEXTLoad - Returns true if the specified node is a EXTLOAD.
+ ///
+ inline bool isEXTLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+ }
+
+ /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD.
+ ///
+ inline bool isSEXTLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+ }
+
+ /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD.
+ ///
+ inline bool isZEXTLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+ }
+
+ /// isUNINDEXEDLoad - Returns true if the specified node is a unindexed load.
+ ///
+ inline bool isUNINDEXEDLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+ }
+
+ /// isNON_TRUNCStore - Returns true if the specified node is a non-truncating
+ /// store.
+ inline bool isNON_TRUNCStore(const SDNode *N) {
+ return N->getOpcode() == ISD::STORE &&
+ !cast<StoreSDNode>(N)->isTruncatingStore();
+ }
+
+ /// isTRUNCStore - Returns true if the specified node is a truncating
+ /// store.
+ inline bool isTRUNCStore(const SDNode *N) {
+ return N->getOpcode() == ISD::STORE &&
+ cast<StoreSDNode>(N)->isTruncatingStore();
+ }
+}
+
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/SimpleRegisterCoalescing.h b/include/llvm/CodeGen/SimpleRegisterCoalescing.h
new file mode 100644
index 0000000..20bcb89
--- /dev/null
+++ b/include/llvm/CodeGen/SimpleRegisterCoalescing.h
@@ -0,0 +1,160 @@
+//===-- SimpleRegisterCoalescing.h - Register Coalescing --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a simple register copy coalescing phase.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SIMPLE_REGISTER_COALESCING_H
+#define LLVM_CODEGEN_SIMPLE_REGISTER_COALESCING_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/IndexedMap.h"
+
+namespace llvm {
+
+ class LiveVariables;
+ class MRegisterInfo;
+ class TargetInstrInfo;
+ class VirtRegMap;
+
+ class SimpleRegisterCoalescing : public MachineFunctionPass {
+ MachineFunction* mf_;
+ const TargetMachine* tm_;
+ const MRegisterInfo* mri_;
+ const TargetInstrInfo* tii_;
+ LiveIntervals *li_;
+ LiveVariables *lv_;
+
+ typedef IndexedMap<unsigned> Reg2RegMap;
+ Reg2RegMap r2rMap_;
+
+ BitVector allocatableRegs_;
+ DenseMap<const TargetRegisterClass*, BitVector> allocatableRCRegs_;
+
+ /// JoinedLIs - Keep track which register intervals have been coalesced
+ /// with other intervals.
+ BitVector JoinedLIs;
+
+ public:
+ static char ID; // Pass identifcation, replacement for typeid
+ SimpleRegisterCoalescing() : MachineFunctionPass((intptr_t)&ID) {};
+
+ struct CopyRec {
+ MachineInstr *MI;
+ unsigned SrcReg, DstReg;
+ };
+ CopyRec getCopyRec(MachineInstr *MI, unsigned SrcReg, unsigned DstReg) {
+ CopyRec R;
+ R.MI = MI;
+ R.SrcReg = SrcReg;
+ R.DstReg = DstReg;
+ return R;
+ }
+ struct InstrSlots {
+ enum {
+ LOAD = 0,
+ USE = 1,
+ DEF = 2,
+ STORE = 3,
+ NUM = 4
+ };
+ };
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+
+ /// runOnMachineFunction - pass entry point
+ virtual bool runOnMachineFunction(MachineFunction&);
+
+ /// print - Implement the dump method.
+ virtual void print(std::ostream &O, const Module* = 0) const;
+ void print(std::ostream *O, const Module* M = 0) const {
+ if (O) print(*O, M);
+ }
+
+ private:
+ /// joinIntervals - join compatible live intervals
+ void joinIntervals();
+
+ /// CopyCoalesceInMBB - Coalesce copies in the specified MBB, putting
+ /// copies that cannot yet be coalesced into the "TryAgain" list.
+ void CopyCoalesceInMBB(MachineBasicBlock *MBB,
+ std::vector<CopyRec> *TryAgain, bool PhysOnly = false);
+
+ /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
+ /// which are the src/dst of the copy instruction CopyMI. This returns true
+ /// if the copy was successfully coalesced away, or if it is never possible
+ /// to coalesce these this copy, due to register constraints. It returns
+ /// false if it is not currently possible to coalesce this interval, but
+ /// it may be possible if other things get coalesced.
+ bool JoinCopy(MachineInstr *CopyMI, unsigned SrcReg, unsigned DstReg,
+ bool PhysOnly = false);
+
+ /// JoinIntervals - Attempt to join these two intervals. On failure, this
+ /// returns false. Otherwise, if one of the intervals being joined is a
+ /// physreg, this method always canonicalizes DestInt to be it. The output
+ /// "SrcInt" will not have been modified, so we can use this information
+ /// below to update aliases.
+ bool JoinIntervals(LiveInterval &LHS, LiveInterval &RHS);
+
+ /// SimpleJoin - Attempt to join the specified interval into this one. The
+ /// caller of this method must guarantee that the RHS only contains a single
+ /// value number and that the RHS is not defined by a copy from this
+ /// interval. This returns false if the intervals are not joinable, or it
+ /// joins them and returns true.
+ bool SimpleJoin(LiveInterval &LHS, LiveInterval &RHS);
+
+ /// Return true if the two specified registers belong to different
+ /// register classes. The registers may be either phys or virt regs.
+ bool differingRegisterClasses(unsigned RegA, unsigned RegB) const;
+
+
+ bool AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
+ MachineInstr *CopyMI);
+
+ /// lastRegisterUse - Returns the last use of the specific register between
+ /// cycles Start and End. It also returns the use operand by reference. It
+ /// returns NULL if there are no uses.
+ MachineInstr *lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,
+ MachineOperand *&MOU);
+
+ /// findDefOperand - Returns the MachineOperand that is a def of the specific
+ /// register. It returns NULL if the def is not found.
+ MachineOperand *findDefOperand(MachineInstr *MI, unsigned Reg);
+
+ /// unsetRegisterKill - Unset IsKill property of all uses of the specific
+ /// register of the specific instruction.
+ void unsetRegisterKill(MachineInstr *MI, unsigned Reg);
+
+ /// unsetRegisterKills - Unset IsKill property of all uses of specific register
+ /// between cycles Start and End.
+ void unsetRegisterKills(unsigned Start, unsigned End, unsigned Reg);
+
+ /// hasRegisterDef - True if the instruction defines the specific register.
+ ///
+ bool hasRegisterDef(MachineInstr *MI, unsigned Reg);
+
+ /// rep - returns the representative of this register
+ unsigned rep(unsigned Reg) {
+ unsigned Rep = r2rMap_[Reg];
+ if (Rep)
+ return r2rMap_[Reg] = rep(Rep);
+ return Reg;
+ }
+
+ void printRegName(unsigned reg) const;
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
new file mode 100644
index 0000000..d2a6414
--- /dev/null
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -0,0 +1,284 @@
+//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the set of low-level target independent types which various
+// values in the code generator are. This allows the target specific behavior
+// of instructions to be described to target independent passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_VALUETYPES_H
+#define LLVM_CODEGEN_VALUETYPES_H
+
+#include <cassert>
+#include <string>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class Type;
+
+/// MVT namespace - This namespace defines the SimpleValueType enum, which
+/// contains the various low-level value types, and the ValueType typedef.
+///
+namespace MVT { // MVT = Machine Value Types
+ enum SimpleValueType {
+ // If you change this numbering, you must change the values in ValueTypes.td
+ // well!
+ Other = 0, // This is a non-standard value
+ i1 = 1, // This is a 1 bit integer value
+ i8 = 2, // This is an 8 bit integer value
+ i16 = 3, // This is a 16 bit integer value
+ i32 = 4, // This is a 32 bit integer value
+ i64 = 5, // This is a 64 bit integer value
+ i128 = 6, // This is a 128 bit integer value
+
+ f32 = 7, // This is a 32 bit floating point value
+ f64 = 8, // This is a 64 bit floating point value
+ f80 = 9, // This is a 80 bit floating point value
+ f128 = 10, // This is a 128 bit floating point value
+ Flag = 11, // This is a condition code or machine flag.
+
+ isVoid = 12, // This has no value
+
+ v8i8 = 13, // 8 x i8
+ v4i16 = 14, // 4 x i16
+ v2i32 = 15, // 2 x i32
+ v1i64 = 16, // 1 x i64
+ v16i8 = 17, // 16 x i8
+ v8i16 = 18, // 8 x i16
+ v4i32 = 19, // 4 x i32
+ v2i64 = 20, // 2 x i64
+
+ v2f32 = 21, // 2 x f32
+ v4f32 = 22, // 4 x f32
+ v2f64 = 23, // 2 x f64
+ FIRST_VECTOR_VALUETYPE = v8i8,
+ LAST_VECTOR_VALUETYPE = v2f64,
+
+ LAST_VALUETYPE = 24, // This always remains at the end of the list.
+
+ // iAny - An integer value of any bit width. This is used for intrinsics
+ // that have overloadings based on integer bit widths. This is only for
+ // tblgen's consumption!
+ iAny = 254,
+
+ // iPTR - An int value the size of the pointer of the current
+ // target. This should only be used internal to tblgen!
+ iPTR = 255
+ };
+
+ /// MVT::ValueType - This type holds low-level value types. Valid values
+ /// include any of the values in the SimpleValueType enum, or any value
+ /// returned from a function in the MVT namespace that has a ValueType
+ /// return type. Any value type equal to one of the SimpleValueType enum
+ /// values is a "simple" value type. All other value types are "extended".
+ ///
+ /// Note that simple doesn't necessary mean legal for the target machine.
+ /// All legal value types must be simple, but often there are some simple
+ /// value types that are not legal.
+ ///
+ /// @internal
+ /// Currently extended types are always vector types. Extended types are
+ /// encoded by having the first SimpleTypeBits bits encode the vector
+ /// element type (which must be a scalar type) and the remaining upper
+ /// bits encode the vector length, offset by one.
+ typedef uint32_t ValueType;
+
+ static const int SimpleTypeBits = 8;
+
+ static const uint32_t SimpleTypeMask =
+ (~uint32_t(0) << (32 - SimpleTypeBits)) >> (32 - SimpleTypeBits);
+
+ /// MVT::isExtendedVT - Test if the given ValueType is extended
+ /// (as opposed to being simple).
+ static inline bool isExtendedVT(ValueType VT) {
+ return VT > SimpleTypeMask;
+ }
+
+ /// MVT::isInteger - Return true if this is an integer, or a vector integer
+ /// type.
+ static inline bool isInteger(ValueType VT) {
+ ValueType SVT = VT & SimpleTypeMask;
+ return (SVT >= i1 && SVT <= i128) || (SVT >= v8i8 && SVT <= v2i64);
+ }
+
+ /// MVT::isFloatingPoint - Return true if this is an FP, or a vector FP type.
+ static inline bool isFloatingPoint(ValueType VT) {
+ ValueType SVT = VT & SimpleTypeMask;
+ return (SVT >= f32 && SVT <= f128) || (SVT >= v2f32 && SVT <= v2f64);
+ }
+
+ /// MVT::isVector - Return true if this is a vector value type.
+ static inline bool isVector(ValueType VT) {
+ return (VT >= FIRST_VECTOR_VALUETYPE && VT <= LAST_VECTOR_VALUETYPE) ||
+ isExtendedVT(VT);
+ }
+
+ /// MVT::getVectorElementType - Given a vector type, return the type of
+ /// each element.
+ static inline ValueType getVectorElementType(ValueType VT) {
+ switch (VT) {
+ default:
+ if (isExtendedVT(VT))
+ return VT & SimpleTypeMask;
+ assert(0 && "Invalid vector type!");
+ case v8i8 :
+ case v16i8: return i8;
+ case v4i16:
+ case v8i16: return i16;
+ case v2i32:
+ case v4i32: return i32;
+ case v1i64:
+ case v2i64: return i64;
+ case v2f32:
+ case v4f32: return f32;
+ case v2f64: return f64;
+ }
+ }
+
+ /// MVT::getVectorNumElements - Given a vector type, return the
+ /// number of elements it contains.
+ static inline unsigned getVectorNumElements(ValueType VT) {
+ switch (VT) {
+ default:
+ if (isExtendedVT(VT))
+ return ((VT & ~SimpleTypeMask) >> SimpleTypeBits) - 1;
+ assert(0 && "Invalid vector type!");
+ case v16i8: return 16;
+ case v8i8 :
+ case v8i16: return 8;
+ case v4i16:
+ case v4i32:
+ case v4f32: return 4;
+ case v2i32:
+ case v2i64:
+ case v2f32:
+ case v2f64: return 2;
+ case v1i64: return 1;
+ }
+ }
+
+ /// MVT::getSizeInBits - Return the size of the specified value type
+ /// in bits.
+ ///
+ static inline unsigned getSizeInBits(ValueType VT) {
+ switch (VT) {
+ default:
+ if (isExtendedVT(VT))
+ return getSizeInBits(getVectorElementType(VT)) *
+ getVectorNumElements(VT);
+ assert(0 && "ValueType has no known size!");
+ case MVT::i1 : return 1;
+ case MVT::i8 : return 8;
+ case MVT::i16 : return 16;
+ case MVT::f32 :
+ case MVT::i32 : return 32;
+ case MVT::f64 :
+ case MVT::i64 :
+ case MVT::v8i8:
+ case MVT::v4i16:
+ case MVT::v2i32:
+ case MVT::v1i64:
+ case MVT::v2f32: return 64;
+ case MVT::f80 : return 80;
+ case MVT::f128:
+ case MVT::i128:
+ case MVT::v16i8:
+ case MVT::v8i16:
+ case MVT::v4i32:
+ case MVT::v2i64:
+ case MVT::v4f32:
+ case MVT::v2f64: return 128;
+ }
+ }
+
+ /// MVT::getVectorType - Returns the ValueType that represents a vector
+ /// NumElements in length, where each element is of type VT.
+ ///
+ static inline ValueType getVectorType(ValueType VT, unsigned NumElements) {
+ switch (VT) {
+ default:
+ break;
+ case MVT::i8:
+ if (NumElements == 8) return MVT::v8i8;
+ if (NumElements == 16) return MVT::v16i8;
+ break;
+ case MVT::i16:
+ if (NumElements == 4) return MVT::v4i16;
+ if (NumElements == 8) return MVT::v8i16;
+ break;
+ case MVT::i32:
+ if (NumElements == 2) return MVT::v2i32;
+ if (NumElements == 4) return MVT::v4i32;
+ break;
+ case MVT::i64:
+ if (NumElements == 1) return MVT::v1i64;
+ if (NumElements == 2) return MVT::v2i64;
+ break;
+ case MVT::f32:
+ if (NumElements == 2) return MVT::v2f32;
+ if (NumElements == 4) return MVT::v4f32;
+ break;
+ case MVT::f64:
+ if (NumElements == 2) return MVT::v2f64;
+ break;
+ }
+ ValueType Result = VT | ((NumElements + 1) << SimpleTypeBits);
+ assert(getVectorElementType(Result) == VT &&
+ "Bad vector element type!");
+ assert(getVectorNumElements(Result) == NumElements &&
+ "Bad vector length!");
+ return Result;
+ }
+
+ /// MVT::getIntVectorWithNumElements - Return any integer vector type that has
+ /// the specified number of elements.
+ static inline ValueType getIntVectorWithNumElements(unsigned NumElts) {
+ switch (NumElts) {
+ default: return getVectorType(i8, NumElts);
+ case 1: return v1i64;
+ case 2: return v2i32;
+ case 4: return v4i16;
+ case 8: return v8i8;
+ case 16: return v16i8;
+ }
+ }
+
+
+ /// MVT::getIntVTBitMask - Return an integer with 1's every place there are
+ /// bits in the specified integer value type.
+ static inline uint64_t getIntVTBitMask(ValueType VT) {
+ assert(isInteger(VT) && !isVector(VT) && "Only applies to int scalars!");
+ return ~uint64_t(0UL) >> (64-getSizeInBits(VT));
+ }
+ /// MVT::getIntVTSignBit - Return an integer with a 1 in the position of the
+ /// sign bit for the specified integer value type.
+ static inline uint64_t getIntVTSignBit(ValueType VT) {
+ assert(isInteger(VT) && !isVector(VT) && "Only applies to int scalars!");
+ return uint64_t(1UL) << (getSizeInBits(VT)-1);
+ }
+
+ /// MVT::getValueTypeString - This function returns value type as a string,
+ /// e.g. "i32".
+ std::string getValueTypeString(ValueType VT);
+
+ /// MVT::getTypeForValueType - This method returns an LLVM type corresponding
+ /// to the specified ValueType. For integer types, this returns an unsigned
+ /// type. Note that this will abort for types that cannot be represented.
+ const Type *getTypeForValueType(ValueType VT);
+
+ /// MVT::getValueType - Return the value type corresponding to the specified
+ /// type. This returns all pointers as MVT::iPTR. If HandleUnknown is true,
+ /// unknown types are returned as Other, otherwise they are invalid.
+ ValueType getValueType(const Type *Ty, bool HandleUnknown = false);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td
new file mode 100644
index 0000000..557a02b
--- /dev/null
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -0,0 +1,52 @@
+//===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Value types - These values correspond to the register types defined in the
+// ValueTypes.h file. If you update anything here, you must update it there as
+// well!
+//
+//===----------------------------------------------------------------------===//
+
+class ValueType<int size, int value> {
+ string Namespace = "MVT";
+ int Size = size;
+ int Value = value;
+}
+
+def OtherVT: ValueType<0 , 0>; // "Other" value
+def i1 : ValueType<1 , 1>; // One bit boolean value
+def i8 : ValueType<8 , 2>; // 8-bit integer value
+def i16 : ValueType<16 , 3>; // 16-bit integer value
+def i32 : ValueType<32 , 4>; // 32-bit integer value
+def i64 : ValueType<64 , 5>; // 64-bit integer value
+def i128 : ValueType<128, 6>; // 128-bit integer value
+def f32 : ValueType<32 , 7>; // 32-bit floating point value
+def f64 : ValueType<64 , 8>; // 64-bit floating point value
+def f80 : ValueType<80 , 9>; // 80-bit floating point value
+def f128 : ValueType<128, 10>; // 128-bit floating point value
+def FlagVT : ValueType<0 , 11>; // Condition code or machine flag
+def isVoid : ValueType<0 , 12>; // Produces no value
+def v8i8 : ValueType<64 , 13>; // 8 x i8 vector value
+def v4i16 : ValueType<64 , 14>; // 4 x i16 vector value
+def v2i32 : ValueType<64 , 15>; // 2 x i32 vector value
+def v1i64 : ValueType<64 , 16>; // 1 x i64 vector value
+
+def v16i8 : ValueType<128, 17>; // 16 x i8 vector value
+def v8i16 : ValueType<128, 18>; // 8 x i16 vector value
+def v4i32 : ValueType<128, 19>; // 4 x i32 vector value
+def v2i64 : ValueType<128, 20>; // 2 x i64 vector value
+def v2f32 : ValueType<64, 21>; // 2 x f32 vector value
+def v4f32 : ValueType<128, 22>; // 4 x f32 vector value
+def v2f64 : ValueType<128, 23>; // 2 x f64 vector value
+
+// Pseudo valuetype to represent "integer of any bit width"
+def iAny : ValueType<0 , 254>; // integer value of any bit width
+
+// Pseudo valuetype mapped to the current pointer size.
+def iPTR : ValueType<0 , 255>;