summaryrefslogtreecommitdiffstats
path: root/include/llvm/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h142
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h9
-rw-r--r--include/llvm/CodeGen/FastISel.h61
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h154
-rw-r--r--include/llvm/CodeGen/GCMetadata.h96
-rw-r--r--include/llvm/CodeGen/GCMetadataPrinter.h28
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h7
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h1
-rw-r--r--include/llvm/CodeGen/LiveInterval.h101
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h17
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h21
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h12
-rw-r--r--include/llvm/CodeGen/MachineFunctionPass.h9
-rw-r--r--include/llvm/CodeGen/MachineInstr.h30
-rw-r--r--include/llvm/CodeGen/MachineJumpTableInfo.h2
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h4
-rw-r--r--include/llvm/CodeGen/MachineOperand.h16
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h15
-rw-r--r--include/llvm/CodeGen/Passes.h15
-rw-r--r--include/llvm/CodeGen/PostRAHazardRecognizer.h94
-rw-r--r--include/llvm/CodeGen/RegisterCoalescer.h90
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h11
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h34
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h39
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h15
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h133
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h61
27 files changed, 768 insertions, 449 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 243ddbb..7ca6c62 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -64,7 +64,7 @@ namespace llvm {
/// Target machine description.
///
TargetMachine &TM;
-
+
/// Target Asm Printer information.
///
const MCAsmInfo *MAI;
@@ -73,13 +73,13 @@ namespace llvm {
/// streaming. This owns all of the global MC-related objects for the
/// generated translation unit.
MCContext &OutContext;
-
+
/// OutStreamer - This is the MCStreamer object for the file we are
/// generating. This contains the transient state for the current
/// translation unit that we are generating (such as the current section
/// etc).
MCStreamer &OutStreamer;
-
+
/// The current machine function.
const MachineFunction *MF;
@@ -94,30 +94,30 @@ namespace llvm {
/// beginning of each call to runOnMachineFunction().
///
MCSymbol *CurrentFnSym;
-
+
private:
// GCMetadataPrinters - The garbage collection metadata printer table.
void *GCMetadataPrinters; // Really a DenseMap.
-
+
/// VerboseAsm - Emit comments in assembly output if this is true.
///
bool VerboseAsm;
static char ID;
-
+
/// If VerboseAsm is set, a pointer to the loop info for this
/// function.
MachineLoopInfo *LI;
/// DD - If the target supports dwarf debug info, this pointer is non-null.
DwarfDebug *DD;
-
+
/// DE - If the target supports dwarf exception info, this pointer is
/// non-null.
DwarfException *DE;
-
+
protected:
explicit AsmPrinter(TargetMachine &TM, MCStreamer &Streamer);
-
+
public:
virtual ~AsmPrinter();
@@ -128,7 +128,7 @@ namespace llvm {
/// getFunctionNumber - Return a unique ID for the current function.
///
unsigned getFunctionNumber() const;
-
+
/// getObjFileLowering - Return information about object file lowering.
const TargetLoweringObjectFile &getObjFileLowering() const;
@@ -137,16 +137,16 @@ namespace llvm {
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *getCurrentSection() const;
-
-
+
+
//===------------------------------------------------------------------===//
// MachineFunctionPass Implementation.
//===------------------------------------------------------------------===//
-
+
/// getAnalysisUsage - Record analysis usage.
- ///
+ ///
void getAnalysisUsage(AnalysisUsage &AU) const;
-
+
/// 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.
@@ -155,7 +155,7 @@ namespace llvm {
/// doFinalization - Shut down the asmprinter. If you override this in your
/// pass, you must make sure to call it explicitly.
bool doFinalization(Module &M);
-
+
/// runOnMachineFunction - Emit the specified function out to the
/// OutStreamer.
virtual bool runOnMachineFunction(MachineFunction &MF) {
@@ -163,20 +163,20 @@ namespace llvm {
EmitFunctionHeader();
EmitFunctionBody();
return false;
- }
-
+ }
+
//===------------------------------------------------------------------===//
// Coarse grained IR lowering routines.
//===------------------------------------------------------------------===//
-
+
/// SetupMachineFunction - This should be called when a new MachineFunction
/// is being processed from runOnMachineFunction.
void SetupMachineFunction(MachineFunction &MF);
-
+
/// EmitFunctionHeader - This method emits the header for the current
/// function.
void EmitFunctionHeader();
-
+
/// EmitFunctionBody - This method emits the body and trailer for a
/// function.
void EmitFunctionBody();
@@ -187,15 +187,15 @@ namespace llvm {
/// the code generator.
///
virtual void EmitConstantPool();
-
- /// EmitJumpTableInfo - Print assembly representations of the jump tables
- /// used by the current function to the current output stream.
+
+ /// EmitJumpTableInfo - Print assembly representations of the jump tables
+ /// used by the current function to the current output stream.
///
void EmitJumpTableInfo();
-
+
/// EmitGlobalVariable - Emit the specified global variable to the .s file.
virtual void EmitGlobalVariable(const GlobalVariable *GV);
-
+
/// 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.
@@ -208,54 +208,54 @@ namespace llvm {
/// if required for correctness.
///
void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const;
-
+
/// EmitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing
/// it if appropriate.
void EmitBasicBlockStart(const MachineBasicBlock *MBB) const;
-
+
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
void EmitGlobalConstant(const Constant *CV, unsigned AddrSpace = 0);
-
-
+
+
//===------------------------------------------------------------------===//
// Overridable Hooks
//===------------------------------------------------------------------===//
-
+
// Targets can, or in the case of EmitInstruction, must implement these to
// customize output.
-
+
/// EmitStartOfAsmFile - This virtual method can be overridden by targets
/// that want to emit something at the start of their file.
virtual void EmitStartOfAsmFile(Module &) {}
-
+
/// EmitEndOfAsmFile - This virtual method can be overridden by targets that
/// want to emit something at the end of their file.
virtual void EmitEndOfAsmFile(Module &) {}
-
+
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
/// the first basic block in the function.
virtual void EmitFunctionBodyStart() {}
-
+
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
/// the last basic block in the function.
virtual void EmitFunctionBodyEnd() {}
-
+
/// EmitInstruction - Targets should implement this to emit instructions.
virtual void EmitInstruction(const MachineInstr *) {
assert(0 && "EmitInstruction not implemented");
}
-
+
virtual void EmitFunctionEntryLabel();
-
+
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
-
+
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
virtual bool
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
-
+
//===------------------------------------------------------------------===//
// Symbol Lowering Routines.
//===------------------------------------------------------------------===//
@@ -264,23 +264,23 @@ namespace llvm {
/// GetTempSymbol - Return the MCSymbol corresponding to the assembler
/// temporary label with the specified stem and unique ID.
MCSymbol *GetTempSymbol(StringRef Name, unsigned ID) const;
-
+
/// GetTempSymbol - Return an assembler temporary label with the specified
/// stem.
MCSymbol *GetTempSymbol(StringRef Name) const;
-
-
+
+
/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
/// global value name as its base, with the specified suffix, and where the
/// symbol is forced to have private linkage if ForcePrivate is true.
MCSymbol *GetSymbolWithGlobalValueBase(const GlobalValue *GV,
StringRef Suffix,
bool ForcePrivate = true) const;
-
+
/// GetExternalSymbolSymbol - Return the MCSymbol for the specified
/// ExternalSymbol.
MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const;
-
+
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
MCSymbol *GetCPISymbol(unsigned CPID) const;
@@ -302,42 +302,42 @@ namespace llvm {
public:
/// printOffset - This is just convenient handler for printing offsets.
void printOffset(int64_t Offset, raw_ostream &OS) 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;
-
+
/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size
/// in bytes of the directive is specified by Size and Hi/Lo specify the
/// labels. This implicitly uses .set if it is available.
void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) const;
-
- /// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo"
+
+ /// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo"
/// where the size in bytes of the directive is specified by Size and Hi/Lo
/// specify the labels. This implicitly uses .set if it is available.
void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
const MCSymbol *Lo, unsigned Size) const;
-
+
//===------------------------------------------------------------------===//
// Dwarf Emission Helper Routines
//===------------------------------------------------------------------===//
-
+
/// EmitSLEB128 - emit the specified signed leb128 value.
void EmitSLEB128(int Value, const char *Desc = 0) const;
-
+
/// EmitULEB128 - emit the specified unsigned leb128 value.
void EmitULEB128(unsigned Value, const char *Desc = 0,
unsigned PadTo = 0) const;
-
+
/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
void EmitCFAByte(unsigned Val) const;
@@ -346,15 +346,15 @@ namespace llvm {
/// describing the encoding. Desc is a string saying what the encoding is
/// specifying (e.g. "LSDA").
void EmitEncodingByte(unsigned Val, const char *Desc = 0) const;
-
+
/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
unsigned GetSizeOfEncodedValue(unsigned Encoding) const;
-
+
/// EmitReference - Emit a reference to a label with a specified encoding.
///
void EmitReference(const MCSymbol *Sym, unsigned Encoding) const;
void EmitReference(const GlobalValue *GV, unsigned Encoding) const;
-
+
/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of
/// its section. This can be done with a special directive if the target
/// supports it (e.g. cygwin) or by emitting it as an offset from a label at
@@ -372,20 +372,20 @@ namespace llvm {
//===------------------------------------------------------------------===//
// Dwarf Lowering Routines
//===------------------------------------------------------------------===//
-
+
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
- void EmitFrameMoves(const std::vector<MachineMove> &Moves,
+ void EmitFrameMoves(const std::vector<MachineMove> &Moves,
MCSymbol *BaseLabel, bool isEH) const;
-
-
+
+
//===------------------------------------------------------------------===//
// Inline Asm Support
//===------------------------------------------------------------------===//
public:
// These are hooks that targets can override to implement inline asm
// support. These should probably be moved out of AsmPrinter someday.
-
+
/// 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
@@ -394,7 +394,7 @@ namespace llvm {
/// for their own strange codes.
virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
const char *Code) const;
-
+
/// 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
@@ -402,16 +402,16 @@ namespace llvm {
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &OS);
-
+
/// 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,
+ unsigned AsmVariant,
const char *ExtraCode,
raw_ostream &OS);
-
+
private:
/// Private state for PrintSpecial()
// Assign a unique ID to this machine instruction.
@@ -422,7 +422,7 @@ namespace llvm {
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void EmitInlineAsm(StringRef Str, unsigned LocCookie) const;
-
+
/// EmitInlineAsm - This method formats and emits the specified machine
/// instruction that is an inline asm.
void EmitInlineAsm(const MachineInstr *MI) const;
@@ -430,13 +430,13 @@ namespace llvm {
//===------------------------------------------------------------------===//
// Internal Implementation Details
//===------------------------------------------------------------------===//
-
+
/// EmitVisibility - This emits visibility information about symbol, if
/// this is suported by the target.
void EmitVisibility(MCSymbol *Sym, unsigned Visibility) const;
-
+
void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const;
-
+
void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
const MachineBasicBlock *MBB,
unsigned uid) const;
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index 45a2757..7911907 100644
--- a/include/llvm/CodeGen/CallingConvLower.h
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -17,14 +17,13 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/Target/TargetCallingConv.h"
#include "llvm/CallingConv.h"
namespace llvm {
class TargetRegisterInfo;
class TargetMachine;
class CCState;
- class SDNode;
/// CCValAssign - Represent assignment of one arg/retval to a location.
class CCValAssign {
@@ -35,6 +34,9 @@ public:
ZExt, // The value is zero extended in the location.
AExt, // The value is extended with undefined upper bits.
BCvt, // The value is bit-converted in the location.
+ VExt, // The value is vector-widened in the location.
+ // FIXME: Not implemented yet. Code that uses AExt to mean
+ // vector-widen should be fixed to use VExt instead.
Indirect // The location contains pointer to the value.
// TODO: a subset of the value is in the location.
};
@@ -186,8 +188,7 @@ public:
/// CheckReturn - Analyze the return values of a function, returning
/// true if the return can be performed without sret-demotion, and
/// false otherwise.
- bool CheckReturn(const SmallVectorImpl<EVT> &OutTys,
- const SmallVectorImpl<ISD::ArgFlagsTy> &ArgsFlags,
+ bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
CCAssignFn Fn);
/// AnalyzeCallOperands - Analyze the outgoing arguments to a call,
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 005c7bc..7f3a7c7 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -19,11 +19,13 @@
#include "llvm/ADT/SmallSet.h"
#endif
#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
namespace llvm {
class AllocaInst;
class ConstantFP;
+class FunctionLoweringInfo;
class Instruction;
class MachineBasicBlock;
class MachineConstantPool;
@@ -36,22 +38,15 @@ class TargetInstrInfo;
class TargetLowering;
class TargetMachine;
class TargetRegisterClass;
+class TargetRegisterInfo;
/// FastISel - This is a fast-path instruction selection class that
/// generates poor code and doesn't support illegal types or non-trivial
/// lowering, but runs quickly.
class FastISel {
protected:
- MachineBasicBlock *MBB;
DenseMap<const Value *, unsigned> LocalValueMap;
- DenseMap<const Value *, unsigned> &ValueMap;
- DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap;
- DenseMap<const AllocaInst *, int> &StaticAllocaMap;
- std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate;
-#ifndef NDEBUG
- SmallSet<const Instruction *, 8> &CatchInfoLost;
-#endif
- MachineFunction &MF;
+ FunctionLoweringInfo &FuncInfo;
MachineRegisterInfo &MRI;
MachineFrameInfo &MFI;
MachineConstantPool &MCP;
@@ -60,23 +55,22 @@ protected:
const TargetData &TD;
const TargetInstrInfo &TII;
const TargetLowering &TLI;
- bool IsBottomUp;
+ const TargetRegisterInfo &TRI;
+ MachineInstr *LastLocalValue;
public:
+ /// getLastLocalValue - Return the position of the last instruction
+ /// emitted for materializing constants for use in the current block.
+ MachineInstr *getLastLocalValue() { return LastLocalValue; }
+
+ /// setLastLocalValue - Update the position of the last instruction
+ /// emitted for materializing constants for use in the current block.
+ void setLastLocalValue(MachineInstr *I) { LastLocalValue = I; }
+
/// startNewBlock - Set the current block to which generated machine
/// instructions will be appended, and clear the local CSE map.
///
- void startNewBlock(MachineBasicBlock *mbb) {
- setCurrentBlock(mbb);
- LocalValueMap.clear();
- }
-
- /// setCurrentBlock - Set the current block to which generated machine
- /// instructions will be appended.
- ///
- void setCurrentBlock(MachineBasicBlock *mbb) {
- MBB = mbb;
- }
+ void startNewBlock();
/// getCurDebugLoc() - Return current debug location information.
DebugLoc getCurDebugLoc() const { return DL; }
@@ -108,18 +102,21 @@ public:
/// index value.
std::pair<unsigned, bool> getRegForGEPIndex(const Value *V);
+ /// recomputeInsertPt - Reset InsertPt to prepare for insterting instructions
+ /// into the current block.
+ void recomputeInsertPt();
+
+ /// enterLocalValueArea - Prepare InsertPt to begin inserting instructions
+ /// into the local value area and return the old insert position.
+ MachineBasicBlock::iterator enterLocalValueArea();
+
+ /// leaveLocalValueArea - Reset InsertPt to the given old insert position
+ void leaveLocalValueArea(MachineBasicBlock::iterator OldInsertPt);
+
virtual ~FastISel();
protected:
- FastISel(MachineFunction &mf,
- DenseMap<const Value *, unsigned> &vm,
- DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
- DenseMap<const AllocaInst *, int> &am,
- std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate
-#ifndef NDEBUG
- , SmallSet<const Instruction *, 8> &cil
-#endif
- );
+ explicit FastISel(FunctionLoweringInfo &funcInfo);
/// TargetSelectInstruction - This method is called by target-independent
/// code when the normal FastISel process fails to select an instruction.
@@ -286,7 +283,7 @@ protected:
/// FastEmitBranch - Emit an unconditional branch to the given block,
/// unless it is the immediate (fall-through) successor, and update
/// the CFG.
- void FastEmitBranch(MachineBasicBlock *MBB);
+ void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL);
unsigned UpdateValueMap(const Value* I, unsigned Reg);
@@ -305,6 +302,8 @@ protected:
}
private:
+ bool SelectLoad(const User *I);
+
bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
bool SelectFNeg(const User *I);
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
new file mode 100644
index 0000000..c49d1ed
--- /dev/null
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -0,0 +1,154 @@
+//===-- FunctionLoweringInfo.h - Lower functions from LLVM IR to CodeGen --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements routines for translating functions from LLVM IR into
+// Machine IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
+#define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
+
+#include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#ifndef NDEBUG
+#include "llvm/ADT/SmallSet.h"
+#endif
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Support/CallSite.h"
+#include <vector>
+
+namespace llvm {
+
+class AllocaInst;
+class BasicBlock;
+class CallInst;
+class Function;
+class GlobalVariable;
+class Instruction;
+class MachineInstr;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineModuleInfo;
+class MachineRegisterInfo;
+class TargetLowering;
+class Value;
+
+//===--------------------------------------------------------------------===//
+/// FunctionLoweringInfo - This contains information that is global to a
+/// function that is used when lowering a region of the function.
+///
+class FunctionLoweringInfo {
+public:
+ const TargetLowering &TLI;
+ const Function *Fn;
+ MachineFunction *MF;
+ MachineRegisterInfo *RegInfo;
+
+ /// CanLowerReturn - true iff the function's return value can be lowered to
+ /// registers.
+ bool CanLowerReturn;
+
+ /// DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg
+ /// allocated to hold a pointer to the hidden sret parameter.
+ unsigned DemoteRegister;
+
+ /// MBBMap - A mapping from LLVM basic blocks to their machine code entry.
+ DenseMap<const BasicBlock*, MachineBasicBlock *> MBBMap;
+
+ /// ValueMap - Since we emit code for the function a basic block at a time,
+ /// we must remember which virtual registers hold the values for
+ /// cross-basic-block values.
+ DenseMap<const Value*, unsigned> ValueMap;
+
+ /// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in
+ /// the entry block. This allows the allocas to be efficiently referenced
+ /// anywhere in the function.
+ DenseMap<const AllocaInst*, int> StaticAllocaMap;
+
+ /// ArgDbgValues - A list of DBG_VALUE instructions created during isel for
+ /// function arguments that are inserted after scheduling is completed.
+ SmallVector<MachineInstr*, 8> ArgDbgValues;
+
+ /// RegFixups - Registers which need to be replaced after isel is done.
+ DenseMap<unsigned, unsigned> RegFixups;
+
+ /// MBB - The current block.
+ MachineBasicBlock *MBB;
+
+ /// MBB - The current insert position inside the current block.
+ MachineBasicBlock::iterator InsertPt;
+
+#ifndef NDEBUG
+ SmallSet<const Instruction *, 8> CatchInfoLost;
+ SmallSet<const Instruction *, 8> CatchInfoFound;
+#endif
+
+ struct LiveOutInfo {
+ unsigned NumSignBits;
+ APInt KnownOne, KnownZero;
+ LiveOutInfo() : NumSignBits(0), KnownOne(1, 0), KnownZero(1, 0) {}
+ };
+
+ /// LiveOutRegInfo - Information about live out vregs, indexed by their
+ /// register number offset by 'FirstVirtualRegister'.
+ std::vector<LiveOutInfo> LiveOutRegInfo;
+
+ /// PHINodesToUpdate - A list of phi instructions whose operand list will
+ /// be updated after processing the current basic block.
+ /// TODO: This isn't per-function state, it's per-basic-block state. But
+ /// there's no other convenient place for it to live right now.
+ std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
+
+ explicit FunctionLoweringInfo(const TargetLowering &TLI);
+
+ /// set - Initialize this FunctionLoweringInfo with the given Function
+ /// and its associated MachineFunction.
+ ///
+ void set(const Function &Fn, MachineFunction &MF);
+
+ /// clear - Clear out all the function-specific state. This returns this
+ /// FunctionLoweringInfo to an empty state, ready to be used for a
+ /// different function.
+ void clear();
+
+ /// isExportedInst - Return true if the specified value is an instruction
+ /// exported from its block.
+ bool isExportedInst(const Value *V) {
+ return ValueMap.count(V);
+ }
+
+ unsigned CreateReg(EVT VT);
+
+ unsigned CreateRegs(const Type *Ty);
+
+ unsigned InitializeRegForValue(const Value *V) {
+ unsigned &R = ValueMap[V];
+ assert(R == 0 && "Already initialized this value register!");
+ return R = CreateRegs(V->getType());
+ }
+};
+
+/// AddCatchInfo - Extract the personality and type infos from an eh.selector
+/// call, and add them to the specified machine basic block.
+void AddCatchInfo(const CallInst &I,
+ MachineModuleInfo *MMI, MachineBasicBlock *MBB);
+
+/// CopyCatchInfo - Copy catch information from DestBB to SrcBB.
+void CopyCatchInfo(const BasicBlock *SrcBB, const BasicBlock *DestBB,
+ MachineModuleInfo *MMI, FunctionLoweringInfo &FLI);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
index 6de69cd..b401068 100644
--- a/include/llvm/CodeGen/GCMetadata.h
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -1,4 +1,4 @@
-//===-- GCMetadata.h - Garbage collector metadata -------------------------===//
+//===-- GCMetadata.h - Garbage collector metadata ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,7 +14,7 @@
//
// The GCFunctionInfo class logs the data necessary to build a type accurate
// stack map. The code generator outputs:
-//
+//
// - Safe points as specified by the GCStrategy's NeededSafePoints.
// - Stack offsets for GC roots, as specified by calls to llvm.gcroot
//
@@ -42,10 +42,10 @@ namespace llvm {
class GCStrategy;
class Constant;
class MCSymbol;
-
+
namespace GC {
/// PointKind - The type of a collector-safe point.
- ///
+ ///
enum PointKind {
Loop, //< Instr is a loop (backwards branch).
Return, //< Instr is a return instruction.
@@ -53,138 +53,138 @@ namespace llvm {
PostCall //< Instr is the return address of a call.
};
}
-
+
/// GCPoint - Metadata for a collector-safe point in machine code.
- ///
+ ///
struct GCPoint {
GC::PointKind Kind; //< The kind of the safe point.
MCSymbol *Label; //< A label.
-
+
GCPoint(GC::PointKind K, MCSymbol *L) : Kind(K), Label(L) {}
};
-
+
/// GCRoot - Metadata for a pointer to an object managed by the garbage
/// collector.
struct GCRoot {
int Num; //< Usually a frame index.
int StackOffset; //< Offset from the stack pointer.
const Constant *Metadata;//< Metadata straight from the call to llvm.gcroot.
-
+
GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
};
-
-
+
+
/// GCFunctionInfo - Garbage collection metadata for a single function.
- ///
+ ///
class GCFunctionInfo {
public:
typedef std::vector<GCPoint>::iterator iterator;
typedef std::vector<GCRoot>::iterator roots_iterator;
typedef std::vector<GCRoot>::const_iterator live_iterator;
-
+
private:
const Function &F;
GCStrategy &S;
uint64_t FrameSize;
std::vector<GCRoot> Roots;
std::vector<GCPoint> SafePoints;
-
+
// FIXME: Liveness. A 2D BitVector, perhaps?
- //
+ //
// BitVector Liveness;
- //
+ //
// bool islive(int point, int root) =
// Liveness[point * SafePoints.size() + root]
- //
+ //
// The bit vector is the more compact representation where >3.2% of roots
// are live per safe point (1.5% on 64-bit hosts).
-
+
public:
GCFunctionInfo(const Function &F, GCStrategy &S);
~GCFunctionInfo();
-
+
/// getFunction - Return the function to which this metadata applies.
- ///
+ ///
const Function &getFunction() const { return F; }
-
+
/// getStrategy - Return the GC strategy for the function.
- ///
+ ///
GCStrategy &getStrategy() { return S; }
-
+
/// addStackRoot - Registers a root that lives on the stack. Num is the
/// stack object ID for the alloca (if the code generator is
// using MachineFrameInfo).
void addStackRoot(int Num, const Constant *Metadata) {
Roots.push_back(GCRoot(Num, Metadata));
}
-
+
/// addSafePoint - Notes the existence of a safe point. Num is the ID of the
- /// label just prior to the safe point (if the code generator is using
+ /// label just prior to the safe point (if the code generator is using
/// MachineModuleInfo).
void addSafePoint(GC::PointKind Kind, MCSymbol *Label) {
SafePoints.push_back(GCPoint(Kind, Label));
}
-
+
/// getFrameSize/setFrameSize - Records the function's frame size.
- ///
+ ///
uint64_t getFrameSize() const { return FrameSize; }
void setFrameSize(uint64_t S) { FrameSize = S; }
-
+
/// begin/end - Iterators for safe points.
- ///
+ ///
iterator begin() { return SafePoints.begin(); }
iterator end() { return SafePoints.end(); }
size_t size() const { return SafePoints.size(); }
-
+
/// roots_begin/roots_end - Iterators for all roots in the function.
- ///
+ ///
roots_iterator roots_begin() { return Roots.begin(); }
roots_iterator roots_end () { return Roots.end(); }
size_t roots_size() const { return Roots.size(); }
-
+
/// live_begin/live_end - Iterators for live roots at a given safe point.
- ///
+ ///
live_iterator live_begin(const iterator &p) { return roots_begin(); }
live_iterator live_end (const iterator &p) { return roots_end(); }
size_t live_size(const iterator &p) const { return roots_size(); }
};
-
-
+
+
/// GCModuleInfo - Garbage collection metadata for a whole module.
- ///
+ ///
class GCModuleInfo : public ImmutablePass {
typedef StringMap<GCStrategy*> strategy_map_type;
typedef std::vector<GCStrategy*> list_type;
typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type;
-
+
strategy_map_type StrategyMap;
list_type StrategyList;
finfo_map_type FInfoMap;
-
+
GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name);
-
+
public:
typedef list_type::const_iterator iterator;
-
+
static char ID;
-
+
GCModuleInfo();
~GCModuleInfo();
-
+
/// clear - Resets the pass. The metadata deleter pass calls this.
- ///
+ ///
void clear();
-
+
/// begin/end - Iterators for used strategies.
- ///
+ ///
iterator begin() const { return StrategyList.begin(); }
iterator end() const { return StrategyList.end(); }
-
+
/// get - Look up function metadata.
- ///
+ ///
GCFunctionInfo &getFunctionInfo(const Function &F);
};
-
+
}
#endif
diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h
index 3703545..17a2653 100644
--- a/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -25,49 +25,49 @@
#include "llvm/Support/Registry.h"
namespace llvm {
-
+
class GCMetadataPrinter;
-
+
/// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
/// defaults from Registry.
typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
-
+
/// GCMetadataPrinter - Emits GC metadata as assembly code.
- ///
+ ///
class GCMetadataPrinter {
public:
typedef GCStrategy::list_type list_type;
typedef GCStrategy::iterator iterator;
-
+
private:
GCStrategy *S;
-
+
friend class AsmPrinter;
-
+
protected:
// May only be subclassed.
GCMetadataPrinter();
-
+
// Do not implement.
GCMetadataPrinter(const GCMetadataPrinter &);
GCMetadataPrinter &operator=(const GCMetadataPrinter &);
-
+
public:
GCStrategy &getStrategy() { return *S; }
const Module &getModule() const { return S->getModule(); }
-
+
/// begin/end - Iterate over the collected function metadata.
iterator begin() { return S->begin(); }
iterator end() { return S->end(); }
-
+
/// beginAssembly/finishAssembly - Emit module metadata as assembly code.
virtual void beginAssembly(AsmPrinter &AP);
-
+
virtual void finishAssembly(AsmPrinter &AP);
-
+
virtual ~GCMetadataPrinter();
};
-
+
}
#endif
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index a5e9dd5..69de598 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -130,7 +130,7 @@ namespace ISD {
/// 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.
+ /// node returns the result of the intrinsic.
INTRINSIC_WO_CHAIN,
/// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
@@ -508,8 +508,9 @@ namespace ISD {
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 - VAARG has four operands: an input chain, a pointer, a SRCVALUE,
+ // and the alignment. 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,
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index b4c2f2f..cd8293d 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -33,7 +33,6 @@ namespace {
(void) llvm::createDeadMachineInstructionElimPass();
- (void) llvm::createLocalRegisterAllocator();
(void) llvm::createFastRegisterAllocator();
(void) llvm::createLinearScanRegisterAllocator();
(void) llvm::createPBQPRegisterAllocator();
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 637f52b..8d80efb 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -53,7 +53,7 @@ namespace llvm {
class VNInfo {
private:
enum {
- HAS_PHI_KILL = 1,
+ HAS_PHI_KILL = 1,
REDEF_BY_EC = 1 << 1,
IS_PHI_DEF = 1 << 2,
IS_UNUSED = 1 << 3,
@@ -67,22 +67,14 @@ namespace llvm {
} cr;
public:
- typedef SpecificBumpPtrAllocator<VNInfo> Allocator;
- typedef SmallVector<SlotIndex, 4> KillSet;
+ typedef BumpPtrAllocator Allocator;
/// The ID number of this value.
unsigned id;
-
+
/// The index of the defining instruction (if isDefAccurate() returns true).
SlotIndex def;
- KillSet kills;
-
- /*
- VNInfo(LiveIntervals &li_)
- : defflags(IS_UNUSED), id(~1U) { cr.copy = 0; }
- */
-
/// VNInfo constructor.
/// d is presumed to point to the actual defining instr. If it doesn't
/// setIsDefAccurate(false) should be called after construction.
@@ -91,7 +83,7 @@ namespace llvm {
/// VNInfo construtor, copies values from orig, except for the value number.
VNInfo(unsigned i, const VNInfo &orig)
- : flags(orig.flags), cr(orig.cr), id(i), def(orig.def), kills(orig.kills)
+ : flags(orig.flags), cr(orig.cr), id(i), def(orig.def)
{ }
/// Copy from the parameter into this VNInfo.
@@ -99,7 +91,6 @@ namespace llvm {
flags = src.flags;
cr = src.cr;
def = src.def;
- kills = src.kills;
}
/// Used for copying value number info.
@@ -114,7 +105,7 @@ namespace llvm {
/// This method should not be called on stack intervals as it may lead to
/// undefined behavior.
void setCopy(MachineInstr *c) { cr.copy = c; }
-
+
/// For a stack interval, returns the reg which this stack interval was
/// defined from.
/// For a register interval the behaviour of this method is undefined.
@@ -144,7 +135,7 @@ namespace llvm {
else
flags &= ~REDEF_BY_EC;
}
-
+
/// Returns true if this value is defined by a PHI instruction (or was,
/// PHI instrucions may have been eliminated).
bool isPHIDef() const { return flags & IS_PHI_DEF; }
@@ -172,49 +163,9 @@ namespace llvm {
void setIsDefAccurate(bool defAccurate) {
if (defAccurate)
flags |= IS_DEF_ACCURATE;
- else
+ else
flags &= ~IS_DEF_ACCURATE;
}
-
- /// Returns true if the given index is a kill of this value.
- bool isKill(SlotIndex k) const {
- KillSet::const_iterator
- i = std::lower_bound(kills.begin(), kills.end(), k);
- return (i != kills.end() && *i == k);
- }
-
- /// addKill - Add a kill instruction index to the specified value
- /// number.
- void addKill(SlotIndex k) {
- if (kills.empty()) {
- kills.push_back(k);
- } else {
- KillSet::iterator
- i = std::lower_bound(kills.begin(), kills.end(), k);
- kills.insert(i, k);
- }
- }
-
- /// Remove the specified kill index from this value's kills list.
- /// Returns true if the value was present, otherwise returns false.
- bool removeKill(SlotIndex k) {
- KillSet::iterator i = std::lower_bound(kills.begin(), kills.end(), k);
- if (i != kills.end() && *i == k) {
- kills.erase(i);
- return true;
- }
- return false;
- }
-
- /// Remove all kills in the range [s, e).
- void removeKills(SlotIndex s, SlotIndex e) {
- KillSet::iterator
- si = std::lower_bound(kills.begin(), kills.end(), s),
- se = std::upper_bound(kills.begin(), kills.end(), e);
-
- kills.erase(si, se);
- }
-
};
/// LiveRange structure - This represents a simple register range in the
@@ -258,6 +209,8 @@ namespace llvm {
LiveRange(); // DO NOT IMPLEMENT
};
+ template <> struct isPodLike<LiveRange> { static const bool value = true; };
+
raw_ostream& operator<<(raw_ostream& os, const LiveRange &LR);
@@ -366,8 +319,8 @@ namespace llvm {
/// the instruction that defines the value number.
VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI,
bool isDefAccurate, VNInfo::Allocator &VNInfoAllocator) {
- VNInfo *VNI = VNInfoAllocator.Allocate();
- new (VNI) VNInfo((unsigned)valnos.size(), def, CopyMI);
+ VNInfo *VNI =
+ new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), def, CopyMI);
VNI->setIsDefAccurate(isDefAccurate);
valnos.push_back(VNI);
return VNI;
@@ -377,23 +330,12 @@ namespace llvm {
/// for the Value number.
VNInfo *createValueCopy(const VNInfo *orig,
VNInfo::Allocator &VNInfoAllocator) {
- VNInfo *VNI = VNInfoAllocator.Allocate();
- new (VNI) VNInfo((unsigned)valnos.size(), *orig);
+ VNInfo *VNI =
+ new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), *orig);
valnos.push_back(VNI);
return VNI;
}
- /// addKills - Add a number of kills into the VNInfo kill vector. If this
- /// interval is live at a kill point, then the kill is not added.
- void addKills(VNInfo *VNI, const VNInfo::KillSet &kills) {
- for (unsigned i = 0, e = static_cast<unsigned>(kills.size());
- i != e; ++i) {
- if (!liveBeforeAndAt(kills[i])) {
- VNI->addKill(kills[i]);
- }
- }
- }
-
/// isOnlyLROfValNo - Return true if the specified live range is the only
/// one defined by the its val#.
bool isOnlyLROfValNo(const LiveRange *LR) {
@@ -472,6 +414,17 @@ namespace llvm {
// range.If it does, then check if the previous live range ends at index-1.
bool liveBeforeAndAt(SlotIndex index) const;
+ /// killedAt - Return true if a live range ends at index. Note that the kill
+ /// point is not contained in the half-open live range. It is usually the
+ /// getDefIndex() slot following its last use.
+ bool killedAt(SlotIndex index) const;
+
+ /// killedInRange - Return true if the interval has kills in [Start,End).
+ /// Note that the kill point is considered the end of a live range, so it is
+ /// not contained in the live range. If a live range ends at End, it won't
+ /// be counted as a kill by this method.
+ bool killedInRange(SlotIndex Start, SlotIndex End) const;
+
/// getLiveRangeContaining - Return the live range that contains the
/// specified index, or null if there is none.
const LiveRange *getLiveRangeContaining(SlotIndex Idx) const {
@@ -486,6 +439,12 @@ namespace llvm {
return I == end() ? 0 : &*I;
}
+ /// getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
+ VNInfo *getVNInfoAt(SlotIndex Idx) const {
+ const_iterator I = FindLiveRangeContaining(Idx);
+ return I == end() ? 0 : I->valno;
+ }
+
/// FindLiveRangeContaining - Return an iterator to the live range that
/// contains the specified index, or end() if there is none.
const_iterator FindLiveRangeContaining(SlotIndex Idx) const;
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index 32fa709..5a0d81b 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -133,10 +133,9 @@ namespace llvm {
bool conflictsWithPhysReg(const LiveInterval &li, VirtRegMap &vrm,
unsigned reg);
- /// conflictsWithSubPhysRegRef - Similar to conflictsWithPhysRegRef except
- /// it checks for sub-register reference and it can check use as well.
- bool conflictsWithSubPhysRegRef(LiveInterval &li, unsigned Reg,
- bool CheckUse,
+ /// conflictsWithAliasRef - Similar to conflictsWithPhysRegRef except
+ /// it checks for alias uses and defs.
+ bool conflictsWithAliasRef(LiveInterval &li, unsigned Reg,
SmallPtrSet<MachineInstr*,32> &JoinedCopies);
// Interval creation
@@ -229,10 +228,6 @@ namespace llvm {
VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
- /// getVNInfoSourceReg - Helper function that parses the specified VNInfo
- /// copy field and returns the source register that defines it.
- unsigned getVNInfoSourceReg(const VNInfo *VNI) const;
-
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void releaseMemory();
@@ -249,12 +244,6 @@ namespace llvm {
addIntervalsForSpills(const LiveInterval& i,
SmallVectorImpl<LiveInterval*> &SpillIs,
const MachineLoopInfo *loopInfo, VirtRegMap& vrm);
-
- /// addIntervalsForSpillsFast - Quickly create new intervals for spilled
- /// defs / uses without remat or splitting.
- std::vector<LiveInterval*>
- addIntervalsForSpillsFast(const LiveInterval &li,
- const MachineLoopInfo *loopInfo, VirtRegMap &vrm);
/// spillPhysRegAroundRegDefsUses - Spill the specified physical register
/// around all defs and uses of the specified interval. Return true if it
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index cc651ca..3cfc47a 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -19,6 +19,7 @@
namespace llvm {
+class Pass;
class BasicBlock;
class MachineFunction;
class MCSymbol;
@@ -258,6 +259,11 @@ public:
/// machine basic block (i.e., copies all the successors fromMBB and
/// remove all the successors from fromMBB).
void transferSuccessors(MachineBasicBlock *fromMBB);
+
+ /// transferSuccessorsAndUpdatePHIs - Transfers all the successors, as
+ /// in transferSuccessors, and update PHI operands in the successor blocks
+ /// which refer to fromMBB to refer to this.
+ void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB);
/// isSuccessor - Return true if the specified MBB is a successor of this
/// block.
@@ -276,11 +282,26 @@ public:
/// branch to do so (e.g., a table jump). True is a conservative answer.
bool canFallThrough();
+ /// Returns a pointer to the first instructon in this block that is not a
+ /// PHINode instruction. When adding instruction to the beginning of the
+ /// basic block, they should be added before the returned value, not before
+ /// the first instruction, which might be PHI.
+ /// Returns end() is there's no non-PHI instruction.
+ iterator getFirstNonPHI();
+
/// getFirstTerminator - returns an iterator to the first terminator
/// instruction of this basic block. If a terminator does not exist,
/// it returns end()
iterator getFirstTerminator();
+ /// SplitCriticalEdge - Split the critical edge from this block to the
+ /// given successor block, and return the newly created block, or null
+ /// if splitting is not possible.
+ ///
+ /// This function updates LiveVariables, MachineDominatorTree, and
+ /// MachineLoopInfo, as applicable.
+ MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P);
+
void pop_front() { Insts.pop_front(); }
void pop_back() { Insts.pop_back(); }
void push_back(MachineInstr *MI) { Insts.push_back(MI); }
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index fe2c298..9471316 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -33,16 +33,14 @@ class BitVector;
/// callee saved register in the current frame.
class CalleeSavedInfo {
unsigned Reg;
- const TargetRegisterClass *RegClass;
int FrameIdx;
public:
- CalleeSavedInfo(unsigned R, const TargetRegisterClass *RC, int FI = 0)
- : Reg(R), RegClass(RC), FrameIdx(FI) {}
+ explicit CalleeSavedInfo(unsigned R, int FI = 0)
+ : Reg(R), 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; }
};
@@ -100,8 +98,7 @@ class MachineFrameInfo {
// cannot alias any other memory objects.
bool isSpillSlot;
- StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
- bool isSS)
+ StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, bool isSS)
: SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
isSpillSlot(isSS) {}
};
@@ -352,8 +349,7 @@ public:
/// efficiency. By default, fixed objects are immutable. This returns an
/// index with a negative value.
///
- int CreateFixedObject(uint64_t Size, int64_t SPOffset,
- bool Immutable, bool isSS);
+ int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable);
/// isFixedObjectIndex - Returns true if the specified index corresponds to a
diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h
index 1a2b129..685e868 100644
--- a/include/llvm/CodeGen/MachineFunctionPass.h
+++ b/include/llvm/CodeGen/MachineFunctionPass.h
@@ -34,9 +34,6 @@ protected:
explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {}
explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {}
- /// createPrinterPass - Get a machine function printer pass.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
-
/// runOnMachineFunction - This method must be overloaded to perform the
/// desired machine code transformation or analysis.
///
@@ -51,7 +48,11 @@ protected:
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
private:
- bool runOnFunction(Function &F);
+ /// createPrinterPass - Get a machine function printer pass.
+ virtual Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const;
+
+ virtual bool runOnFunction(Function &F);
};
} // End llvm namespace
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index cf691bb..e67b2dd 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -215,9 +215,6 @@ public:
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
- bool isExtractSubreg() const {
- return getOpcode() == TargetOpcode::EXTRACT_SUBREG;
- }
bool isInsertSubreg() const {
return getOpcode() == TargetOpcode::INSERT_SUBREG;
}
@@ -227,7 +224,22 @@ public:
bool isRegSequence() const {
return getOpcode() == TargetOpcode::REG_SEQUENCE;
}
-
+ bool isCopy() const {
+ return getOpcode() == TargetOpcode::COPY;
+ }
+
+ /// isCopyLike - Return true if the instruction behaves like a copy.
+ /// This does not include native copy instructions.
+ bool isCopyLike() const {
+ return isCopy() || isSubregToReg();
+ }
+
+ /// isIdentityCopy - Return true is the instruction is an identity copy.
+ bool isIdentityCopy() const {
+ return isCopy() && getOperand(0).getReg() == getOperand(1).getReg() &&
+ getOperand(0).getSubReg() == getOperand(1).getSubReg();
+ }
+
/// readsRegister - Return true if the MachineInstr reads the specified
/// register. If TargetRegisterInfo is passed, then it also checks if there
/// is a read of a super-register.
@@ -339,6 +351,11 @@ public:
/// copyPredicates - Copies predicate operand(s) from MI.
void copyPredicates(const MachineInstr *MI);
+ /// substituteRegister - Replace all occurrences of FromReg with ToReg:SubIdx,
+ /// properly composing subreg indices where necessary.
+ void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx,
+ const TargetRegisterInfo &RegInfo);
+
/// 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
@@ -359,6 +376,11 @@ public:
void addRegisterDefined(unsigned IncomingReg,
const TargetRegisterInfo *RegInfo = 0);
+ /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as dead
+ /// except those in the UsedRegs list.
+ void setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRegs,
+ const TargetRegisterInfo &TRI);
+
/// isSafeToMove - Return true if it is safe to move this instruction. If
/// SawStore is set to true, it means that there is a store (or call) between
/// the instruction's location and its intended destination.
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
index 1b6ab2c..6264349 100644
--- a/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -74,7 +74,7 @@ private:
JTEntryKind EntryKind;
std::vector<MachineJumpTableEntry> JumpTables;
public:
- MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {}
+ explicit MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {}
JTEntryKind getEntryKind() const { return EntryKind; }
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index 8459a8d..3b3e31e 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -64,13 +64,13 @@ class MachineLoopInfo : public MachineFunctionPass {
void operator=(const MachineLoopInfo &); // do not implement
MachineLoopInfo(const MachineLoopInfo &); // do not implement
- LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; }
-
public:
static char ID; // Pass identification, replacement for typeid
MachineLoopInfo() : MachineFunctionPass(&ID) {}
+ LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; }
+
/// iterator/begin/end - The interface to the top-level loops in the current
/// function.
///
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 31858ce..afa2c29 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -27,6 +27,7 @@ class MachineInstr;
class MachineRegisterInfo;
class MDNode;
class TargetMachine;
+class TargetRegisterInfo;
class raw_ostream;
class MCSymbol;
@@ -246,7 +247,20 @@ public:
assert(isReg() && "Wrong MachineOperand accessor");
SubReg = (unsigned char)subReg;
}
-
+
+ /// substVirtReg - Substitute the current register with the virtual
+ /// subregister Reg:SubReg. Take any existing SubReg index into account,
+ /// using TargetRegisterInfo to compose the subreg indices if necessary.
+ /// Reg must be a virtual register, SubIdx can be 0.
+ ///
+ void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo&);
+
+ /// substPhysReg - Substitute the current register with the physical register
+ /// Reg, taking any existing SubReg into account. For instance,
+ /// substPhysReg(%EAX) will change %reg1024:sub_8bit to %AL.
+ ///
+ void substPhysReg(unsigned Reg, const TargetRegisterInfo&);
+
void setIsUse(bool Val = true) {
assert(isReg() && "Wrong MachineOperand accessor");
assert((Val || !isDebug()) && "Marking a debug operation as def");
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index fa14fdc..066c91b 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -35,7 +35,7 @@ class MachineRegisterInfo {
/// RegClassVRegMap - This vector acts as a map from TargetRegisterClass to
/// virtual registers. For each target register class, it keeps a list of
/// virtual registers belonging to the class.
- std::vector<std::vector<unsigned> > RegClass2VRegMap;
+ std::vector<unsigned> *RegClass2VRegMap;
/// RegAllocHints - This vector records register allocation hints for virtual
/// registers. For each virtual register, it keeps a register and hint type
@@ -363,7 +363,18 @@ public:
defusechain_iterator operator++(int) { // Postincrement
defusechain_iterator tmp = *this; ++*this; return tmp;
}
-
+
+ /// skipInstruction - move forward until reaching a different instruction.
+ /// Return the skipped instruction that is no longer pointed to, or NULL if
+ /// already pointing to end().
+ MachineInstr *skipInstruction() {
+ if (!Op) return 0;
+ MachineInstr *MI = Op->getParent();
+ do ++*this;
+ while (Op && Op->getParent() == MI);
+ return MI;
+ }
+
MachineOperand &getOperand() const {
assert(Op && "Cannot dereference end iterator!");
return *Op;
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 2f5d576..7445ec7 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -85,15 +85,10 @@ namespace llvm {
///
FunctionPass *createDeadMachineInstructionElimPass();
- /// Creates a register allocator as the user specified on the command line.
+ /// Creates a register allocator as the user specified on the command line, or
+ /// picks one that matches OptLevel.
///
- FunctionPass *createRegisterAllocator();
-
- /// 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();
+ FunctionPass *createRegisterAllocator(CodeGenOpt::Level OptLevel);
/// FastRegisterAllocation Pass - This pass register allocates as fast as
/// possible. It is best suited for debug code where live ranges are short.
@@ -147,10 +142,6 @@ namespace llvm {
/// headers to target specific alignment boundary.
FunctionPass *createCodePlacementOptPass();
- /// getRegisterAllocator - This creates an instance of the register allocator
- /// for the Sparc.
- FunctionPass *getRegisterAllocator(TargetMachine &T);
-
/// IntrinsicLowering Pass - Performs target-independent LLVM IR
/// transformations for highly portable strategies.
FunctionPass *createGCLoweringPass();
diff --git a/include/llvm/CodeGen/PostRAHazardRecognizer.h b/include/llvm/CodeGen/PostRAHazardRecognizer.h
new file mode 100644
index 0000000..24d73cb
--- /dev/null
+++ b/include/llvm/CodeGen/PostRAHazardRecognizer.h
@@ -0,0 +1,94 @@
+//=- llvm/CodeGen/PostRAHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the PostRAHazardRecognizer class, which
+// implements hazard-avoidance heuristics for scheduling, based on the
+// scheduling itineraries specified for the target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H
+#define LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H
+
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
+#include "llvm/System/DataTypes.h"
+
+#include <cassert>
+#include <cstring>
+#include <string>
+
+namespace llvm {
+
+class InstrItineraryData;
+class SUnit;
+
+class PostRAHazardRecognizer : public ScheduleHazardRecognizer {
+ // ScoreBoard to track function unit usage. ScoreBoard[0] is a
+ // mask of the FUs in use in the cycle currently being
+ // schedule. ScoreBoard[1] is a mask for the next cycle. The
+ // ScoreBoard is used as a circular buffer with the current cycle
+ // indicated by Head.
+ class ScoreBoard {
+ unsigned *Data;
+
+ // The maximum number of cycles monitored by the Scoreboard. This
+ // value is determined based on the target itineraries to ensure
+ // that all hazards can be tracked.
+ size_t Depth;
+ // Indices into the Scoreboard that represent the current cycle.
+ size_t Head;
+ public:
+ ScoreBoard():Data(NULL), Depth(0), Head(0) { }
+ ~ScoreBoard() {
+ delete[] Data;
+ }
+
+ size_t getDepth() const { return Depth; }
+ unsigned& operator[](size_t idx) const {
+ assert(Depth && "ScoreBoard was not initialized properly!");
+
+ return Data[(Head + idx) % Depth];
+ }
+
+ void reset(size_t d = 1) {
+ if (Data == NULL) {
+ Depth = d;
+ Data = new unsigned[Depth];
+ }
+
+ memset(Data, 0, Depth * sizeof(Data[0]));
+ Head = 0;
+ }
+
+ void advance() {
+ Head = (Head + 1) % Depth;
+ }
+
+ // Print the scoreboard.
+ void dump() const;
+ };
+
+ // Itinerary data for the target.
+ const InstrItineraryData &ItinData;
+
+ ScoreBoard ReservedScoreboard;
+ ScoreBoard RequiredScoreboard;
+
+public:
+ PostRAHazardRecognizer(const InstrItineraryData &ItinData);
+
+ virtual HazardType getHazardType(SUnit *SU);
+ virtual void Reset();
+ virtual void EmitInstruction(SUnit *SU);
+ virtual void AdvanceCycle();
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/RegisterCoalescer.h b/include/llvm/CodeGen/RegisterCoalescer.h
index 1490aa0..7644433 100644
--- a/include/llvm/CodeGen/RegisterCoalescer.h
+++ b/include/llvm/CodeGen/RegisterCoalescer.h
@@ -25,6 +25,9 @@ namespace llvm {
class RegallocQuery;
class AnalysisUsage;
class MachineInstr;
+ class TargetRegisterInfo;
+ class TargetRegisterClass;
+ class TargetInstrInfo;
/// An abstract interface for register coalescers. Coalescers must
/// implement this interface to be part of the coalescer analysis
@@ -141,6 +144,93 @@ namespace llvm {
return true;
}
};
+
+
+ /// CoalescerPair - A helper class for register coalescers. When deciding if
+ /// two registers can be coalesced, CoalescerPair can determine if a copy
+ /// instruction would become an identity copy after coalescing.
+ class CoalescerPair {
+ const TargetInstrInfo &tii_;
+ const TargetRegisterInfo &tri_;
+
+ /// dstReg_ - The register that will be left after coalescing. It can be a
+ /// virtual or physical register.
+ unsigned dstReg_;
+
+ /// srcReg_ - the virtual register that will be coalesced into dstReg.
+ unsigned srcReg_;
+
+ /// subReg_ - The subregister index of srcReg in dstReg_. It is possible the
+ /// coalesce srcReg_ into a subreg of the larger dstReg_ when dstReg_ is a
+ /// virtual register.
+ unsigned subIdx_;
+
+ /// partial_ - True when the original copy was a partial subregister copy.
+ bool partial_;
+
+ /// crossClass_ - True when both regs are virtual, and newRC is constrained.
+ bool crossClass_;
+
+ /// flipped_ - True when DstReg and SrcReg are reversed from the oriignal copy
+ /// instruction.
+ bool flipped_;
+
+ /// newRC_ - The register class of the coalesced register, or NULL if dstReg_
+ /// is a physreg.
+ const TargetRegisterClass *newRC_;
+
+ /// compose - Compose subreg indices a and b, either may be 0.
+ unsigned compose(unsigned, unsigned) const;
+
+ /// isMoveInstr - Return true if MI is a move or subreg instruction.
+ bool isMoveInstr(const MachineInstr *MI, unsigned &Src, unsigned &Dst,
+ unsigned &SrcSub, unsigned &DstSub) const;
+
+ public:
+ CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri)
+ : tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0),
+ partial_(false), crossClass_(false), flipped_(false), newRC_(0) {}
+
+ /// setRegisters - set registers to match the copy instruction MI. Return
+ /// false if MI is not a coalescable copy instruction.
+ bool setRegisters(const MachineInstr*);
+
+ /// flip - Swap srcReg_ and dstReg_. Return false if swapping is impossible
+ /// because dstReg_ is a physical register, or subIdx_ is set.
+ bool flip();
+
+ /// isCoalescable - Return true if MI is a copy instruction that will become
+ /// an identity copy after coalescing.
+ bool isCoalescable(const MachineInstr*) const;
+
+ /// isPhys - Return true if DstReg is a physical register.
+ bool isPhys() const { return !newRC_; }
+
+ /// isPartial - Return true if the original copy instruction did not copy the
+ /// full register, but was a subreg operation.
+ bool isPartial() const { return partial_; }
+
+ /// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's.
+ bool isCrossClass() const { return crossClass_; }
+
+ /// isFlipped - Return true when getSrcReg is the register being defined by
+ /// the original copy instruction.
+ bool isFlipped() const { return flipped_; }
+
+ /// getDstReg - Return the register (virtual or physical) that will remain
+ /// after coalescing.
+ unsigned getDstReg() const { return dstReg_; }
+
+ /// getSrcReg - Return the virtual register that will be coalesced away.
+ unsigned getSrcReg() const { return srcReg_; }
+
+ /// getSubIdx - Return the subregister index in DstReg that SrcReg will be
+ /// coalesced into, or 0.
+ unsigned getSubIdx() const { return subIdx_; }
+
+ /// getNewRC - Return the register class of the coalesced register.
+ const TargetRegisterClass *getNewRC() const { return newRC_; }
+ };
}
// Because of the way .a files work, we must force the SimpleRC
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
index 84b726d..246831c 100644
--- a/include/llvm/CodeGen/RegisterScavenging.h
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -98,6 +98,10 @@ public:
/// getRegsUsed - return all registers currently in use in used.
void getRegsUsed(BitVector &used, bool includeReserved);
+ /// getRegsAvailable - Return all available registers in the register class
+ /// in Mask.
+ void getRegsAvailable(const TargetRegisterClass *RC, BitVector &Mask);
+
/// FindUnusedReg - Find a unused register of the specified register class.
/// Return 0 if none is found.
unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const;
@@ -147,7 +151,12 @@ private:
/// Add Reg and its aliases to BV.
void addRegWithAliases(BitVector &BV, unsigned Reg);
- unsigned findSurvivorReg(MachineBasicBlock::iterator MI,
+ /// findSurvivorReg - Return the candidate register that is unused for the
+ /// longest after StartMI. UseMI is set to the instruction where the search
+ /// stopped.
+ ///
+ /// No more than InstrLimit instructions are inspected.
+ unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI,
BitVector &Candidates,
unsigned InstrLimit,
MachineBasicBlock::iterator &UseMI);
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
index 42ae563..a51e82a 100644
--- a/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -247,6 +247,40 @@ namespace RTLIB {
// EXCEPTION HANDLING
UNWIND_RESUME,
+ // Family ATOMICs
+ SYNC_VAL_COMPARE_AND_SWAP_1,
+ SYNC_VAL_COMPARE_AND_SWAP_2,
+ SYNC_VAL_COMPARE_AND_SWAP_4,
+ SYNC_VAL_COMPARE_AND_SWAP_8,
+ SYNC_LOCK_TEST_AND_SET_1,
+ SYNC_LOCK_TEST_AND_SET_2,
+ SYNC_LOCK_TEST_AND_SET_4,
+ SYNC_LOCK_TEST_AND_SET_8,
+ SYNC_FETCH_AND_ADD_1,
+ SYNC_FETCH_AND_ADD_2,
+ SYNC_FETCH_AND_ADD_4,
+ SYNC_FETCH_AND_ADD_8,
+ SYNC_FETCH_AND_SUB_1,
+ SYNC_FETCH_AND_SUB_2,
+ SYNC_FETCH_AND_SUB_4,
+ SYNC_FETCH_AND_SUB_8,
+ SYNC_FETCH_AND_AND_1,
+ SYNC_FETCH_AND_AND_2,
+ SYNC_FETCH_AND_AND_4,
+ SYNC_FETCH_AND_AND_8,
+ SYNC_FETCH_AND_OR_1,
+ SYNC_FETCH_AND_OR_2,
+ SYNC_FETCH_AND_OR_4,
+ SYNC_FETCH_AND_OR_8,
+ SYNC_FETCH_AND_XOR_1,
+ SYNC_FETCH_AND_XOR_2,
+ SYNC_FETCH_AND_XOR_4,
+ SYNC_FETCH_AND_XOR_8,
+ SYNC_FETCH_AND_NAND_1,
+ SYNC_FETCH_AND_NAND_2,
+ SYNC_FETCH_AND_NAND_4,
+ SYNC_FETCH_AND_NAND_8,
+
UNKNOWN_LIBCALL
};
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 97202bd..de49d18 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -29,7 +29,6 @@
namespace llvm {
class AliasAnalysis;
-class FunctionLoweringInfo;
class MachineConstantPoolValue;
class MachineFunction;
class MDNode;
@@ -134,7 +133,6 @@ class SelectionDAG {
const TargetLowering &TLI;
const TargetSelectionDAGInfo &TSI;
MachineFunction *MF;
- FunctionLoweringInfo &FLI;
LLVMContext *Context;
/// EntryNode - The starting token.
@@ -187,7 +185,7 @@ class SelectionDAG {
SelectionDAG(const SelectionDAG&); // Do not implement.
public:
- SelectionDAG(const TargetMachine &TM, FunctionLoweringInfo &fli);
+ explicit SelectionDAG(const TargetMachine &TM);
~SelectionDAG();
/// init - Prepare this SelectionDAG to process code in the given
@@ -204,7 +202,6 @@ public:
const TargetMachine &getTarget() const { return TM; }
const TargetLowering &getTargetLoweringInfo() const { return TLI; }
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
- FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; }
LLVMContext *getContext() const {return Context; }
/// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
@@ -351,13 +348,13 @@ public:
SDValue getTargetConstantFP(const ConstantFP &Val, EVT VT) {
return getConstantFP(Val, VT, true);
}
- SDValue getGlobalAddress(const GlobalValue *GV, EVT VT,
+ SDValue getGlobalAddress(const GlobalValue *GV, DebugLoc DL, EVT VT,
int64_t offset = 0, bool isTargetGA = false,
unsigned char TargetFlags = 0);
- SDValue getTargetGlobalAddress(const GlobalValue *GV, EVT VT,
+ SDValue getTargetGlobalAddress(const GlobalValue *GV, DebugLoc DL, EVT VT,
int64_t offset = 0,
unsigned char TargetFlags = 0) {
- return getGlobalAddress(GV, VT, offset, true, TargetFlags);
+ return getGlobalAddress(GV, DL, VT, offset, true, TargetFlags);
}
SDValue getFrameIndex(int FI, EVT VT, bool isTarget = false);
SDValue getTargetFrameIndex(int FI, EVT VT) {
@@ -585,7 +582,7 @@ public:
/// getVAArg - VAArg produces a result and token chain, and takes a pointer
/// and a source value as input.
SDValue getVAArg(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
- SDValue SV);
+ SDValue SV, unsigned Align);
/// getAtomic - Gets a node for an atomic op, produces result and chain and
/// takes 3 operands
@@ -635,18 +632,20 @@ public:
SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
const Value *SV, int SVOffset, bool isVolatile,
bool isNonTemporal, unsigned Alignment);
- SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
+ SDValue getExtLoad(ISD::LoadExtType ExtType, EVT VT, DebugLoc dl,
SDValue Chain, SDValue Ptr, const Value *SV,
int SVOffset, EVT MemVT, bool isVolatile,
bool isNonTemporal, unsigned Alignment);
SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
- SDValue Offset, ISD::MemIndexedMode AM);
- SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
- EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset,
+ SDValue Offset, ISD::MemIndexedMode AM);
+ SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
+ EVT VT, DebugLoc dl,
+ SDValue Chain, SDValue Ptr, SDValue Offset,
const Value *SV, int SVOffset, EVT MemVT,
bool isVolatile, bool isNonTemporal, unsigned Alignment);
- SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
- EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset,
+ SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
+ EVT VT, DebugLoc dl,
+ SDValue Chain, SDValue Ptr, SDValue Offset,
EVT MemVT, MachineMemOperand *MMO);
/// getStore - Helper function to build ISD::STORE nodes.
@@ -681,15 +680,15 @@ public:
/// 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.
- SDValue UpdateNodeOperands(SDValue N, SDValue Op);
- SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2);
- SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2,
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op);
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2);
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
SDValue Op3);
- SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2,
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
SDValue Op3, SDValue Op4);
- SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2,
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
SDValue Op3, SDValue Op4, SDValue Op5);
- SDValue UpdateNodeOperands(SDValue N,
+ SDNode *UpdateNodeOperands(SDNode *N,
const SDValue *Ops, unsigned NumOps);
/// SelectNodeTo - These are used for target selectors to *mutate* the
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 3817580..01d05dd 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -280,19 +280,16 @@ private:
SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo);
- void PrepareEHLandingPad(MachineBasicBlock *BB);
+ void PrepareEHLandingPad();
void SelectAllBasicBlocks(const Function &Fn);
- void FinishBasicBlock(MachineBasicBlock *BB);
+ void FinishBasicBlock();
- MachineBasicBlock *SelectBasicBlock(MachineBasicBlock *BB,
- const BasicBlock *LLVMBB,
- BasicBlock::const_iterator Begin,
- BasicBlock::const_iterator End,
- bool &HadTailCall);
- MachineBasicBlock *CodeGenAndEmitDAG(MachineBasicBlock *BB);
+ void SelectBasicBlock(BasicBlock::const_iterator Begin,
+ BasicBlock::const_iterator End,
+ bool &HadTailCall);
+ void CodeGenAndEmitDAG();
void LowerArguments(const BasicBlock *BB);
- void ShrinkDemandedOps();
void ComputeLiveOutVRegInfo();
/// Create the scheduler. If a specific scheduler was specified
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index fd529b6..4cf6f36 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -549,6 +549,15 @@ public:
return FoundNode;
}
+ /// getFlaggedUser - If this node has a flag value with a user, return
+ /// the user (there is at most one). Otherwise return NULL.
+ SDNode *getFlaggedUser() const {
+ for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI)
+ if (UI.getUse().get().getValueType() == MVT::Flag)
+ return *UI;
+ return 0;
+ }
+
/// getNumValues - Return the number of values defined/returned by this
/// operator.
///
@@ -1082,6 +1091,7 @@ public:
uint64_t getZExtValue() const { return Value->getZExtValue(); }
int64_t getSExtValue() const { return Value->getSExtValue(); }
+ bool isOne() const { return Value->isOne(); }
bool isNullValue() const { return Value->isNullValue(); }
bool isAllOnesValue() const { return Value->isAllOnesValue(); }
@@ -1130,7 +1140,7 @@ public:
}
bool isExactlyValue(const APFloat& V) const;
- bool isValueValidForType(EVT VT, const APFloat& Val);
+ static bool isValueValidForType(EVT VT, const APFloat& Val);
static bool classof(const ConstantFPSDNode *) { return true; }
static bool classof(const SDNode *N) {
@@ -1144,7 +1154,7 @@ class GlobalAddressSDNode : public SDNode {
int64_t Offset;
unsigned char TargetFlags;
friend class SelectionDAG;
- GlobalAddressSDNode(unsigned Opc, const GlobalValue *GA, EVT VT,
+ GlobalAddressSDNode(unsigned Opc, DebugLoc DL, const GlobalValue *GA, EVT VT,
int64_t o, unsigned char TargetFlags);
public:
@@ -1454,125 +1464,6 @@ public:
}
};
-namespace ISD {
- struct ArgFlagsTy {
- private:
- static const uint64_t NoFlagSet = 0ULL;
- static const uint64_t ZExt = 1ULL<<0; ///< Zero extended
- static const uint64_t ZExtOffs = 0;
- static const uint64_t SExt = 1ULL<<1; ///< Sign extended
- static const uint64_t SExtOffs = 1;
- static const uint64_t InReg = 1ULL<<2; ///< Passed in register
- static const uint64_t InRegOffs = 2;
- static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr
- static const uint64_t SRetOffs = 3;
- static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value
- static const uint64_t ByValOffs = 4;
- static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
- static const uint64_t NestOffs = 5;
- static const uint64_t ByValAlign = 0xFULL << 6; //< Struct alignment
- static const uint64_t ByValAlignOffs = 6;
- static const uint64_t Split = 1ULL << 10;
- static const uint64_t SplitOffs = 10;
- static const uint64_t OrigAlign = 0x1FULL<<27;
- static const uint64_t OrigAlignOffs = 27;
- static const uint64_t ByValSize = 0xffffffffULL << 32; //< Struct size
- static const uint64_t ByValSizeOffs = 32;
-
- static const uint64_t One = 1ULL; //< 1 of this type, for shifts
-
- uint64_t Flags;
- public:
- ArgFlagsTy() : Flags(0) { }
-
- bool isZExt() const { return Flags & ZExt; }
- void setZExt() { Flags |= One << ZExtOffs; }
-
- bool isSExt() const { return Flags & SExt; }
- void setSExt() { Flags |= One << SExtOffs; }
-
- bool isInReg() const { return Flags & InReg; }
- void setInReg() { Flags |= One << InRegOffs; }
-
- bool isSRet() const { return Flags & SRet; }
- void setSRet() { Flags |= One << SRetOffs; }
-
- bool isByVal() const { return Flags & ByVal; }
- void setByVal() { Flags |= One << ByValOffs; }
-
- bool isNest() const { return Flags & Nest; }
- void setNest() { Flags |= One << NestOffs; }
-
- unsigned getByValAlign() const {
- return (unsigned)
- ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2);
- }
- void setByValAlign(unsigned A) {
- Flags = (Flags & ~ByValAlign) |
- (uint64_t(Log2_32(A) + 1) << ByValAlignOffs);
- }
-
- bool isSplit() const { return Flags & Split; }
- void setSplit() { Flags |= One << SplitOffs; }
-
- unsigned getOrigAlign() const {
- return (unsigned)
- ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2);
- }
- void setOrigAlign(unsigned A) {
- Flags = (Flags & ~OrigAlign) |
- (uint64_t(Log2_32(A) + 1) << OrigAlignOffs);
- }
-
- unsigned getByValSize() const {
- return (unsigned)((Flags & ByValSize) >> ByValSizeOffs);
- }
- void setByValSize(unsigned S) {
- Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
- }
-
- /// getArgFlagsString - Returns the flags as a string, eg: "zext align:4".
- std::string getArgFlagsString();
-
- /// getRawBits - Represent the flags as a bunch of bits.
- uint64_t getRawBits() const { return Flags; }
- };
-
- /// InputArg - This struct carries flags and type information about a
- /// single incoming (formal) argument or incoming (from the perspective
- /// of the caller) return value virtual register.
- ///
- struct InputArg {
- ArgFlagsTy Flags;
- EVT VT;
- bool Used;
-
- InputArg() : VT(MVT::Other), Used(false) {}
- InputArg(ISD::ArgFlagsTy flags, EVT vt, bool used)
- : Flags(flags), VT(vt), Used(used) {
- assert(VT.isSimple() &&
- "InputArg value type must be Simple!");
- }
- };
-
- /// OutputArg - This struct carries flags and a value for a
- /// single outgoing (actual) argument or outgoing (from the perspective
- /// of the caller) return value virtual register.
- ///
- struct OutputArg {
- ArgFlagsTy Flags;
- SDValue Val;
- bool IsFixed;
-
- OutputArg() : IsFixed(false) {}
- OutputArg(ISD::ArgFlagsTy flags, SDValue val, bool isfixed)
- : Flags(flags), Val(val), IsFixed(isfixed) {
- assert(Val.getValueType().isSimple() &&
- "OutputArg value type must be Simple!");
- }
- };
-}
-
/// VTSDNode - This class is used to represent EVT's, which are used
/// to parameterize some operations.
class VTSDNode : public SDNode {
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index 3c56d0d..f1f047b 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -23,6 +23,7 @@
#define LLVM_CODEGEN_SLOTINDEXES_H
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
@@ -663,15 +664,20 @@ namespace llvm {
MachineBasicBlock::iterator miItr(mi);
bool needRenumber = false;
IndexListEntry *newEntry;
-
+ // Get previous index, considering that not all instructions are indexed.
IndexListEntry *prevEntry;
- if (miItr == mbb->begin()) {
+ for (;;) {
// If mi is at the mbb beginning, get the prev index from the mbb.
- prevEntry = &mbbRangeItr->second.first.entry();
- } else {
- // Otherwise get it from the previous instr.
- MachineBasicBlock::iterator pItr(prior(miItr));
- prevEntry = &getInstructionIndex(pItr).entry();
+ if (miItr == mbb->begin()) {
+ prevEntry = &mbbRangeItr->second.first.entry();
+ break;
+ }
+ // Otherwise rewind until we find a mapped instruction.
+ Mi2IndexMap::const_iterator itr = mi2iMap.find(--miItr);
+ if (itr != mi2iMap.end()) {
+ prevEntry = &itr->second.entry();
+ break;
+ }
}
// Get next entry from previous entry.
@@ -757,6 +763,47 @@ namespace llvm {
mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex));
}
+ /// Add the given MachineBasicBlock into the maps.
+ void insertMBBInMaps(MachineBasicBlock *mbb) {
+ MachineFunction::iterator nextMBB =
+ llvm::next(MachineFunction::iterator(mbb));
+ IndexListEntry *startEntry = createEntry(0, 0);
+ IndexListEntry *terminatorEntry = createEntry(0, 0);
+ IndexListEntry *nextEntry = 0;
+
+ if (nextMBB == mbb->getParent()->end()) {
+ nextEntry = getTail();
+ } else {
+ nextEntry = &getMBBStartIdx(nextMBB).entry();
+ }
+
+ insert(nextEntry, startEntry);
+ insert(nextEntry, terminatorEntry);
+
+ SlotIndex startIdx(startEntry, SlotIndex::LOAD);
+ SlotIndex terminatorIdx(terminatorEntry, SlotIndex::PHI_BIT);
+ SlotIndex endIdx(nextEntry, SlotIndex::LOAD);
+
+ terminatorGaps.insert(
+ std::make_pair(mbb, terminatorIdx));
+
+ mbb2IdxMap.insert(
+ std::make_pair(mbb, std::make_pair(startIdx, endIdx)));
+
+ idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb));
+
+ if (MachineFunction::iterator(mbb) != mbb->getParent()->begin()) {
+ // Have to update the end index of the previous block.
+ MachineBasicBlock *priorMBB =
+ llvm::prior(MachineFunction::iterator(mbb));
+ mbb2IdxMap[priorMBB].second = startIdx;
+ }
+
+ renumberIndexes();
+ std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
+
+ }
+
};
OpenPOWER on IntegriCloud