//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "isel"
+#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/CodeGen/SelectionDAGISel.h"
-#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/Constants.h"
#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Intrinsics.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/ParameterAttributes.h"
-#include "llvm/CodeGen/Collector.h"
+#include "llvm/CodeGen/FastISel.h"
+#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Timer.h"
#include <algorithm>
using namespace llvm;
static cl::opt<bool>
-EnableValueProp("enable-value-prop", cl::Hidden, cl::init(false));
-
+EnableValueProp("enable-value-prop", cl::Hidden);
+static cl::opt<bool>
+EnableLegalizeTypes("enable-legalize-types", cl::Hidden);
+static cl::opt<bool>
+EnableFastISel("fast-isel", cl::Hidden,
+ cl::desc("Enable the experimental \"fast\" instruction selector"));
+static cl::opt<bool>
+DisableFastISelAbort("fast-isel-no-abort", cl::Hidden,
+ cl::desc("Use the SelectionDAGISel when \"fast\" instruction "
+ "selection fails"));
#ifndef NDEBUG
static cl::opt<bool>
+ViewDAGCombine1("view-dag-combine1-dags", cl::Hidden,
+ cl::desc("Pop up a window to show dags before the first "
+ "dag combine pass"));
+static cl::opt<bool>
+ViewLegalizeTypesDAGs("view-legalize-types-dags", cl::Hidden,
+ cl::desc("Pop up a window to show dags before legalize types"));
+static cl::opt<bool>
+ViewLegalizeDAGs("view-legalize-dags", cl::Hidden,
+ cl::desc("Pop up a window to show dags before legalize"));
+static cl::opt<bool>
+ViewDAGCombine2("view-dag-combine2-dags", cl::Hidden,
+ cl::desc("Pop up a window to show dags before the second "
+ "dag combine pass"));
+static cl::opt<bool>
ViewISelDAGs("view-isel-dags", cl::Hidden,
cl::desc("Pop up a window to show isel dags as they are selected"));
static cl::opt<bool>
ViewSUnitDAGs("view-sunit-dags", cl::Hidden,
cl::desc("Pop up a window to show SUnit dags after they are processed"));
#else
-static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0, ViewSUnitDAGs = 0;
+static const bool ViewDAGCombine1 = false,
+ ViewLegalizeTypesDAGs = false, ViewLegalizeDAGs = false,
+ ViewDAGCombine2 = false,
+ ViewISelDAGs = false, ViewSchedDAGs = false,
+ ViewSUnitDAGs = false;
#endif
//===---------------------------------------------------------------------===//
/// this value and returns the result as a ValueVTs value. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
- SDOperand getCopyFromRegs(SelectionDAG &DAG,
- SDOperand &Chain, SDOperand *Flag) const;
+ SDValue getCopyFromRegs(SelectionDAG &DAG,
+ SDValue &Chain, SDValue *Flag) const;
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
/// specified value into the registers specified by this object. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
- void getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
- SDOperand &Chain, SDOperand *Flag) const;
+ void getCopyToRegs(SDValue Val, SelectionDAG &DAG,
+ SDValue &Chain, SDValue *Flag) const;
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
/// operand list. This adds the code marker and includes the number of
/// values added into it.
void AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
- std::vector<SDOperand> &Ops) const;
+ std::vector<SDValue> &Ops) const;
};
}
/// for the target.
ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG,
- MachineBasicBlock *BB) {
+ MachineBasicBlock *BB,
+ bool Fast) {
TargetLowering &TLI = IS->getTargetLowering();
if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) {
- return createTDListDAGScheduler(IS, DAG, BB);
+ return createTDListDAGScheduler(IS, DAG, BB, Fast);
} else {
assert(TLI.getSchedulingPreference() ==
TargetLowering::SchedulingForRegPressure && "Unknown sched type!");
- return createBURRListDAGScheduler(IS, DAG, BB);
+ return createBURRListDAGScheduler(IS, DAG, BB, Fast);
}
}
class FunctionLoweringInfo {
public:
TargetLowering &TLI;
- Function &Fn;
- MachineFunction &MF;
- MachineRegisterInfo &RegInfo;
+ Function *Fn;
+ MachineFunction *MF;
+ MachineRegisterInfo *RegInfo;
+
+ explicit FunctionLoweringInfo(TargetLowering &TLI);
- FunctionLoweringInfo(TargetLowering &TLI, Function &Fn,MachineFunction &MF);
+ /// set - Initialize this FunctionLoweringInfo with the given Function
+ /// and its associated MachineFunction.
+ ///
+ void set(Function &Fn, MachineFunction &MF);
/// MBBMap - A mapping from LLVM basic blocks to their machine code entry.
- std::map<const BasicBlock*, MachineBasicBlock *> MBBMap;
+ 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
/// 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.
- std::map<const AllocaInst*, int> StaticAllocaMap;
+ DenseMap<const AllocaInst*, int> StaticAllocaMap;
#ifndef NDEBUG
SmallSet<Instruction*, 8> CatchInfoLost;
#endif
unsigned MakeReg(MVT VT) {
- return RegInfo.createVirtualRegister(TLI.getRegClassFor(VT));
+ return RegInfo->createVirtualRegister(TLI.getRegClassFor(VT));
}
/// isExportedInst - Return true if the specified value is an instruction
/// LiveOutRegInfo - Information about live out vregs, indexed by their
/// register number offset by 'FirstVirtualRegister'.
std::vector<LiveOutInfo> LiveOutRegInfo;
+
+ /// 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() {
+ MBBMap.clear();
+ ValueMap.clear();
+ StaticAllocaMap.clear();
+#ifndef NDEBUG
+ CatchInfoLost.clear();
+ CatchInfoFound.clear();
+#endif
+ LiveOutRegInfo.clear();
+ }
};
}
/// entry block, return true. This includes arguments used by switches, since
/// the switch may expand into multiple basic blocks.
static bool isOnlyUsedInEntryBlock(Argument *A) {
+ // With FastISel active, we may be splitting blocks, so force creation
+ // of virtual registers for all non-dead arguments.
+ if (EnableFastISel)
+ return A->use_empty();
+
BasicBlock *Entry = A->getParent()->begin();
for (Value::use_iterator UI = A->use_begin(), E = A->use_end(); UI != E; ++UI)
if (cast<Instruction>(*UI)->getParent() != Entry || isa<SwitchInst>(*UI))
return true;
}
-FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli,
- Function &fn, MachineFunction &mf)
- : TLI(tli), Fn(fn), MF(mf), RegInfo(MF.getRegInfo()) {
+FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli)
+ : TLI(tli) {
+}
+
+void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf) {
+ Fn = &fn;
+ MF = &mf;
+ RegInfo = &MF->getRegInfo();
// Create a vreg for each argument register that is not dead and is used
// outside of the entry block for the function.
- for (Function::arg_iterator AI = Fn.arg_begin(), E = Fn.arg_end();
+ for (Function::arg_iterator AI = Fn->arg_begin(), E = Fn->arg_end();
AI != E; ++AI)
if (!isOnlyUsedInEntryBlock(AI))
InitializeRegForValue(AI);
// Initialize the mapping of values to registers. This is only set up for
// instruction values that are used outside of the block that defines
// them.
- Function::iterator BB = Fn.begin(), EB = Fn.end();
+ Function::iterator BB = Fn->begin(), EB = Fn->end();
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
if (ConstantInt *CUI = dyn_cast<ConstantInt>(AI->getArraySize())) {
TySize *= CUI->getZExtValue(); // Get total allocated size.
if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects.
StaticAllocaMap[AI] =
- MF.getFrameInfo()->CreateStackObject(TySize, Align);
+ MF->getFrameInfo()->CreateStackObject(TySize, Align);
}
for (; BB != EB; ++BB)
// Create an initial MachineBasicBlock for each LLVM BasicBlock in F. This
// also creates the initial PHI MachineInstrs, though none of the input
// operands are populated.
- for (BB = Fn.begin(), EB = Fn.end(); BB != EB; ++BB) {
- MachineBasicBlock *MBB = new MachineBasicBlock(BB);
+ for (BB = Fn->begin(), EB = Fn->end(); BB != EB; ++BB) {
+ MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(BB);
MBBMap[BB] = MBB;
- MF.getBasicBlockList().push_back(MBB);
+ MF->push_back(MBB);
// Create Machine PHI nodes for LLVM PHI nodes, lowering them as
// appropriate.
for (BasicBlock::iterator I = BB->begin();(PN = dyn_cast<PHINode>(I)); ++I){
if (PN->use_empty()) continue;
- MVT VT = TLI.getValueType(PN->getType());
- unsigned NumRegisters = TLI.getNumRegisters(VT);
unsigned PHIReg = ValueMap[PN];
assert(PHIReg && "PHI node does not have an assigned virtual register!");
- const TargetInstrInfo *TII = TLI.getTargetMachine().getInstrInfo();
- for (unsigned i = 0; i != NumRegisters; ++i)
- BuildMI(MBB, TII->get(TargetInstrInfo::PHI), PHIReg+i);
+
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(TLI, PN->getType(), ValueVTs);
+ for (unsigned vti = 0, vte = ValueVTs.size(); vti != vte; ++vti) {
+ MVT VT = ValueVTs[vti];
+ unsigned NumRegisters = TLI.getNumRegisters(VT);
+ const TargetInstrInfo *TII = TLI.getTargetMachine().getInstrInfo();
+ for (unsigned i = 0; i != NumRegisters; ++i)
+ BuildMI(MBB, TII->get(TargetInstrInfo::PHI), PHIReg+i);
+ PHIReg += NumRegisters;
+ }
}
}
}
return FirstReg;
}
+namespace {
+
+/// 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;
+};
+
+} // end anonymous namespace
+
//===----------------------------------------------------------------------===//
/// SelectionDAGLowering - This is the common target-independent lowering
/// implementation that is parameterized by a TargetLowering object.
class SelectionDAGLowering {
MachineBasicBlock *CurMBB;
- DenseMap<const Value*, SDOperand> NodeMap;
+ DenseMap<const Value*, SDValue> NodeMap;
/// PendingLoads - Loads are not emitted to the program immediately. We bunch
/// them up and then emit token factor nodes when possible. This allows us to
/// get simple disambiguation between loads without worrying about alias
/// analysis.
- std::vector<SDOperand> PendingLoads;
+ SmallVector<SDValue, 8> PendingLoads;
/// PendingExports - CopyToReg nodes that copy values to virtual registers
/// for export to other blocks need to be emitted before any terminator
/// instruction, but they have no other ordering requirements. We bunch them
/// up and the emit a single tokenfactor for them just before terminator
/// instructions.
- std::vector<SDOperand> PendingExports;
+ SmallVector<SDValue, 8> PendingExports;
/// Case - A struct to record the Value for a switch case, and the
/// case's target basic block.
TargetLowering &TLI;
SelectionDAG &DAG;
const TargetData *TD;
- AliasAnalysis &AA;
+ AliasAnalysis *AA;
/// SwitchCases - Vector of CaseBlock structures used to communicate
/// SwitchInst code generation information.
- std::vector<SelectionDAGISel::CaseBlock> SwitchCases;
+ std::vector<CaseBlock> SwitchCases;
/// JTCases - Vector of JumpTable structures used to communicate
/// SwitchInst code generation information.
- std::vector<SelectionDAGISel::JumpTableBlock> JTCases;
- std::vector<SelectionDAGISel::BitTestBlock> BitTestCases;
+ std::vector<JumpTableBlock> JTCases;
+ /// BitTestCases - Vector of BitTestBlock structures used to communicate
+ /// SwitchInst code generation information.
+ std::vector<BitTestBlock> BitTestCases;
+ std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
+
+ // Emit PHI-node-operand constants only once even if used by multiple
+ // PHI nodes.
+ DenseMap<Constant*, unsigned> ConstantsOut;
+
/// FuncInfo - Information about the function as a whole.
///
FunctionLoweringInfo &FuncInfo;
- /// GCI - Garbage collection metadata for the function.
- CollectorMetadata *GCI;
+ /// GFI - Garbage collection metadata for the function.
+ GCFunctionInfo *GFI;
SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli,
- AliasAnalysis &aa,
- FunctionLoweringInfo &funcinfo,
- CollectorMetadata *gci)
- : TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()), AA(aa),
- FuncInfo(funcinfo), GCI(gci) {
+ FunctionLoweringInfo &funcinfo)
+ : TLI(tli), DAG(dag), FuncInfo(funcinfo) {
+ }
+
+ void init(GCFunctionInfo *gfi, AliasAnalysis &aa) {
+ AA = &aa;
+ GFI = gfi;
+ TD = DAG.getTarget().getTargetData();
+ }
+
+ /// clear - Clear out the curret SelectionDAG and the associated
+ /// state and prepare this SelectionDAGLowering object to be used
+ /// for a new block. This doesn't clear out information about
+ /// additional blocks that are needed to complete switch lowering
+ /// or PHI node updating; that information is cleared out as it is
+ /// consumed.
+ void clear() {
+ NodeMap.clear();
+ PendingLoads.clear();
+ PendingExports.clear();
+ DAG.clear();
}
/// getRoot - Return the current virtual root of the Selection DAG,
/// a store or any other node that may need to be ordered after any
/// prior load instructions.
///
- SDOperand getRoot() {
+ SDValue getRoot() {
if (PendingLoads.empty())
return DAG.getRoot();
if (PendingLoads.size() == 1) {
- SDOperand Root = PendingLoads[0];
+ SDValue Root = PendingLoads[0];
DAG.setRoot(Root);
PendingLoads.clear();
return Root;
}
// Otherwise, we have to make a token factor node.
- SDOperand Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
+ SDValue Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
&PendingLoads[0], PendingLoads.size());
PendingLoads.clear();
DAG.setRoot(Root);
/// PendingLoad items, flush all the PendingExports items. It is necessary
/// to do this before emitting a terminator instruction.
///
- SDOperand getControlRoot() {
- SDOperand Root = DAG.getRoot();
+ SDValue getControlRoot() {
+ SDValue Root = DAG.getRoot();
if (PendingExports.empty())
return Root;
void setCurrentBasicBlock(MachineBasicBlock *MBB) { CurMBB = MBB; }
- SDOperand getValue(const Value *V);
+ SDValue getValue(const Value *V);
- void setValue(const Value *V, SDOperand NewN) {
- SDOperand &N = NodeMap[V];
+ void setValue(const Value *V, SDValue NewN) {
+ SDValue &N = NodeMap[V];
assert(N.Val == 0 && "Already set a value for this node!");
N = NewN;
}
unsigned Opc);
bool isExportableFromCurrentBlock(Value *V, const BasicBlock *FromBB);
void ExportFromCurrentBlock(Value *V);
- void LowerCallTo(CallSite CS, SDOperand Callee, bool IsTailCall,
+ void LowerCallTo(CallSite CS, SDValue Callee, bool IsTailCall,
MachineBasicBlock *LandingPad = NULL);
// Terminator instructions.
CaseRecVector& WorkList,
Value* SV,
MachineBasicBlock* Default);
- void visitSwitchCase(SelectionDAGISel::CaseBlock &CB);
- void visitBitTestHeader(SelectionDAGISel::BitTestBlock &B);
+ void visitSwitchCase(CaseBlock &CB);
+ void visitBitTestHeader(BitTestBlock &B);
void visitBitTestCase(MachineBasicBlock* NextMBB,
unsigned Reg,
- SelectionDAGISel::BitTestCase &B);
- void visitJumpTable(SelectionDAGISel::JumpTable &JT);
- void visitJumpTableHeader(SelectionDAGISel::JumpTable &JT,
- SelectionDAGISel::JumpTableHeader &JTH);
+ BitTestCase &B);
+ void visitJumpTable(JumpTable &JT);
+ void visitJumpTableHeader(JumpTable &JT, JumpTableHeader &JTH);
// These all get lowered before this pass.
void visitInvoke(InvokeInst &I);
void visitVAEnd(CallInst &I);
void visitVACopy(CallInst &I);
- void visitGetResult(GetResultInst &I);
-
void visitUserOp1(Instruction &I) {
assert(0 && "UserOp1 should not exist at instruction selection time!");
abort();
/// larger then ValueVT then AssertOp can be used to specify whether the extra
/// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT
/// (ISD::AssertSext).
-static SDOperand getCopyFromParts(SelectionDAG &DAG,
- const SDOperand *Parts,
+static SDValue getCopyFromParts(SelectionDAG &DAG,
+ const SDValue *Parts,
unsigned NumParts,
MVT PartVT,
MVT ValueVT,
ISD::NodeType AssertOp = ISD::DELETED_NODE) {
assert(NumParts > 0 && "No parts to assemble!");
TargetLowering &TLI = DAG.getTargetLoweringInfo();
- SDOperand Val = Parts[0];
+ SDValue Val = Parts[0];
if (NumParts > 1) {
// Assemble the value from multiple parts.
unsigned RoundBits = PartBits * RoundParts;
MVT RoundVT = RoundBits == ValueBits ?
ValueVT : MVT::getIntegerVT(RoundBits);
- SDOperand Lo, Hi;
+ SDValue Lo, Hi;
if (RoundParts > 2) {
MVT HalfVT = MVT::getIntegerVT(RoundBits/2);
"Part type doesn't match part!");
// Assemble the parts into intermediate operands.
- SmallVector<SDOperand, 8> Ops(NumIntermediates);
+ SmallVector<SDValue, 8> Ops(NumIntermediates);
if (NumIntermediates == NumParts) {
// If the register was not expanded, truncate or copy the value,
// as appropriate.
return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
assert(0 && "Unknown mismatch!");
- return SDOperand();
+ return SDValue();
}
/// getCopyToParts - Create a series of nodes that contain the specified value
/// split into legal parts. If the parts contain more bits than Val, then, for
/// integers, ExtendKind can be used to specify how to generate the extra bits.
static void getCopyToParts(SelectionDAG &DAG,
- SDOperand Val,
- SDOperand *Parts,
+ SDValue Val,
+ SDValue *Parts,
unsigned NumParts,
MVT PartVT,
ISD::NodeType ExtendKind = ISD::ANY_EXTEND) {
unsigned RoundParts = 1 << Log2_32(NumParts);
unsigned RoundBits = RoundParts * PartBits;
unsigned OddParts = NumParts - RoundParts;
- SDOperand OddVal = DAG.getNode(ISD::SRL, ValueVT, Val,
+ SDValue OddVal = DAG.getNode(ISD::SRL, ValueVT, Val,
DAG.getConstant(RoundBits,
TLI.getShiftAmountTy()));
getCopyToParts(DAG, OddVal, Parts + RoundParts, OddParts, PartVT);
for (unsigned i = 0; i < NumParts; i += StepSize) {
unsigned ThisBits = StepSize * PartBits / 2;
MVT ThisVT = MVT::getIntegerVT (ThisBits);
- SDOperand &Part0 = Parts[i];
- SDOperand &Part1 = Parts[i+StepSize/2];
+ SDValue &Part0 = Parts[i];
+ SDValue &Part1 = Parts[i+StepSize/2];
Part1 = DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Part0,
DAG.getConstant(1, PtrVT));
assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
// Split the vector into intermediate operands.
- SmallVector<SDOperand, 8> Ops(NumIntermediates);
+ SmallVector<SDValue, 8> Ops(NumIntermediates);
for (unsigned i = 0; i != NumIntermediates; ++i)
if (IntermediateVT.isVector())
Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
}
-SDOperand SelectionDAGLowering::getValue(const Value *V) {
- SDOperand &N = NodeMap[V];
+SDValue SelectionDAGLowering::getValue(const Value *V) {
+ SDValue &N = NodeMap[V];
if (N.Val) return N;
if (Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V))) {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
visit(CE->getOpcode(), *CE);
- SDOperand N1 = NodeMap[V];
+ SDValue N1 = NodeMap[V];
assert(N1.Val && "visit didn't populate the ValueMap!");
return N1;
}
if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) {
- SmallVector<SDOperand, 4> Constants;
- SmallVector<MVT, 4> ValueVTs;
+ SmallVector<SDValue, 4> Constants;
for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end();
OI != OE; ++OI) {
SDNode *Val = getValue(*OI).Val;
- for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i) {
- Constants.push_back(SDOperand(Val, i));
- ValueVTs.push_back(Val->getValueType(i));
- }
+ for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i)
+ Constants.push_back(SDValue(Val, i));
}
- return DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Constants[0], Constants.size());
+ return DAG.getMergeValues(&Constants[0], Constants.size());
}
- if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
+ if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType())) {
assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
- "Unknown array constant!");
- unsigned NumElts = ATy->getNumElements();
- if (NumElts == 0)
- return SDOperand(); // empty array
- MVT EltVT = TLI.getValueType(ATy->getElementType());
- SmallVector<SDOperand, 4> Constants(NumElts);
- SmallVector<MVT, 4> ValueVTs(NumElts, EltVT);
- for (unsigned i = 0, e = NumElts; i != e; ++i) {
- if (isa<UndefValue>(C))
- Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
- else if (EltVT.isFloatingPoint())
- Constants[i] = DAG.getConstantFP(0, EltVT);
- else
- Constants[i] = DAG.getConstant(0, EltVT);
- }
- return DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Constants[0], Constants.size());
- }
+ "Unknown struct or array constant!");
- if (const StructType *STy = dyn_cast<StructType>(C->getType())) {
- assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
- "Unknown struct constant!");
- unsigned NumElts = STy->getNumElements();
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(TLI, C->getType(), ValueVTs);
+ unsigned NumElts = ValueVTs.size();
if (NumElts == 0)
- return SDOperand(); // empty struct
- SmallVector<SDOperand, 4> Constants(NumElts);
- SmallVector<MVT, 4> ValueVTs(NumElts);
- for (unsigned i = 0, e = NumElts; i != e; ++i) {
- MVT EltVT = TLI.getValueType(STy->getElementType(i));
- ValueVTs[i] = EltVT;
+ return SDValue(); // empty struct
+ SmallVector<SDValue, 4> Constants(NumElts);
+ for (unsigned i = 0; i != NumElts; ++i) {
+ MVT EltVT = ValueVTs[i];
if (isa<UndefValue>(C))
Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
else if (EltVT.isFloatingPoint())
else
Constants[i] = DAG.getConstant(0, EltVT);
}
- return DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Constants[0], Constants.size());
+ return DAG.getMergeValues(&Constants[0], NumElts);
}
const VectorType *VecTy = cast<VectorType>(V->getType());
// Now that we know the number and type of the elements, get that number of
// elements into the Ops array based on what kind of constant it is.
- SmallVector<SDOperand, 16> Ops;
+ SmallVector<SDValue, 16> Ops;
if (ConstantVector *CP = dyn_cast<ConstantVector>(C)) {
for (unsigned i = 0; i != NumElements; ++i)
Ops.push_back(getValue(CP->getOperand(i)));
"Unknown vector constant!");
MVT EltVT = TLI.getValueType(VecTy->getElementType());
- SDOperand Op;
+ SDValue Op;
if (isa<UndefValue>(C))
Op = DAG.getNode(ISD::UNDEF, EltVT);
else if (EltVT.isFloatingPoint())
// If this is a static alloca, generate it as the frameindex instead of
// computation.
if (const AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
- std::map<const AllocaInst*, int>::iterator SI =
+ DenseMap<const AllocaInst*, int>::iterator SI =
FuncInfo.StaticAllocaMap.find(AI);
if (SI != FuncInfo.StaticAllocaMap.end())
return DAG.getFrameIndex(SI->second, TLI.getPointerTy());
assert(InReg && "Value not in map!");
RegsForValue RFV(TLI, InReg, V->getType());
- SDOperand Chain = DAG.getEntryNode();
+ SDValue Chain = DAG.getEntryNode();
return RFV.getCopyFromRegs(DAG, Chain, NULL);
}
return;
}
- SmallVector<SDOperand, 8> NewValues;
+ SmallVector<SDValue, 8> NewValues;
NewValues.push_back(getControlRoot());
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
- SDOperand RetOp = getValue(I.getOperand(i));
- MVT VT = RetOp.getValueType();
-
- // FIXME: C calling convention requires the return type to be promoted to
- // at least 32-bit. But this is not necessary for non-C calling conventions.
- if (VT.isInteger()) {
- MVT MinVT = TLI.getRegisterType(MVT::i32);
- if (VT.bitsLT(MinVT))
- VT = MinVT;
- }
+ SDValue RetOp = getValue(I.getOperand(i));
- unsigned NumParts = TLI.getNumRegisters(VT);
- MVT PartVT = TLI.getRegisterType(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
- ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(TLI, I.getOperand(i)->getType(), ValueVTs);
+ for (unsigned j = 0, f = ValueVTs.size(); j != f; ++j) {
+ MVT VT = ValueVTs[j];
+
+ // FIXME: C calling convention requires the return type to be promoted to
+ // at least 32-bit. But this is not necessary for non-C calling conventions.
+ if (VT.isInteger()) {
+ MVT MinVT = TLI.getRegisterType(MVT::i32);
+ if (VT.bitsLT(MinVT))
+ VT = MinVT;
+ }
- const Function *F = I.getParent()->getParent();
- if (F->paramHasAttr(0, ParamAttr::SExt))
- ExtendKind = ISD::SIGN_EXTEND;
- else if (F->paramHasAttr(0, ParamAttr::ZExt))
- ExtendKind = ISD::ZERO_EXTEND;
+ unsigned NumParts = TLI.getNumRegisters(VT);
+ MVT PartVT = TLI.getRegisterType(VT);
+ SmallVector<SDValue, 4> Parts(NumParts);
+ ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
+
+ const Function *F = I.getParent()->getParent();
+ if (F->paramHasAttr(0, ParamAttr::SExt))
+ ExtendKind = ISD::SIGN_EXTEND;
+ else if (F->paramHasAttr(0, ParamAttr::ZExt))
+ ExtendKind = ISD::ZERO_EXTEND;
- getCopyToParts(DAG, RetOp, &Parts[0], NumParts, PartVT, ExtendKind);
+ getCopyToParts(DAG, SDValue(RetOp.Val, RetOp.getResNo() + j),
+ &Parts[0], NumParts, PartVT, ExtendKind);
- for (unsigned i = 0; i < NumParts; ++i) {
- NewValues.push_back(Parts[i]);
- NewValues.push_back(DAG.getArgFlags(ISD::ArgFlagsTy()));
+ for (unsigned i = 0; i < NumParts; ++i) {
+ NewValues.push_back(Parts[i]);
+ NewValues.push_back(DAG.getArgFlags(ISD::ArgFlagsTy()));
+ }
}
}
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
assert(0 && "Unknown compare instruction");
}
- SelectionDAGISel::CaseBlock CB(Condition, BOp->getOperand(0),
- BOp->getOperand(1), NULL, TBB, FBB, CurBB);
+ CaseBlock CB(Condition, BOp->getOperand(0),
+ BOp->getOperand(1), NULL, TBB, FBB, CurBB);
SwitchCases.push_back(CB);
return;
}
// Create a CaseBlock record representing this branch.
- SelectionDAGISel::CaseBlock CB(ISD::SETEQ, Cond, ConstantInt::getTrue(),
- NULL, TBB, FBB, CurBB);
+ CaseBlock CB(ISD::SETEQ, Cond, ConstantInt::getTrue(),
+ NULL, TBB, FBB, CurBB);
SwitchCases.push_back(CB);
return;
}
// Create TmpBB after CurBB.
MachineFunction::iterator BBI = CurBB;
- MachineBasicBlock *TmpBB = new MachineBasicBlock(CurBB->getBasicBlock());
- CurBB->getParent()->getBasicBlockList().insert(++BBI, TmpBB);
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineBasicBlock *TmpBB = MF.CreateMachineBasicBlock(CurBB->getBasicBlock());
+ CurBB->getParent()->insert(++BBI, TmpBB);
if (Opc == Instruction::Or) {
// Codegen X | Y as:
/// If we should emit this as a bunch of and/or'd together conditions, return
/// false.
static bool
-ShouldEmitAsBranches(const std::vector<SelectionDAGISel::CaseBlock> &Cases) {
+ShouldEmitAsBranches(const std::vector<CaseBlock> &Cases) {
if (Cases.size() != 2) return true;
// If this is two comparisons of the same values or'd or and'd together, they
// Okay, we decided not to do this, remove any inserted MBB's and clear
// SwitchCases.
for (unsigned i = 1, e = SwitchCases.size(); i != e; ++i)
- CurMBB->getParent()->getBasicBlockList().erase(SwitchCases[i].ThisBB);
+ CurMBB->getParent()->erase(SwitchCases[i].ThisBB);
SwitchCases.clear();
}
}
// Create a CaseBlock record representing this branch.
- SelectionDAGISel::CaseBlock CB(ISD::SETEQ, CondVal, ConstantInt::getTrue(),
- NULL, Succ0MBB, Succ1MBB, CurMBB);
+ CaseBlock CB(ISD::SETEQ, CondVal, ConstantInt::getTrue(),
+ NULL, Succ0MBB, Succ1MBB, CurMBB);
// Use visitSwitchCase to actually insert the fast branch sequence for this
// cond branch.
visitSwitchCase(CB);
/// visitSwitchCase - Emits the necessary code to represent a single node in
/// the binary search tree resulting from lowering a switch instruction.
-void SelectionDAGLowering::visitSwitchCase(SelectionDAGISel::CaseBlock &CB) {
- SDOperand Cond;
- SDOperand CondLHS = getValue(CB.CmpLHS);
+void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
+ SDValue Cond;
+ SDValue CondLHS = getValue(CB.CmpLHS);
// Build the setcc now.
if (CB.CmpMHS == NULL) {
if (CB.CmpRHS == ConstantInt::getTrue() && CB.CC == ISD::SETEQ)
Cond = CondLHS;
else if (CB.CmpRHS == ConstantInt::getFalse() && CB.CC == ISD::SETEQ) {
- SDOperand True = DAG.getConstant(1, CondLHS.getValueType());
+ SDValue True = DAG.getConstant(1, CondLHS.getValueType());
Cond = DAG.getNode(ISD::XOR, CondLHS.getValueType(), CondLHS, True);
} else
Cond = DAG.getSetCC(MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
uint64_t Low = cast<ConstantInt>(CB.CmpLHS)->getSExtValue();
uint64_t High = cast<ConstantInt>(CB.CmpRHS)->getSExtValue();
- SDOperand CmpOp = getValue(CB.CmpMHS);
+ SDValue CmpOp = getValue(CB.CmpMHS);
MVT VT = CmpOp.getValueType();
if (cast<ConstantInt>(CB.CmpLHS)->isMinValue(true)) {
Cond = DAG.getSetCC(MVT::i1, CmpOp, DAG.getConstant(High, VT), ISD::SETLE);
} else {
- SDOperand SUB = DAG.getNode(ISD::SUB, VT, CmpOp, DAG.getConstant(Low, VT));
+ SDValue SUB = DAG.getNode(ISD::SUB, VT, CmpOp, DAG.getConstant(Low, VT));
Cond = DAG.getSetCC(MVT::i1, SUB,
DAG.getConstant(High-Low, VT), ISD::SETULE);
}
// fall through to the lhs instead of the rhs block.
if (CB.TrueBB == NextBlock) {
std::swap(CB.TrueBB, CB.FalseBB);
- SDOperand True = DAG.getConstant(1, Cond.getValueType());
+ SDValue True = DAG.getConstant(1, Cond.getValueType());
Cond = DAG.getNode(ISD::XOR, Cond.getValueType(), Cond, True);
}
- SDOperand BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(), Cond,
+ SDValue BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(), Cond,
DAG.getBasicBlock(CB.TrueBB));
- if (CB.FalseBB == NextBlock)
+
+ // If the branch was constant folded, fix up the CFG.
+ if (BrCond.getOpcode() == ISD::BR) {
+ CurMBB->removeSuccessor(CB.FalseBB);
DAG.setRoot(BrCond);
- else
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond,
- DAG.getBasicBlock(CB.FalseBB)));
+ } else {
+ // Otherwise, go ahead and insert the false branch.
+ if (BrCond == getControlRoot())
+ CurMBB->removeSuccessor(CB.TrueBB);
+
+ if (CB.FalseBB == NextBlock)
+ DAG.setRoot(BrCond);
+ else
+ DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond,
+ DAG.getBasicBlock(CB.FalseBB)));
+ }
}
/// visitJumpTable - Emit JumpTable node in the current MBB
-void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) {
+void SelectionDAGLowering::visitJumpTable(JumpTable &JT) {
// Emit the code for the jump table
assert(JT.Reg != -1U && "Should lower JT Header first!");
MVT PTy = TLI.getPointerTy();
- SDOperand Index = DAG.getCopyFromReg(getControlRoot(), JT.Reg, PTy);
- SDOperand Table = DAG.getJumpTable(JT.JTI, PTy);
+ SDValue Index = DAG.getCopyFromReg(getControlRoot(), JT.Reg, PTy);
+ SDValue Table = DAG.getJumpTable(JT.JTI, PTy);
DAG.setRoot(DAG.getNode(ISD::BR_JT, MVT::Other, Index.getValue(1),
Table, Index));
return;
/// visitJumpTableHeader - This function emits necessary code to produce index
/// in the JumpTable from switch case.
-void SelectionDAGLowering::visitJumpTableHeader(SelectionDAGISel::JumpTable &JT,
- SelectionDAGISel::JumpTableHeader &JTH) {
+void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT,
+ JumpTableHeader &JTH) {
// Subtract the lowest switch case value from the value being switched on
// and conditional branch to default mbb if the result is greater than the
// difference between smallest and largest cases.
- SDOperand SwitchOp = getValue(JTH.SValue);
+ SDValue SwitchOp = getValue(JTH.SValue);
MVT VT = SwitchOp.getValueType();
- SDOperand SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
+ SDValue SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
DAG.getConstant(JTH.First, VT));
// The SDNode we just created, which holds the value being switched on
SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy());
- SDOperand CopyTo = DAG.getCopyToReg(getControlRoot(), JumpTableReg, SwitchOp);
+ SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), JumpTableReg, SwitchOp);
JT.Reg = JumpTableReg;
// Emit the range check for the jump table, and branch to the default
// block for the switch statement if the value being switched on exceeds
// the largest case in the switch.
- SDOperand CMP = DAG.getSetCC(TLI.getSetCCResultType(SUB), SUB,
+ SDValue CMP = DAG.getSetCC(TLI.getSetCCResultType(SUB), SUB,
DAG.getConstant(JTH.Last-JTH.First,VT),
ISD::SETUGT);
if (++BBI != CurMBB->getParent()->end())
NextBlock = BBI;
- SDOperand BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, CMP,
+ SDValue BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, CMP,
DAG.getBasicBlock(JT.Default));
if (JT.MBB == NextBlock)
/// visitBitTestHeader - This function emits necessary code to produce value
/// suitable for "bit tests"
-void SelectionDAGLowering::visitBitTestHeader(SelectionDAGISel::BitTestBlock &B) {
+void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) {
// Subtract the minimum value
- SDOperand SwitchOp = getValue(B.SValue);
+ SDValue SwitchOp = getValue(B.SValue);
MVT VT = SwitchOp.getValueType();
- SDOperand SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
+ SDValue SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
DAG.getConstant(B.First, VT));
// Check range
- SDOperand RangeCmp = DAG.getSetCC(TLI.getSetCCResultType(SUB), SUB,
+ SDValue RangeCmp = DAG.getSetCC(TLI.getSetCCResultType(SUB), SUB,
DAG.getConstant(B.Range, VT),
ISD::SETUGT);
- SDOperand ShiftOp;
+ SDValue ShiftOp;
if (VT.bitsGT(TLI.getShiftAmountTy()))
ShiftOp = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), SUB);
else
ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), SUB);
// Make desired shift
- SDOperand SwitchVal = DAG.getNode(ISD::SHL, TLI.getPointerTy(),
+ SDValue SwitchVal = DAG.getNode(ISD::SHL, TLI.getPointerTy(),
DAG.getConstant(1, TLI.getPointerTy()),
ShiftOp);
unsigned SwitchReg = FuncInfo.MakeReg(TLI.getPointerTy());
- SDOperand CopyTo = DAG.getCopyToReg(getControlRoot(), SwitchReg, SwitchVal);
+ SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), SwitchReg, SwitchVal);
B.Reg = SwitchReg;
// Set NextBlock to be the MBB immediately after the current one, if any.
CurMBB->addSuccessor(B.Default);
CurMBB->addSuccessor(MBB);
- SDOperand BrRange = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, RangeCmp,
+ SDValue BrRange = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, RangeCmp,
DAG.getBasicBlock(B.Default));
if (MBB == NextBlock)
/// visitBitTestCase - this function produces one "bit test"
void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
unsigned Reg,
- SelectionDAGISel::BitTestCase &B) {
+ BitTestCase &B) {
// Emit bit tests and jumps
- SDOperand SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg,
+ SDValue SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg,
TLI.getPointerTy());
- SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(), SwitchVal,
+ SDValue AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(), SwitchVal,
DAG.getConstant(B.Mask, TLI.getPointerTy()));
- SDOperand AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp), AndOp,
+ SDValue AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp), AndOp,
DAG.getConstant(0, TLI.getPointerTy()),
ISD::SETNE);
CurMBB->addSuccessor(B.TargetBB);
CurMBB->addSuccessor(NextMBB);
- SDOperand BrAnd = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(),
+ SDValue BrAnd = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(),
AndCmp, DAG.getBasicBlock(B.TargetBB));
// Set NextBlock to be the MBB immediately after the current one, if any.
for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I) {
MachineBasicBlock *FallThrough;
if (I != E-1) {
- FallThrough = new MachineBasicBlock(CurBlock->getBasicBlock());
- CurMF->getBasicBlockList().insert(BBI, FallThrough);
+ FallThrough = CurMF->CreateMachineBasicBlock(CurBlock->getBasicBlock());
+ CurMF->insert(BBI, FallThrough);
} else {
// If the last case doesn't match, go to the default block.
FallThrough = Default;
CC = ISD::SETLE;
LHS = I->Low; MHS = SV; RHS = I->High;
}
- SelectionDAGISel::CaseBlock CB(CC, LHS, RHS, MHS,
- I->BB, FallThrough, CurBlock);
+ CaseBlock CB(CC, LHS, RHS, MHS, I->BB, FallThrough, CurBlock);
// If emitting the first comparison, just call visitSwitchCase to emit the
// code into the current block. Otherwise, push the CaseBlock onto the
}
static inline bool areJTsAllowed(const TargetLowering &TLI) {
- return (TLI.isOperationLegal(ISD::BR_JT, MVT::Other) ||
- TLI.isOperationLegal(ISD::BRIND, MVT::Other));
+ return !DisableJumpTables &&
+ (TLI.isOperationLegal(ISD::BR_JT, MVT::Other) ||
+ TLI.isOperationLegal(ISD::BRIND, MVT::Other));
}
/// handleJTSwitchCase - Emit jumptable for current switch case range
// of the jump table, and jumping to it. Update successor information;
// we will either branch to the default case for the switch, or the jump
// table.
- MachineBasicBlock *JumpTableBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, JumpTableBB);
+ MachineBasicBlock *JumpTableBB = CurMF->CreateMachineBasicBlock(LLVMBB);
+ CurMF->insert(BBI, JumpTableBB);
CR.CaseBB->addSuccessor(Default);
CR.CaseBB->addSuccessor(JumpTableBB);
// Set the jump table information so that we can codegen it as a second
// MachineBasicBlock
- SelectionDAGISel::JumpTable JT(-1U, JTI, JumpTableBB, Default);
- SelectionDAGISel::JumpTableHeader JTH(First, Last, SV, CR.CaseBB,
- (CR.CaseBB == CurMBB));
+ JumpTable JT(-1U, JTI, JumpTableBB, Default);
+ JumpTableHeader JTH(First, Last, SV, CR.CaseBB, (CR.CaseBB == CurMBB));
if (CR.CaseBB == CurMBB)
visitJumpTableHeader(JT, JTH);
- JTCases.push_back(SelectionDAGISel::JumpTableBlock(JTH, JT));
+ JTCases.push_back(JumpTableBlock(JTH, JT));
return true;
}
(cast<ConstantInt>(CR.GE)->getSExtValue() + 1LL)) {
TrueBB = LHSR.first->BB;
} else {
- TrueBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, TrueBB);
+ TrueBB = CurMF->CreateMachineBasicBlock(LLVMBB);
+ CurMF->insert(BBI, TrueBB);
WorkList.push_back(CaseRec(TrueBB, C, CR.GE, LHSR));
}
(cast<ConstantInt>(CR.LT)->getSExtValue() - 1LL)) {
FalseBB = RHSR.first->BB;
} else {
- FalseBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, FalseBB);
+ FalseBB = CurMF->CreateMachineBasicBlock(LLVMBB);
+ CurMF->insert(BBI, FalseBB);
WorkList.push_back(CaseRec(FalseBB,CR.LT,C,RHSR));
}
// Create a CaseBlock record representing a conditional branch to
// the LHS node if the value being switched on SV is less than C.
// Otherwise, branch to LHS.
- SelectionDAGISel::CaseBlock CB(ISD::SETLT, SV, C, NULL,
- TrueBB, FalseBB, CR.CaseBB);
+ CaseBlock CB(ISD::SETLT, SV, C, NULL, TrueBB, FalseBB, CR.CaseBB);
if (CR.CaseBB == CurMBB)
visitSwitchCase(CB);
}
std::sort(CasesBits.begin(), CasesBits.end(), CaseBitsCmp());
- SelectionDAGISel::BitTestInfo BTC;
+ BitTestInfo BTC;
// Figure out which block is immediately after the current one.
MachineFunction::iterator BBI = CR.CaseBB;
DOUT << "Mask: " << CasesBits[i].Mask << ", Bits: " << CasesBits[i].Bits
<< ", BB: " << CasesBits[i].BB << "\n";
- MachineBasicBlock *CaseBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, CaseBB);
- BTC.push_back(SelectionDAGISel::BitTestCase(CasesBits[i].Mask,
- CaseBB,
- CasesBits[i].BB));
+ MachineBasicBlock *CaseBB = CurMF->CreateMachineBasicBlock(LLVMBB);
+ CurMF->insert(BBI, CaseBB);
+ BTC.push_back(BitTestCase(CasesBits[i].Mask,
+ CaseBB,
+ CasesBits[i].BB));
}
- SelectionDAGISel::BitTestBlock BTB(lowBound, range, SV,
- -1U, (CR.CaseBB == CurMBB),
- CR.CaseBB, Default, BTC);
+ BitTestBlock BTB(lowBound, range, SV,
+ -1U, (CR.CaseBB == CurMBB),
+ CR.CaseBB, Default, BTC);
if (CR.CaseBB == CurMBB)
visitBitTestHeader(BTB);
std::vector<Constant*> NZ(VL, ConstantFP::getNegativeZero(ElTy));
Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size());
if (CV == CNZ) {
- SDOperand Op2 = getValue(I.getOperand(1));
+ SDValue Op2 = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
return;
}
if (Ty->isFloatingPoint()) {
if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) {
- SDOperand Op2 = getValue(I.getOperand(1));
+ SDValue Op2 = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
return;
}
}
void SelectionDAGLowering::visitBinary(User &I, unsigned OpCode) {
- SDOperand Op1 = getValue(I.getOperand(0));
- SDOperand Op2 = getValue(I.getOperand(1));
+ SDValue Op1 = getValue(I.getOperand(0));
+ SDValue Op2 = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(OpCode, Op1.getValueType(), Op1, Op2));
}
void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
- SDOperand Op1 = getValue(I.getOperand(0));
- SDOperand Op2 = getValue(I.getOperand(1));
-
- if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
- Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
- else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
- Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
+ SDValue Op1 = getValue(I.getOperand(0));
+ SDValue Op2 = getValue(I.getOperand(1));
+ if (!isa<VectorType>(I.getType())) {
+ if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
+ Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
+ else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
+ Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
+ }
setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
}
predicate = IC->getPredicate();
else if (ConstantExpr *IC = dyn_cast<ConstantExpr>(&I))
predicate = ICmpInst::Predicate(IC->getPredicate());
- SDOperand Op1 = getValue(I.getOperand(0));
- SDOperand Op2 = getValue(I.getOperand(1));
+ SDValue Op1 = getValue(I.getOperand(0));
+ SDValue Op2 = getValue(I.getOperand(1));
ISD::CondCode Opcode;
switch (predicate) {
case ICmpInst::ICMP_EQ : Opcode = ISD::SETEQ; break;
predicate = FC->getPredicate();
else if (ConstantExpr *FC = dyn_cast<ConstantExpr>(&I))
predicate = FCmpInst::Predicate(FC->getPredicate());
- SDOperand Op1 = getValue(I.getOperand(0));
- SDOperand Op2 = getValue(I.getOperand(1));
+ SDValue Op1 = getValue(I.getOperand(0));
+ SDValue Op2 = getValue(I.getOperand(1));
ISD::CondCode Condition, FOC, FPC;
switch (predicate) {
case FCmpInst::FCMP_FALSE: FOC = FPC = ISD::SETFALSE; break;
predicate = IC->getPredicate();
else if (ConstantExpr *IC = dyn_cast<ConstantExpr>(&I))
predicate = ICmpInst::Predicate(IC->getPredicate());
- SDOperand Op1 = getValue(I.getOperand(0));
- SDOperand Op2 = getValue(I.getOperand(1));
+ SDValue Op1 = getValue(I.getOperand(0));
+ SDValue Op2 = getValue(I.getOperand(1));
ISD::CondCode Opcode;
switch (predicate) {
case ICmpInst::ICMP_EQ : Opcode = ISD::SETEQ; break;
predicate = FC->getPredicate();
else if (ConstantExpr *FC = dyn_cast<ConstantExpr>(&I))
predicate = FCmpInst::Predicate(FC->getPredicate());
- SDOperand Op1 = getValue(I.getOperand(0));
- SDOperand Op2 = getValue(I.getOperand(1));
+ SDValue Op1 = getValue(I.getOperand(0));
+ SDValue Op2 = getValue(I.getOperand(1));
ISD::CondCode Condition, FOC, FPC;
switch (predicate) {
case FCmpInst::FCMP_FALSE: FOC = FPC = ISD::SETFALSE; break;
}
void SelectionDAGLowering::visitSelect(User &I) {
- SDOperand Cond = getValue(I.getOperand(0));
- SDOperand TrueVal = getValue(I.getOperand(1));
- SDOperand FalseVal = getValue(I.getOperand(2));
+ SDValue Cond = getValue(I.getOperand(0));
+ SDValue TrueVal = getValue(I.getOperand(1));
+ SDValue FalseVal = getValue(I.getOperand(2));
setValue(&I, DAG.getNode(ISD::SELECT, TrueVal.getValueType(), Cond,
TrueVal, FalseVal));
}
void SelectionDAGLowering::visitTrunc(User &I) {
// TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest).
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
}
void SelectionDAGLowering::visitZExt(User &I) {
// ZExt cannot be a no-op cast because sizeof(src) < sizeof(dest).
// ZExt also can't be a cast to bool for same reason. So, nothing much to do
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N));
}
void SelectionDAGLowering::visitSExt(User &I) {
// SExt cannot be a no-op cast because sizeof(src) < sizeof(dest).
// SExt also can't be a cast to bool for same reason. So, nothing much to do
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DestVT, N));
}
void SelectionDAGLowering::visitFPTrunc(User &I) {
// FPTrunc is never a no-op cast, no need to check
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N, DAG.getIntPtrConstant(0)));
}
void SelectionDAGLowering::visitFPExt(User &I){
// FPTrunc is never a no-op cast, no need to check
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::FP_EXTEND, DestVT, N));
}
void SelectionDAGLowering::visitFPToUI(User &I) {
// FPToUI is never a no-op cast, no need to check
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DestVT, N));
}
void SelectionDAGLowering::visitFPToSI(User &I) {
// FPToSI is never a no-op cast, no need to check
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DestVT, N));
}
void SelectionDAGLowering::visitUIToFP(User &I) {
// UIToFP is never a no-op cast, no need to check
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DestVT, N));
}
void SelectionDAGLowering::visitSIToFP(User &I){
// UIToFP is never a no-op cast, no need to check
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DestVT, N));
}
void SelectionDAGLowering::visitPtrToInt(User &I) {
// What to do depends on the size of the integer and the size of the pointer.
// We can either truncate, zero extend, or no-op, accordingly.
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT SrcVT = N.getValueType();
MVT DestVT = TLI.getValueType(I.getType());
- SDOperand Result;
+ SDValue Result;
if (DestVT.bitsLT(SrcVT))
Result = DAG.getNode(ISD::TRUNCATE, DestVT, N);
else
void SelectionDAGLowering::visitIntToPtr(User &I) {
// What to do depends on the size of the integer and the size of the pointer.
// We can either truncate, zero extend, or no-op, accordingly.
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT SrcVT = N.getValueType();
MVT DestVT = TLI.getValueType(I.getType());
if (DestVT.bitsLT(SrcVT))
}
void SelectionDAGLowering::visitBitCast(User &I) {
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
// BitCast assures us that source and destination are the same size so this
}
void SelectionDAGLowering::visitInsertElement(User &I) {
- SDOperand InVec = getValue(I.getOperand(0));
- SDOperand InVal = getValue(I.getOperand(1));
- SDOperand InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
+ SDValue InVec = getValue(I.getOperand(0));
+ SDValue InVal = getValue(I.getOperand(1));
+ SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
getValue(I.getOperand(2)));
setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT,
}
void SelectionDAGLowering::visitExtractElement(User &I) {
- SDOperand InVec = getValue(I.getOperand(0));
- SDOperand InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
+ SDValue InVec = getValue(I.getOperand(0));
+ SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
getValue(I.getOperand(1)));
setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
TLI.getValueType(I.getType()), InVec, InIdx));
}
void SelectionDAGLowering::visitShuffleVector(User &I) {
- SDOperand V1 = getValue(I.getOperand(0));
- SDOperand V2 = getValue(I.getOperand(1));
- SDOperand Mask = getValue(I.getOperand(2));
+ SDValue V1 = getValue(I.getOperand(0));
+ SDValue V2 = getValue(I.getOperand(1));
+ SDValue Mask = getValue(I.getOperand(2));
setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE,
TLI.getValueType(I.getType()),
unsigned NumAggValues = AggValueVTs.size();
unsigned NumValValues = ValValueVTs.size();
- SmallVector<SDOperand, 4> Values(NumAggValues);
+ SmallVector<SDValue, 4> Values(NumAggValues);
- SDOperand Agg = getValue(Op0);
- SDOperand Val = getValue(Op1);
+ SDValue Agg = getValue(Op0);
+ SDValue Val = getValue(Op1);
unsigned i = 0;
// Copy the beginning value(s) from the original aggregate.
for (; i != LinearIndex; ++i)
Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
- SDOperand(Agg.Val, Agg.ResNo + i);
+ SDValue(Agg.Val, Agg.getResNo() + i);
// Copy values from the inserted value(s).
for (; i != LinearIndex + NumValValues; ++i)
Values[i] = FromUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
- SDOperand(Val.Val, Val.ResNo + i - LinearIndex);
+ SDValue(Val.Val, Val.getResNo() + i - LinearIndex);
// Copy remaining value(s) from the original aggregate.
for (; i != NumAggValues; ++i)
Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
- SDOperand(Agg.Val, Agg.ResNo + i);
+ SDValue(Agg.Val, Agg.getResNo() + i);
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&AggValueVTs[0], NumAggValues),
- &Values[0], NumAggValues));
+ setValue(&I, DAG.getMergeValues(DAG.getVTList(&AggValueVTs[0], NumAggValues),
+ &Values[0], NumAggValues));
}
void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) {
ComputeValueVTs(TLI, ValTy, ValValueVTs);
unsigned NumValValues = ValValueVTs.size();
- SmallVector<SDOperand, 4> Values(NumValValues);
+ SmallVector<SDValue, 4> Values(NumValValues);
- SDOperand Agg = getValue(Op0);
+ SDValue Agg = getValue(Op0);
// Copy out the selected value(s).
for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i)
Values[i - LinearIndex] =
- OutOfUndef ? DAG.getNode(ISD::UNDEF, Agg.Val->getValueType(i)) :
- SDOperand(Agg.Val, Agg.ResNo + i - LinearIndex);
+ OutOfUndef ? DAG.getNode(ISD::UNDEF, Agg.Val->getValueType(Agg.getResNo() + i)) :
+ SDValue(Agg.Val, Agg.getResNo() + i);
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValValueVTs[0], NumValValues),
- &Values[0], NumValValues));
+ setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValValueVTs[0], NumValValues),
+ &Values[0], NumValValues));
}
void SelectionDAGLowering::visitGetElementPtr(User &I) {
- SDOperand N = getValue(I.getOperand(0));
+ SDValue N = getValue(I.getOperand(0));
const Type *Ty = I.getOperand(0)->getType();
for (GetElementPtrInst::op_iterator OI = I.op_begin()+1, E = I.op_end();
// N = N + Idx * ElementSize;
uint64_t ElementSize = TD->getABITypeSize(Ty);
- SDOperand IdxN = getValue(Idx);
+ SDValue IdxN = getValue(Idx);
// If the index is smaller or larger than intptr_t, truncate or extend
// it.
- if (IdxN.getValueType().bitsLT(N.getValueType())) {
+ if (IdxN.getValueType().bitsLT(N.getValueType()))
IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN);
- } else if (IdxN.getValueType().bitsGT(N.getValueType()))
+ else if (IdxN.getValueType().bitsGT(N.getValueType()))
IdxN = DAG.getNode(ISD::TRUNCATE, N.getValueType(), IdxN);
// If this is a multiply by a power of two, turn it into a shl
// immediately. This is a very common case.
- if (isPowerOf2_64(ElementSize)) {
- unsigned Amt = Log2_64(ElementSize);
- IdxN = DAG.getNode(ISD::SHL, N.getValueType(), IdxN,
- DAG.getConstant(Amt, TLI.getShiftAmountTy()));
- N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN);
- continue;
+ if (ElementSize != 1) {
+ if (isPowerOf2_64(ElementSize)) {
+ unsigned Amt = Log2_64(ElementSize);
+ IdxN = DAG.getNode(ISD::SHL, N.getValueType(), IdxN,
+ DAG.getConstant(Amt, TLI.getShiftAmountTy()));
+ } else {
+ SDValue Scale = DAG.getIntPtrConstant(ElementSize);
+ IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale);
+ }
}
-
- SDOperand Scale = DAG.getIntPtrConstant(ElementSize);
- IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale);
+
N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN);
}
}
std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
I.getAlignment());
- SDOperand AllocSize = getValue(I.getArraySize());
+ SDValue AllocSize = getValue(I.getArraySize());
MVT IntPtr = TLI.getPointerTy();
if (IntPtr.bitsLT(AllocSize.getValueType()))
AllocSize = DAG.getNode(ISD::TRUNCATE, IntPtr, AllocSize);
AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize,
DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1)));
- SDOperand Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) };
+ SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) };
const MVT *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(),
MVT::Other);
- SDOperand DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, VTs, 2, Ops, 3);
+ SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, VTs, 2, Ops, 3);
setValue(&I, DSA);
DAG.setRoot(DSA.getValue(1));
void SelectionDAGLowering::visitLoad(LoadInst &I) {
const Value *SV = I.getOperand(0);
- SDOperand Ptr = getValue(SV);
+ SDValue Ptr = getValue(SV);
const Type *Ty = I.getType();
bool isVolatile = I.isVolatile();
if (NumValues == 0)
return;
- SDOperand Root;
+ SDValue Root;
+ bool ConstantMemory = false;
if (I.isVolatile())
+ // Serialize volatile loads with other side effects.
Root = getRoot();
- else {
+ else if (AA->pointsToConstantMemory(SV)) {
+ // Do not serialize (non-volatile) loads of constant memory with anything.
+ Root = DAG.getEntryNode();
+ ConstantMemory = true;
+ } else {
// Do not serialize non-volatile loads against each other.
Root = DAG.getRoot();
}
- SmallVector<SDOperand, 4> Values(NumValues);
- SmallVector<SDOperand, 4> Chains(NumValues);
+ SmallVector<SDValue, 4> Values(NumValues);
+ SmallVector<SDValue, 4> Chains(NumValues);
MVT PtrVT = Ptr.getValueType();
for (unsigned i = 0; i != NumValues; ++i) {
- SDOperand L = DAG.getLoad(ValueVTs[i], Root,
+ SDValue L = DAG.getLoad(ValueVTs[i], Root,
DAG.getNode(ISD::ADD, PtrVT, Ptr,
DAG.getConstant(Offsets[i], PtrVT)),
SV, Offsets[i],
Chains[i] = L.getValue(1);
}
- SDOperand Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
- &Chains[0], NumValues);
- if (isVolatile)
- DAG.setRoot(Chain);
- else
- PendingLoads.push_back(Chain);
+ if (!ConstantMemory) {
+ SDValue Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
+ &Chains[0], NumValues);
+ if (isVolatile)
+ DAG.setRoot(Chain);
+ else
+ PendingLoads.push_back(Chain);
+ }
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValueVTs[0], NumValues),
- &Values[0], NumValues));
+ setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], NumValues),
+ &Values[0], NumValues));
}
void SelectionDAGLowering::visitStore(StoreInst &I) {
Value *SrcV = I.getOperand(0);
- SDOperand Src = getValue(SrcV);
Value *PtrV = I.getOperand(1);
- SDOperand Ptr = getValue(PtrV);
SmallVector<MVT, 4> ValueVTs;
SmallVector<uint64_t, 4> Offsets;
if (NumValues == 0)
return;
- SDOperand Root = getRoot();
- SmallVector<SDOperand, 4> Chains(NumValues);
+ // Get the lowered operands. Note that we do this after
+ // checking if NumResults is zero, because with zero results
+ // the operands won't have values in the map.
+ SDValue Src = getValue(SrcV);
+ SDValue Ptr = getValue(PtrV);
+
+ SDValue Root = getRoot();
+ SmallVector<SDValue, 4> Chains(NumValues);
MVT PtrVT = Ptr.getValueType();
bool isVolatile = I.isVolatile();
unsigned Alignment = I.getAlignment();
for (unsigned i = 0; i != NumValues; ++i)
- Chains[i] = DAG.getStore(Root, SDOperand(Src.Val, Src.ResNo + i),
+ Chains[i] = DAG.getStore(Root, SDValue(Src.Val, Src.getResNo() + i),
DAG.getNode(ISD::ADD, PtrVT, Ptr,
DAG.getConstant(Offsets[i], PtrVT)),
PtrV, Offsets[i],
bool OnlyLoad = HasChain && I.onlyReadsMemory();
// Build the operand list.
- SmallVector<SDOperand, 8> Ops;
+ SmallVector<SDValue, 8> Ops;
if (HasChain) { // If this intrinsic has side-effects, chainify it.
if (OnlyLoad) {
// We don't need to serialize loads against other loads.
// Add all operands of the call to the operand list.
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
- SDOperand Op = getValue(I.getOperand(i));
+ SDValue Op = getValue(I.getOperand(i));
assert(TLI.isTypeLegal(Op.getValueType()) &&
"Intrinsic uses a non-legal type?");
Ops.push_back(Op);
const MVT *VTList = DAG.getNodeValueTypes(VTs);
// Create the node.
- SDOperand Result;
+ SDValue Result;
if (!HasChain)
Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VTList, VTs.size(),
&Ops[0], Ops.size());
&Ops[0], Ops.size());
if (HasChain) {
- SDOperand Chain = Result.getValue(Result.Val->getNumValues()-1);
+ SDValue Chain = Result.getValue(Result.Val->getNumValues()-1);
if (OnlyLoad)
PendingLoads.push_back(Chain);
else
// Op is the associated NodeType for I
const char *
SelectionDAGLowering::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) {
- SDOperand Root = getRoot();
- SDOperand O2 = getValue(I.getOperand(2));
- SDOperand L = DAG.getAtomic(Op, Root,
+ SDValue Root = getRoot();
+ SDValue L = DAG.getAtomic(Op, Root,
getValue(I.getOperand(1)),
- O2, O2.getValueType());
+ getValue(I.getOperand(2)),
+ I.getOperand(1));
setValue(&I, L);
DAG.setRoot(L.getValue(1));
return 0;
break;
case Intrinsic::memcpy_i32:
case Intrinsic::memcpy_i64: {
- SDOperand Op1 = getValue(I.getOperand(1));
- SDOperand Op2 = getValue(I.getOperand(2));
- SDOperand Op3 = getValue(I.getOperand(3));
+ SDValue Op1 = getValue(I.getOperand(1));
+ SDValue Op2 = getValue(I.getOperand(2));
+ SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
DAG.setRoot(DAG.getMemcpy(getRoot(), Op1, Op2, Op3, Align, false,
I.getOperand(1), 0, I.getOperand(2), 0));
}
case Intrinsic::memset_i32:
case Intrinsic::memset_i64: {
- SDOperand Op1 = getValue(I.getOperand(1));
- SDOperand Op2 = getValue(I.getOperand(2));
- SDOperand Op3 = getValue(I.getOperand(3));
+ SDValue Op1 = getValue(I.getOperand(1));
+ SDValue Op2 = getValue(I.getOperand(2));
+ SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
DAG.setRoot(DAG.getMemset(getRoot(), Op1, Op2, Op3, Align,
I.getOperand(1), 0));
}
case Intrinsic::memmove_i32:
case Intrinsic::memmove_i64: {
- SDOperand Op1 = getValue(I.getOperand(1));
- SDOperand Op2 = getValue(I.getOperand(2));
- SDOperand Op3 = getValue(I.getOperand(3));
+ SDValue Op1 = getValue(I.getOperand(1));
+ SDValue Op2 = getValue(I.getOperand(2));
+ SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
// If the source and destination are known to not be aliases, we can
uint64_t Size = -1ULL;
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op3))
Size = C->getValue();
- if (AA.alias(I.getOperand(1), Size, I.getOperand(2), Size) ==
+ if (AA->alias(I.getOperand(1), Size, I.getOperand(2), Size) ==
AliasAnalysis::NoAlias) {
DAG.setRoot(DAG.getMemcpy(getRoot(), Op1, Op2, Op3, Align, false,
I.getOperand(1), 0, I.getOperand(2), 0));
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
if (MMI && SPI.getContext() && MMI->Verify(SPI.getContext())) {
- SDOperand Ops[5];
-
- Ops[0] = getRoot();
- Ops[1] = getValue(SPI.getLineValue());
- Ops[2] = getValue(SPI.getColumnValue());
-
DebugInfoDesc *DD = MMI->getDescFor(SPI.getContext());
assert(DD && "Not a debug information descriptor");
- CompileUnitDesc *CompileUnit = cast<CompileUnitDesc>(DD);
-
- Ops[3] = DAG.getString(CompileUnit->getFileName());
- Ops[4] = DAG.getString(CompileUnit->getDirectory());
-
- DAG.setRoot(DAG.getNode(ISD::LOCATION, MVT::Other, Ops, 5));
+ DAG.setRoot(DAG.getDbgStopPoint(getRoot(),
+ SPI.getLine(),
+ SPI.getColumn(),
+ cast<CompileUnitDesc>(DD)));
}
return 0;
DbgRegionStartInst &RSI = cast<DbgRegionStartInst>(I);
if (MMI && RSI.getContext() && MMI->Verify(RSI.getContext())) {
unsigned LabelID = MMI->RecordRegionStart(RSI.getContext());
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
- DAG.getConstant(LabelID, MVT::i32),
- DAG.getConstant(0, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
}
return 0;
DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
if (MMI && REI.getContext() && MMI->Verify(REI.getContext())) {
unsigned LabelID = MMI->RecordRegionEnd(REI.getContext());
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
- DAG.getConstant(LabelID, MVT::i32),
- DAG.getConstant(0, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
}
return 0;
assert(DD && "Not a debug information descriptor");
SubprogramDesc *Subprogram = cast<SubprogramDesc>(DD);
const CompileUnitDesc *CompileUnit = Subprogram->getFile();
- unsigned SrcFile = MMI->RecordSource(CompileUnit->getDirectory(),
- CompileUnit->getFileName());
+ unsigned SrcFile = MMI->RecordSource(CompileUnit);
// Record the source line but does create a label. It will be emitted
// at asm emission time.
MMI->RecordSourceLine(Subprogram->getLine(), 0, SrcFile);
}
// Insert the EXCEPTIONADDR instruction.
SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
- SDOperand Ops[1];
+ SDValue Ops[1];
Ops[0] = DAG.getRoot();
- SDOperand Op = DAG.getNode(ISD::EXCEPTIONADDR, VTs, Ops, 1);
+ SDValue Op = DAG.getNode(ISD::EXCEPTIONADDR, VTs, Ops, 1);
setValue(&I, Op);
DAG.setRoot(Op.getValue(1));
return 0;
// Insert the EHSELECTION instruction.
SDVTList VTs = DAG.getVTList(VT, MVT::Other);
- SDOperand Ops[2];
+ SDValue Ops[2];
Ops[0] = getValue(I.getOperand(1));
Ops[1] = getRoot();
- SDOperand Op = DAG.getNode(ISD::EHSELECTION, VTs, Ops, 2);
+ SDValue Op = DAG.getNode(ISD::EHSELECTION, VTs, Ops, 2);
setValue(&I, Op);
DAG.setRoot(Op.getValue(1));
} else {
case Intrinsic::eh_dwarf_cfa: {
MVT VT = getValue(I.getOperand(1)).getValueType();
- SDOperand CfaArg;
+ SDValue CfaArg;
if (VT.bitsGT(TLI.getPointerTy()))
CfaArg = DAG.getNode(ISD::TRUNCATE,
TLI.getPointerTy(), getValue(I.getOperand(1)));
CfaArg = DAG.getNode(ISD::SIGN_EXTEND,
TLI.getPointerTy(), getValue(I.getOperand(1)));
- SDOperand Offset = DAG.getNode(ISD::ADD,
+ SDValue Offset = DAG.getNode(ISD::ADD,
TLI.getPointerTy(),
DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET,
TLI.getPointerTy()),
getValue(I.getOperand(2))));
return 0;
case Intrinsic::pcmarker: {
- SDOperand Tmp = getValue(I.getOperand(1));
+ SDValue Tmp = getValue(I.getOperand(1));
DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp));
return 0;
}
case Intrinsic::readcyclecounter: {
- SDOperand Op = getRoot();
- SDOperand Tmp = DAG.getNode(ISD::READCYCLECOUNTER,
+ SDValue Op = getRoot();
+ SDValue Tmp = DAG.getNode(ISD::READCYCLECOUNTER,
DAG.getNodeValueTypes(MVT::i64, MVT::Other), 2,
&Op, 1);
setValue(&I, Tmp);
getValue(I.getOperand(1))));
return 0;
case Intrinsic::cttz: {
- SDOperand Arg = getValue(I.getOperand(1));
+ SDValue Arg = getValue(I.getOperand(1));
MVT Ty = Arg.getValueType();
- SDOperand result = DAG.getNode(ISD::CTTZ, Ty, Arg);
+ SDValue result = DAG.getNode(ISD::CTTZ, Ty, Arg);
setValue(&I, result);
return 0;
}
case Intrinsic::ctlz: {
- SDOperand Arg = getValue(I.getOperand(1));
+ SDValue Arg = getValue(I.getOperand(1));
MVT Ty = Arg.getValueType();
- SDOperand result = DAG.getNode(ISD::CTLZ, Ty, Arg);
+ SDValue result = DAG.getNode(ISD::CTLZ, Ty, Arg);
setValue(&I, result);
return 0;
}
case Intrinsic::ctpop: {
- SDOperand Arg = getValue(I.getOperand(1));
+ SDValue Arg = getValue(I.getOperand(1));
MVT Ty = Arg.getValueType();
- SDOperand result = DAG.getNode(ISD::CTPOP, Ty, Arg);
+ SDValue result = DAG.getNode(ISD::CTPOP, Ty, Arg);
setValue(&I, result);
return 0;
}
case Intrinsic::stacksave: {
- SDOperand Op = getRoot();
- SDOperand Tmp = DAG.getNode(ISD::STACKSAVE,
+ SDValue Op = getRoot();
+ SDValue Tmp = DAG.getNode(ISD::STACKSAVE,
DAG.getNodeValueTypes(TLI.getPointerTy(), MVT::Other), 2, &Op, 1);
setValue(&I, Tmp);
DAG.setRoot(Tmp.getValue(1));
return 0;
}
case Intrinsic::stackrestore: {
- SDOperand Tmp = getValue(I.getOperand(1));
+ SDValue Tmp = getValue(I.getOperand(1));
DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, MVT::Other, getRoot(), Tmp));
return 0;
}
case Intrinsic::init_trampoline: {
const Function *F = cast<Function>(I.getOperand(2)->stripPointerCasts());
- SDOperand Ops[6];
+ SDValue Ops[6];
Ops[0] = getRoot();
Ops[1] = getValue(I.getOperand(1));
Ops[2] = getValue(I.getOperand(2));
Ops[4] = DAG.getSrcValue(I.getOperand(1));
Ops[5] = DAG.getSrcValue(F);
- SDOperand Tmp = DAG.getNode(ISD::TRAMPOLINE,
+ SDValue Tmp = DAG.getNode(ISD::TRAMPOLINE,
DAG.getNodeValueTypes(TLI.getPointerTy(),
MVT::Other), 2,
Ops, 6);
}
case Intrinsic::gcroot:
- if (GCI) {
+ if (GFI) {
Value *Alloca = I.getOperand(1);
Constant *TypeMap = cast<Constant>(I.getOperand(2));
FrameIndexSDNode *FI = cast<FrameIndexSDNode>(getValue(Alloca).Val);
- GCI->addStackRoot(FI->getIndex(), TypeMap);
+ GFI->addStackRoot(FI->getIndex(), TypeMap);
}
return 0;
case Intrinsic::gcread:
case Intrinsic::gcwrite:
- assert(0 && "Collector failed to lower gcread/gcwrite intrinsics!");
+ assert(0 && "GC failed to lower gcread/gcwrite intrinsics!");
return 0;
case Intrinsic::flt_rounds: {
return 0;
}
case Intrinsic::prefetch: {
- SDOperand Ops[4];
+ SDValue Ops[4];
Ops[0] = getRoot();
Ops[1] = getValue(I.getOperand(1));
Ops[2] = getValue(I.getOperand(2));
}
case Intrinsic::memory_barrier: {
- SDOperand Ops[6];
+ SDValue Ops[6];
Ops[0] = getRoot();
for (int x = 1; x < 6; ++x)
Ops[x] = getValue(I.getOperand(x));
DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, MVT::Other, &Ops[0], 6));
return 0;
}
- case Intrinsic::atomic_lcs: {
- SDOperand Root = getRoot();
- SDOperand O3 = getValue(I.getOperand(3));
- SDOperand L = DAG.getAtomic(ISD::ATOMIC_LCS, Root,
- getValue(I.getOperand(1)),
- getValue(I.getOperand(2)),
- O3, O3.getValueType());
+ case Intrinsic::atomic_cmp_swap: {
+ SDValue Root = getRoot();
+ SDValue L;
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ L = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP_8, Root,
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2)),
+ getValue(I.getOperand(3)),
+ I.getOperand(1));
+ break;
+ case MVT::i16:
+ L = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP_16, Root,
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2)),
+ getValue(I.getOperand(3)),
+ I.getOperand(1));
+ break;
+ case MVT::i32:
+ L = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP_32, Root,
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2)),
+ getValue(I.getOperand(3)),
+ I.getOperand(1));
+ break;
+ case MVT::i64:
+ L = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP_64, Root,
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2)),
+ getValue(I.getOperand(3)),
+ I.getOperand(1));
+ break;
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
setValue(&I, L);
DAG.setRoot(L.getValue(1));
return 0;
}
- case Intrinsic::atomic_las:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LAS);
- case Intrinsic::atomic_lss:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LSS);
- case Intrinsic::atomic_load_and:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND);
+ case Intrinsic::atomic_load_add:
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_ADD_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_ADD_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_ADD_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_ADD_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
+ case Intrinsic::atomic_load_sub:
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_SUB_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_SUB_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_SUB_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_SUB_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
case Intrinsic::atomic_load_or:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR);
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
case Intrinsic::atomic_load_xor:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR);
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
+ case Intrinsic::atomic_load_and:
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
case Intrinsic::atomic_load_nand:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND);
- case Intrinsic::atomic_load_min:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN);
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
case Intrinsic::atomic_load_max:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MAX);
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MAX_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MAX_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MAX_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MAX_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
+ case Intrinsic::atomic_load_min:
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
case Intrinsic::atomic_load_umin:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMIN);
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMIN_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMIN_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMIN_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMIN_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
case Intrinsic::atomic_load_umax:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX);
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
case Intrinsic::atomic_swap:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP);
+ switch (getValue(I.getOperand(2)).getValueType().getSimpleVT()) {
+ case MVT::i8:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP_8);
+ case MVT::i16:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP_16);
+ case MVT::i32:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP_32);
+ case MVT::i64:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP_64);
+ default:
+ assert(0 && "Invalid atomic type");
+ abort();
+ }
}
}
-void SelectionDAGLowering::LowerCallTo(CallSite CS, SDOperand Callee,
+void SelectionDAGLowering::LowerCallTo(CallSite CS, SDValue Callee,
bool IsTailCall,
MachineBasicBlock *LandingPad) {
const PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
Args.reserve(CS.arg_size());
for (CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
i != e; ++i) {
- SDOperand ArgNode = getValue(*i);
+ SDValue ArgNode = getValue(*i);
Entry.Node = ArgNode; Entry.Ty = (*i)->getType();
unsigned attrInd = i - CS.arg_begin() + 1;
// Both PendingLoads and PendingExports must be flushed here;
// this call might not return.
(void)getRoot();
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getControlRoot(),
- DAG.getConstant(BeginLabel, MVT::i32),
- DAG.getConstant(1, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, getControlRoot(), BeginLabel));
}
- std::pair<SDOperand,SDOperand> Result =
+ std::pair<SDValue,SDValue> Result =
TLI.LowerCallTo(getRoot(), CS.getType(),
CS.paramHasAttr(0, ParamAttr::SExt),
CS.paramHasAttr(0, ParamAttr::ZExt),
// Insert a label at the end of the invoke call to mark the try range. This
// can be used to detect deletion of the invoke via the MachineModuleInfo.
EndLabel = MMI->NextLabelID();
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
- DAG.getConstant(EndLabel, MVT::i32),
- DAG.getConstant(1, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, getRoot(), EndLabel));
// Inform MachineModuleInfo of range.
MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
I.getOperand(1)->getType()->isFloatingPoint() &&
I.getType() == I.getOperand(1)->getType() &&
I.getType() == I.getOperand(2)->getType()) {
- SDOperand LHS = getValue(I.getOperand(1));
- SDOperand RHS = getValue(I.getOperand(2));
+ SDValue LHS = getValue(I.getOperand(1));
+ SDValue RHS = getValue(I.getOperand(2));
setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(),
LHS, RHS));
return;
if (I.getNumOperands() == 2 && // Basic sanity checks.
I.getOperand(1)->getType()->isFloatingPoint() &&
I.getType() == I.getOperand(1)->getType()) {
- SDOperand Tmp = getValue(I.getOperand(1));
+ SDValue Tmp = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp));
return;
}
if (I.getNumOperands() == 2 && // Basic sanity checks.
I.getOperand(1)->getType()->isFloatingPoint() &&
I.getType() == I.getOperand(1)->getType()) {
- SDOperand Tmp = getValue(I.getOperand(1));
+ SDValue Tmp = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp));
return;
}
if (I.getNumOperands() == 2 && // Basic sanity checks.
I.getOperand(1)->getType()->isFloatingPoint() &&
I.getType() == I.getOperand(1)->getType()) {
- SDOperand Tmp = getValue(I.getOperand(1));
+ SDValue Tmp = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp));
return;
}
return;
}
- SDOperand Callee;
+ SDValue Callee;
if (!RenameFn)
Callee = getValue(I.getOperand(0));
else
}
-void SelectionDAGLowering::visitGetResult(GetResultInst &I) {
- if (isa<UndefValue>(I.getOperand(0))) {
- SDOperand Undef = DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()));
- setValue(&I, Undef);
- return;
- }
-
- // To add support for individual return values with aggregate types,
- // we'd need a way to take a getresult index and determine which
- // values of the Call SDNode are associated with it.
- assert(TLI.getValueType(I.getType(), true) != MVT::Other &&
- "Individual return values must not be aggregates!");
-
- SDOperand Call = getValue(I.getOperand(0));
- setValue(&I, SDOperand(Call.Val, I.getIndex()));
-}
-
-
/// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
/// this value and returns the result as a ValueVT value. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
-SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
- SDOperand &Chain,
- SDOperand *Flag) const {
+SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
+ SDValue &Chain,
+ SDValue *Flag) const {
// Assemble the legal parts into the final values.
- SmallVector<SDOperand, 4> Values(ValueVTs.size());
- SmallVector<SDOperand, 8> Parts;
+ SmallVector<SDValue, 4> Values(ValueVTs.size());
+ SmallVector<SDValue, 8> Parts;
for (unsigned Value = 0, Part = 0, e = ValueVTs.size(); Value != e; ++Value) {
// Copy the legal parts from the registers.
MVT ValueVT = ValueVTs[Value];
Parts.resize(NumRegs);
for (unsigned i = 0; i != NumRegs; ++i) {
- SDOperand P;
+ SDValue P;
if (Flag == 0)
P = DAG.getCopyFromReg(Chain, Regs[Part+i], RegisterVT);
else {
}
}
- Parts[Part+i] = P;
+ Parts[i] = P;
}
- Values[Value] = getCopyFromParts(DAG, &Parts[Part], NumRegs, RegisterVT,
+ Values[Value] = getCopyFromParts(DAG, Parts.begin(), NumRegs, RegisterVT,
ValueVT);
Part += NumRegs;
+ Parts.clear();
}
-
- if (ValueVTs.size() == 1)
- return Values[0];
-
- return DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Values[0], ValueVTs.size());
+
+ return DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
+ &Values[0], ValueVTs.size());
}
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
/// specified value into the registers specified by this object. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
-void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
- SDOperand &Chain, SDOperand *Flag) const {
+void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG,
+ SDValue &Chain, SDValue *Flag) const {
// Get the list of the values's legal parts.
unsigned NumRegs = Regs.size();
- SmallVector<SDOperand, 8> Parts(NumRegs);
+ SmallVector<SDValue, 8> Parts(NumRegs);
for (unsigned Value = 0, Part = 0, e = ValueVTs.size(); Value != e; ++Value) {
MVT ValueVT = ValueVTs[Value];
unsigned NumParts = TLI->getNumRegisters(ValueVT);
MVT RegisterVT = RegVTs[Value];
- getCopyToParts(DAG, Val.getValue(Val.ResNo + Value),
+ getCopyToParts(DAG, Val.getValue(Val.getResNo() + Value),
&Parts[Part], NumParts, RegisterVT);
Part += NumParts;
}
// Copy the parts into the registers.
- SmallVector<SDOperand, 8> Chains(NumRegs);
+ SmallVector<SDValue, 8> Chains(NumRegs);
for (unsigned i = 0; i != NumRegs; ++i) {
- SDOperand Part;
+ SDValue Part;
if (Flag == 0)
Part = DAG.getCopyToReg(Chain, Regs[i], Parts[i]);
else {
/// operand list. This adds the code marker and includes the number of
/// values added into it.
void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
- std::vector<SDOperand> &Ops) const {
+ std::vector<SDValue> &Ops) const {
MVT IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
Ops.push_back(DAG.getTargetConstant(Code | (Regs.size() << 3), IntPtrTy));
for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) {
/// CallOperand - If this is the result output operand or a clobber
/// this is null, otherwise it is the incoming operand to the CallInst.
/// This gets modified as the asm is processed.
- SDOperand CallOperand;
+ SDValue CallOperand;
/// AssignedRegs - If this is a register or register class operand, this
/// contains the set of register corresponding to the operand.
/// ConstraintOperands - Information about all of the constraints.
std::vector<SDISelAsmOperandInfo> ConstraintOperands;
- SDOperand Chain = getRoot();
- SDOperand Flag;
+ SDValue Chain = getRoot();
+ SDValue Flag;
std::set<unsigned> OutputRegs, InputRegs;
if (!SawEarlyClobber &&
OpInfo.Type == InlineAsm::isClobber &&
OpInfo.ConstraintType == TargetLowering::C_Register) {
- // Note that we want to ignore things that we don't trick here, like
+ // Note that we want to ignore things that we don't track here, like
// dirflag, fpsr, flags, etc.
std::pair<unsigned, const TargetRegisterClass*> PhysReg =
TLI.getRegForInlineAsmConstraint(OpInfo.ConstraintCode,
unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty);
MachineFunction &MF = DAG.getMachineFunction();
int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align);
- SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
+ SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
Chain = DAG.getStore(Chain, OpInfo.CallOperand, StackSlot, NULL, 0);
OpInfo.CallOperand = StackSlot;
}
}
// AsmNodeOperands - The operands for the ISD::INLINEASM node.
- std::vector<SDOperand> AsmNodeOperands;
- AsmNodeOperands.push_back(SDOperand()); // reserve space for input chain
+ std::vector<SDValue> AsmNodeOperands;
+ AsmNodeOperands.push_back(SDValue()); // reserve space for input chain
AsmNodeOperands.push_back(
DAG.getTargetExternalSymbol(IA->getAsmString().c_str(), MVT::Other));
break;
}
case InlineAsm::isInput: {
- SDOperand InOperandVal = OpInfo.CallOperand;
+ SDValue InOperandVal = OpInfo.CallOperand;
if (isdigit(OpInfo.ConstraintCode[0])) { // Matching constraint?
// If this is required to match an output register we have already set,
assert(!OpInfo.isIndirect &&
"Don't know how to handle indirect other inputs yet!");
- std::vector<SDOperand> Ops;
+ std::vector<SDValue> Ops;
TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode[0],
Ops, DAG);
if (Ops.empty()) {
// If this asm returns a register value, copy the result from that register
// and set it as the value of the call.
if (!RetValRegs.Regs.empty()) {
- SDOperand Val = RetValRegs.getCopyFromRegs(DAG, Chain, &Flag);
+ SDValue Val = RetValRegs.getCopyFromRegs(DAG, Chain, &Flag);
// If any of the results of the inline asm is a vector, it may have the
// wrong width/num elts. This can happen for register classes that can
setValue(CS.getInstruction(), Val);
}
- std::vector<std::pair<SDOperand, Value*> > StoresToEmit;
+ std::vector<std::pair<SDValue, Value*> > StoresToEmit;
// Process indirect outputs, first output all of the flagged copies out of
// physregs.
for (unsigned i = 0, e = IndirectStoresToEmit.size(); i != e; ++i) {
RegsForValue &OutRegs = IndirectStoresToEmit[i].first;
Value *Ptr = IndirectStoresToEmit[i].second;
- SDOperand OutVal = OutRegs.getCopyFromRegs(DAG, Chain, &Flag);
+ SDValue OutVal = OutRegs.getCopyFromRegs(DAG, Chain, &Flag);
StoresToEmit.push_back(std::make_pair(OutVal, Ptr));
}
// Emit the non-flagged stores from the physregs.
- SmallVector<SDOperand, 8> OutChains;
+ SmallVector<SDValue, 8> OutChains;
for (unsigned i = 0, e = StoresToEmit.size(); i != e; ++i)
OutChains.push_back(DAG.getStore(Chain, StoresToEmit[i].first,
getValue(StoresToEmit[i].second),
void SelectionDAGLowering::visitMalloc(MallocInst &I) {
- SDOperand Src = getValue(I.getOperand(0));
+ SDValue Src = getValue(I.getOperand(0));
MVT IntPtr = TLI.getPointerTy();
Entry.Ty = TLI.getTargetData()->getIntPtrType();
Args.push_back(Entry);
- std::pair<SDOperand,SDOperand> Result =
+ std::pair<SDValue,SDValue> Result =
TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, CallingConv::C,
true, DAG.getExternalSymbol("malloc", IntPtr), Args, DAG);
setValue(&I, Result.first); // Pointers always fit in registers
Entry.Ty = TLI.getTargetData()->getIntPtrType();
Args.push_back(Entry);
MVT IntPtr = TLI.getPointerTy();
- std::pair<SDOperand,SDOperand> Result =
+ std::pair<SDValue,SDValue> Result =
TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false,
CallingConv::C, true,
DAG.getExternalSymbol("free", IntPtr), Args, DAG);
}
void SelectionDAGLowering::visitVAArg(VAArgInst &I) {
- SDOperand V = DAG.getVAArg(TLI.getValueType(I.getType()), getRoot(),
+ SDValue V = DAG.getVAArg(TLI.getValueType(I.getType()), getRoot(),
getValue(I.getOperand(0)),
DAG.getSrcValue(I.getOperand(0)));
setValue(&I, V);
/// implementation, which just inserts a FORMAL_ARGUMENTS node. FIXME: When all
/// targets are migrated to using FORMAL_ARGUMENTS, this hook should be
/// integrated into SDISel.
-std::vector<SDOperand>
-TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
+void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &ArgValues) {
// Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node.
- std::vector<SDOperand> Ops;
+ SmallVector<SDValue, 3+16> Ops;
Ops.push_back(DAG.getRoot());
Ops.push_back(DAG.getConstant(F.getCallingConv(), getPointerTy()));
Ops.push_back(DAG.getConstant(F.isVarArg(), getPointerTy()));
// Add one result value for each formal argument.
- std::vector<MVT> RetVals;
+ SmallVector<MVT, 16> RetVals;
unsigned j = 1;
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
I != E; ++I, ++j) {
// Prelower FORMAL_ARGUMENTS. This isn't required for functionality, but
// allows exposing the loads that may be part of the argument access to the
// first DAGCombiner pass.
- SDOperand TmpRes = LowerOperation(SDOperand(Result, 0), DAG);
+ SDValue TmpRes = LowerOperation(SDValue(Result, 0), DAG);
// The number of results should match up, except that the lowered one may have
// an extra flag result.
(Result->getNumValues()+1 == TmpRes.Val->getNumValues() &&
TmpRes.getValue(Result->getNumValues()).getValueType() == MVT::Flag))
&& "Lowering produced unexpected number of results!");
+
+ // The FORMAL_ARGUMENTS node itself is likely no longer needed.
+ if (Result != TmpRes.Val && Result->use_empty()) {
+ HandleSDNode Dummy(DAG.getRoot());
+ DAG.RemoveDeadNode(Result);
+ }
+
Result = TmpRes.Val;
unsigned NumArgRegs = Result->getNumValues() - 1;
- DAG.setRoot(SDOperand(Result, NumArgRegs));
+ DAG.setRoot(SDValue(Result, NumArgRegs));
// Set up the return result vector.
- Ops.clear();
unsigned i = 0;
unsigned Idx = 1;
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E;
MVT PartVT = getRegisterType(VT);
unsigned NumParts = getNumRegisters(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
+ SmallVector<SDValue, 4> Parts(NumParts);
for (unsigned j = 0; j != NumParts; ++j)
- Parts[j] = SDOperand(Result, i++);
+ Parts[j] = SDValue(Result, i++);
ISD::NodeType AssertOp = ISD::DELETED_NODE;
if (F.paramHasAttr(Idx, ParamAttr::SExt))
else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
AssertOp = ISD::AssertZext;
- Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
- AssertOp));
+ ArgValues.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
+ AssertOp));
}
}
assert(i == NumArgRegs && "Argument register count mismatch!");
- return Ops;
}
/// implementation, which just inserts an ISD::CALL node, which is later custom
/// lowered by the target to something concrete. FIXME: When all targets are
/// migrated to using ISD::CALL, this hook should be integrated into SDISel.
-std::pair<SDOperand, SDOperand>
-TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
+std::pair<SDValue, SDValue>
+TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
bool RetSExt, bool RetZExt, bool isVarArg,
unsigned CallingConv, bool isTailCall,
- SDOperand Callee,
+ SDValue Callee,
ArgListTy &Args, SelectionDAG &DAG) {
- SmallVector<SDOperand, 32> Ops;
+ SmallVector<SDValue, 32> Ops;
Ops.push_back(Chain); // Op#0 - Chain
Ops.push_back(DAG.getConstant(CallingConv, getPointerTy())); // Op#1 - CC
Ops.push_back(DAG.getConstant(isVarArg, getPointerTy())); // Op#2 - VarArg
Value != NumValues; ++Value) {
MVT VT = ValueVTs[Value];
const Type *ArgTy = VT.getTypeForMVT();
- SDOperand Op = SDOperand(Args[i].Node.Val, Args[i].Node.ResNo + Value);
+ SDValue Op = SDValue(Args[i].Node.Val, Args[i].Node.getResNo() + Value);
ISD::ArgFlagsTy Flags;
unsigned OriginalAlignment =
getTargetData()->getABITypeAlignment(ArgTy);
MVT PartVT = getRegisterType(VT);
unsigned NumParts = getNumRegisters(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
+ SmallVector<SDValue, 4> Parts(NumParts);
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
if (Args[i].isSExt)
LoweredRetTys.push_back(MVT::Other); // Always has a chain.
// Create the CALL node.
- SDOperand Res = DAG.getNode(ISD::CALL,
+ SDValue Res = DAG.getNode(ISD::CALL,
DAG.getVTList(&LoweredRetTys[0],
LoweredRetTys.size()),
&Ops[0], Ops.size());
else if (RetZExt)
AssertOp = ISD::AssertZext;
- SmallVector<SDOperand, 4> ReturnValues;
+ SmallVector<SDValue, 4> ReturnValues;
unsigned RegNo = 0;
for (unsigned I = 0, E = RetTys.size(); I != E; ++I) {
MVT VT = RetTys[I];
MVT RegisterVT = getRegisterType(VT);
unsigned NumRegs = getNumRegisters(VT);
unsigned RegNoEnd = NumRegs + RegNo;
- SmallVector<SDOperand, 4> Results;
+ SmallVector<SDValue, 4> Results;
for (; RegNo != RegNoEnd; ++RegNo)
Results.push_back(Res.getValue(RegNo));
- SDOperand ReturnValue =
+ SDValue ReturnValue =
getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT,
AssertOp);
ReturnValues.push_back(ReturnValue);
}
- Res = ReturnValues.size() == 1 ? ReturnValues.front() :
- DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&RetTys[0], RetTys.size()),
- &ReturnValues[0], ReturnValues.size());
+ Res = DAG.getMergeValues(DAG.getVTList(&RetTys[0], RetTys.size()),
+ &ReturnValues[0], ReturnValues.size());
}
return std::make_pair(Res, Chain);
}
-SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
+SDValue TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
assert(0 && "LowerOperation not implemented for this target!");
abort();
- return SDOperand();
+ return SDValue();
}
-SDOperand TargetLowering::CustomPromoteOperation(SDOperand Op,
- SelectionDAG &DAG) {
- assert(0 && "CustomPromoteOperation not implemented for this target!");
- abort();
- return SDOperand();
-}
//===----------------------------------------------------------------------===//
// SelectionDAGISel code
//===----------------------------------------------------------------------===//
+SelectionDAGISel::SelectionDAGISel(TargetLowering &tli, bool fast) :
+ FunctionPass((intptr_t)&ID), TLI(tli),
+ FuncInfo(new FunctionLoweringInfo(TLI)),
+ CurDAG(new SelectionDAG(TLI, *FuncInfo)),
+ SDL(new SelectionDAGLowering(*CurDAG, TLI, *FuncInfo)),
+ GFI(),
+ Fast(fast),
+ DAGSize(0)
+{}
+
+SelectionDAGISel::~SelectionDAGISel() {
+ delete SDL;
+ delete CurDAG;
+ delete FuncInfo;
+}
+
unsigned SelectionDAGISel::MakeReg(MVT VT) {
return RegInfo->createVirtualRegister(TLI.getRegClassFor(VT));
}
void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AliasAnalysis>();
- AU.addRequired<CollectorModuleMetadata>();
+ AU.addRequired<GCModuleInfo>();
AU.setPreservesAll();
}
AA = &getAnalysis<AliasAnalysis>();
MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
- if (MF.getFunction()->hasCollector())
- GCI = &getAnalysis<CollectorModuleMetadata>().get(*MF.getFunction());
+ if (MF.getFunction()->hasGC())
+ GFI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF.getFunction());
else
- GCI = 0;
+ GFI = 0;
RegInfo = &MF.getRegInfo();
DOUT << "\n\n\n=== " << Fn.getName() << "\n";
- FunctionLoweringInfo FuncInfo(TLI, Fn, MF);
+ FuncInfo->set(Fn, MF);
+ CurDAG->init(MF, getAnalysisToUpdate<MachineModuleInfo>());
+ SDL->init(GFI, *AA);
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
if (InvokeInst *Invoke = dyn_cast<InvokeInst>(I->getTerminator()))
// Mark landing pad.
- FuncInfo.MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
+ FuncInfo->MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
- for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
- SelectBasicBlock(I, MF, FuncInfo);
+ SelectAllBasicBlocks(Fn, MF);
// Add function live-ins to entry block live-in set.
BasicBlock *EntryBB = &Fn.getEntryBlock();
- BB = FuncInfo.MBBMap[EntryBB];
+ BB = FuncInfo->MBBMap[EntryBB];
if (!RegInfo->livein_empty())
for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(),
E = RegInfo->livein_end(); I != E; ++I)
BB->addLiveIn(I->first);
#ifndef NDEBUG
- assert(FuncInfo.CatchInfoFound.size() == FuncInfo.CatchInfoLost.size() &&
+ assert(FuncInfo->CatchInfoFound.size() == FuncInfo->CatchInfoLost.size() &&
"Not all catch info was assigned to a landing pad!");
#endif
+ FuncInfo->clear();
+
return true;
}
void SelectionDAGLowering::CopyValueToVirtualRegister(Value *V, unsigned Reg) {
- SDOperand Op = getValue(V);
+ SDValue Op = getValue(V);
assert((Op.getOpcode() != ISD::CopyFromReg ||
cast<RegisterSDNode>(Op.getOperand(1))->getReg() != Reg) &&
"Copy from a reg to the same reg!");
assert(!TargetRegisterInfo::isPhysicalRegister(Reg) && "Is a physreg");
RegsForValue RFV(TLI, Reg, V->getType());
- SDOperand Chain = DAG.getEntryNode();
+ SDValue Chain = DAG.getEntryNode();
RFV.getCopyToRegs(Op, DAG, Chain, 0);
PendingExports.push_back(Chain);
}
void SelectionDAGISel::
-LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) {
+LowerArguments(BasicBlock *LLVMBB) {
// If this is the entry block, emit arguments.
Function &F = *LLVMBB->getParent();
- FunctionLoweringInfo &FuncInfo = SDL.FuncInfo;
- SDOperand OldRoot = SDL.DAG.getRoot();
- std::vector<SDOperand> Args = TLI.LowerArguments(F, SDL.DAG);
+ SDValue OldRoot = SDL->DAG.getRoot();
+ SmallVector<SDValue, 16> Args;
+ TLI.LowerArguments(F, SDL->DAG, Args);
unsigned a = 0;
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
ComputeValueVTs(TLI, AI->getType(), ValueVTs);
unsigned NumValues = ValueVTs.size();
if (!AI->use_empty()) {
- SmallVector<MVT, 4> LegalValueVTs(NumValues);
- for (unsigned VI = 0; VI != NumValues; ++VI)
- LegalValueVTs[VI] = Args[a + VI].getValueType();
- SDL.setValue(AI, SDL.DAG.getNode(ISD::MERGE_VALUES,
- SDL.DAG.getVTList(&LegalValueVTs[0],
- NumValues),
- &Args[a], NumValues));
+ SDL->setValue(AI, SDL->DAG.getMergeValues(&Args[a], NumValues));
// If this argument is live outside of the entry block, insert a copy from
// whereever we got it to the vreg that other BB's will reference it as.
- DenseMap<const Value*, unsigned>::iterator VMI=FuncInfo.ValueMap.find(AI);
- if (VMI != FuncInfo.ValueMap.end()) {
- SDL.CopyValueToVirtualRegister(AI, VMI->second);
+ DenseMap<const Value*, unsigned>::iterator VMI=FuncInfo->ValueMap.find(AI);
+ if (VMI != FuncInfo->ValueMap.end()) {
+ SDL->CopyValueToVirtualRegister(AI, VMI->second);
}
}
a += NumValues;
// Finally, if the target has anything special to do, allow it to do so.
// FIXME: this should insert code into the DAG!
- EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction());
+ EmitFunctionEntryCode(F, SDL->DAG.getMachineFunction());
}
static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB,
/// IsFixedFrameObjectWithPosOffset - Check if object is a fixed frame object and
/// whether object offset >= 0.
static bool
-IsFixedFrameObjectWithPosOffset(MachineFrameInfo * MFI, SDOperand Op) {
+IsFixedFrameObjectWithPosOffset(MachineFrameInfo * MFI, SDValue Op) {
if (!isa<FrameIndexSDNode>(Op)) return false;
FrameIndexSDNode * FrameIdxNode = dyn_cast<FrameIndexSDNode>(Op);
/// call. Currently the implementation of this call is very conservative and
/// assumes all arguments sourcing from FORMAL_ARGUMENTS or a CopyFromReg with
/// virtual registers would be overwritten by direct lowering.
-static bool IsPossiblyOverwrittenArgumentOfTailCall(SDOperand Op,
+static bool IsPossiblyOverwrittenArgumentOfTailCall(SDValue Op,
MachineFrameInfo * MFI) {
RegisterSDNode * OpReg = NULL;
if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS ||
(Op.getOpcode() == ISD::LOAD &&
IsFixedFrameObjectWithPosOffset(MFI, Op.getOperand(1))) ||
(Op.getOpcode() == ISD::MERGE_VALUES &&
- Op.getOperand(Op.ResNo).getOpcode() == ISD::LOAD &&
- IsFixedFrameObjectWithPosOffset(MFI, Op.getOperand(Op.ResNo).
+ Op.getOperand(Op.getResNo()).getOpcode() == ISD::LOAD &&
+ IsFixedFrameObjectWithPosOffset(MFI, Op.getOperand(Op.getResNo()).
getOperand(1))))
return true;
return false;
static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG,
TargetLowering& TLI) {
SDNode * Ret = NULL;
- SDOperand Terminator = DAG.getRoot();
+ SDValue Terminator = DAG.getRoot();
// Find RET node.
if (Terminator.getOpcode() == ISD::RET) {
// Fix tail call attribute of CALL nodes.
for (SelectionDAG::allnodes_iterator BE = DAG.allnodes_begin(),
- BI = prior(DAG.allnodes_end()); BI != BE; --BI) {
+ BI = DAG.allnodes_end(); BI != BE; ) {
+ --BI;
if (BI->getOpcode() == ISD::CALL) {
- SDOperand OpRet(Ret, 0);
- SDOperand OpCall(static_cast<SDNode*>(BI), 0);
+ SDValue OpRet(Ret, 0);
+ SDValue OpCall(BI, 0);
bool isMarkedTailCall =
cast<ConstantSDNode>(OpCall.getOperand(3))->getValue() != 0;
// If CALL node has tail call attribute set to true and the call is not
if (Ret==NULL ||
!TLI.IsEligibleForTailCallOptimization(OpCall, OpRet, DAG)) {
// Not eligible. Mark CALL node as non tail call.
- SmallVector<SDOperand, 32> Ops;
+ SmallVector<SDValue, 32> Ops;
unsigned idx=0;
for(SDNode::op_iterator I =OpCall.Val->op_begin(),
E = OpCall.Val->op_end(); I != E; I++, idx++) {
} else {
// Look for tail call clobbered arguments. Emit a series of
// copyto/copyfrom virtual register nodes to protect them.
- SmallVector<SDOperand, 32> Ops;
- SDOperand Chain = OpCall.getOperand(0), InFlag;
+ SmallVector<SDValue, 32> Ops;
+ SDValue Chain = OpCall.getOperand(0), InFlag;
unsigned idx=0;
for(SDNode::op_iterator I = OpCall.Val->op_begin(),
E = OpCall.Val->op_end(); I != E; I++, idx++) {
- SDOperand Arg = *I;
+ SDValue Arg = *I;
if (idx > 4 && (idx % 2)) {
bool isByVal = cast<ARG_FLAGSSDNode>(OpCall.getOperand(idx+1))->
getArgFlags().isByVal();
}
}
-void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
- std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
- FunctionLoweringInfo &FuncInfo) {
- SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo, GCI);
+/// Handle PHI nodes in successor blocks. Emit code into the SelectionDAG to
+/// ensure constants are generated when needed. Remember the virtual registers
+/// that need to be added to the Machine PHI nodes as input. We cannot just
+/// directly add them, because expansion might result in multiple MBB's for one
+/// BB. As such, the start of the BB might correspond to a different MBB than
+/// the end.
+///
+void
+SelectionDAGISel::HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB) {
+ TerminatorInst *TI = LLVMBB->getTerminator();
+
+ SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
+ // Check successor nodes' PHI nodes that expect a constant to be available
+ // from this block.
+ for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
+ BasicBlock *SuccBB = TI->getSuccessor(succ);
+ if (!isa<PHINode>(SuccBB->begin())) continue;
+ MachineBasicBlock *SuccMBB = FuncInfo->MBBMap[SuccBB];
+
+ // If this terminator has multiple identical successors (common for
+ // switches), only handle each succ once.
+ if (!SuccsHandled.insert(SuccMBB)) continue;
+
+ MachineBasicBlock::iterator MBBI = SuccMBB->begin();
+ PHINode *PN;
+
+ // At this point we know that there is a 1-1 correspondence between LLVM PHI
+ // nodes and Machine PHI nodes, but the incoming operands have not been
+ // emitted yet.
+ for (BasicBlock::iterator I = SuccBB->begin();
+ (PN = dyn_cast<PHINode>(I)); ++I) {
+ // Ignore dead phi's.
+ if (PN->use_empty()) continue;
+
+ unsigned Reg;
+ Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB);
+
+ if (Constant *C = dyn_cast<Constant>(PHIOp)) {
+ unsigned &RegOut = SDL->ConstantsOut[C];
+ if (RegOut == 0) {
+ RegOut = FuncInfo->CreateRegForValue(C);
+ SDL->CopyValueToVirtualRegister(C, RegOut);
+ }
+ Reg = RegOut;
+ } else {
+ Reg = FuncInfo->ValueMap[PHIOp];
+ if (Reg == 0) {
+ assert(isa<AllocaInst>(PHIOp) &&
+ FuncInfo->StaticAllocaMap.count(cast<AllocaInst>(PHIOp)) &&
+ "Didn't codegen value into a register!??");
+ Reg = FuncInfo->CreateRegForValue(PHIOp);
+ SDL->CopyValueToVirtualRegister(PHIOp, Reg);
+ }
+ }
+
+ // Remember that this register needs to added to the machine PHI node as
+ // the input for this MBB.
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(TLI, PN->getType(), ValueVTs);
+ for (unsigned vti = 0, vte = ValueVTs.size(); vti != vte; ++vti) {
+ MVT VT = ValueVTs[vti];
+ unsigned NumRegisters = TLI.getNumRegisters(VT);
+ for (unsigned i = 0, e = NumRegisters; i != e; ++i)
+ SDL->PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i));
+ Reg += NumRegisters;
+ }
+ }
+ }
+ SDL->ConstantsOut.clear();
+
+ // Lower the terminator after the copies are emitted.
+ SDL->visit(*LLVMBB->getTerminator());
+}
+
+void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
+ BasicBlock::iterator Begin,
+ BasicBlock::iterator End,
+ bool DoArgs) {
// Lower any arguments needed in this block if this is the entry block.
- if (LLVMBB == &LLVMBB->getParent()->getEntryBlock())
- LowerArguments(LLVMBB, SDL);
+ if (DoArgs)
+ LowerArguments(LLVMBB);
- BB = FuncInfo.MBBMap[LLVMBB];
- SDL.setCurrentBasicBlock(BB);
+ SDL->setCurrentBasicBlock(BB);
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ MachineModuleInfo *MMI = CurDAG->getMachineModuleInfo();
if (MMI && BB->isLandingPad()) {
// Add a label to mark the beginning of the landing pad. Deletion of the
// landing pad can thus be detected via the MachineModuleInfo.
unsigned LabelID = MMI->addLandingPad(BB);
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
- DAG.getConstant(LabelID, MVT::i32),
- DAG.getConstant(1, MVT::i32)));
+ CurDAG->setRoot(CurDAG->getLabel(ISD::EH_LABEL,
+ CurDAG->getEntryNode(), LabelID));
// Mark exception register as live in.
unsigned Reg = TLI.getExceptionAddressRegister();
if (I == E)
// No catch info found - try to extract some from the successor.
- copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, FuncInfo);
+ copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, *FuncInfo);
}
}
// Lower all of the non-terminator instructions.
- for (BasicBlock::iterator I = LLVMBB->begin(), E = --LLVMBB->end();
- I != E; ++I)
- SDL.visit(*I);
+ for (BasicBlock::iterator I = Begin; I != End; ++I)
+ if (!isa<TerminatorInst>(I))
+ SDL->visit(*I);
// Ensure that all instructions which are used outside of their defining
// blocks are available as virtual registers. Invoke is handled elsewhere.
- for (BasicBlock::iterator I = LLVMBB->begin(), E = LLVMBB->end(); I != E;++I)
+ for (BasicBlock::iterator I = Begin; I != End; ++I)
if (!I->use_empty() && !isa<PHINode>(I) && !isa<InvokeInst>(I)) {
- DenseMap<const Value*, unsigned>::iterator VMI =FuncInfo.ValueMap.find(I);
- if (VMI != FuncInfo.ValueMap.end())
- SDL.CopyValueToVirtualRegister(I, VMI->second);
+ DenseMap<const Value*,unsigned>::iterator VMI =FuncInfo->ValueMap.find(I);
+ if (VMI != FuncInfo->ValueMap.end())
+ SDL->CopyValueToVirtualRegister(I, VMI->second);
}
- // Handle PHI nodes in successor blocks. Emit code into the SelectionDAG to
- // ensure constants are generated when needed. Remember the virtual registers
- // that need to be added to the Machine PHI nodes as input. We cannot just
- // directly add them, because expansion might result in multiple MBB's for one
- // BB. As such, the start of the BB might correspond to a different MBB than
- // the end.
- //
- TerminatorInst *TI = LLVMBB->getTerminator();
-
- // Emit constants only once even if used by multiple PHI nodes.
- std::map<Constant*, unsigned> ConstantsOut;
-
- // Vector bool would be better, but vector<bool> is really slow.
- std::vector<unsigned char> SuccsHandled;
- if (TI->getNumSuccessors())
- SuccsHandled.resize(BB->getParent()->getNumBlockIDs());
-
- // Check successor nodes' PHI nodes that expect a constant to be available
- // from this block.
- for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
- BasicBlock *SuccBB = TI->getSuccessor(succ);
- if (!isa<PHINode>(SuccBB->begin())) continue;
- MachineBasicBlock *SuccMBB = FuncInfo.MBBMap[SuccBB];
-
- // If this terminator has multiple identical successors (common for
- // switches), only handle each succ once.
- unsigned SuccMBBNo = SuccMBB->getNumber();
- if (SuccsHandled[SuccMBBNo]) continue;
- SuccsHandled[SuccMBBNo] = true;
-
- MachineBasicBlock::iterator MBBI = SuccMBB->begin();
- PHINode *PN;
-
- // At this point we know that there is a 1-1 correspondence between LLVM PHI
- // nodes and Machine PHI nodes, but the incoming operands have not been
- // emitted yet.
- for (BasicBlock::iterator I = SuccBB->begin();
- (PN = dyn_cast<PHINode>(I)); ++I) {
- // Ignore dead phi's.
- if (PN->use_empty()) continue;
-
- unsigned Reg;
- Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB);
-
- if (Constant *C = dyn_cast<Constant>(PHIOp)) {
- unsigned &RegOut = ConstantsOut[C];
- if (RegOut == 0) {
- RegOut = FuncInfo.CreateRegForValue(C);
- SDL.CopyValueToVirtualRegister(C, RegOut);
- }
- Reg = RegOut;
- } else {
- Reg = FuncInfo.ValueMap[PHIOp];
- if (Reg == 0) {
- assert(isa<AllocaInst>(PHIOp) &&
- FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(PHIOp)) &&
- "Didn't codegen value into a register!??");
- Reg = FuncInfo.CreateRegForValue(PHIOp);
- SDL.CopyValueToVirtualRegister(PHIOp, Reg);
- }
- }
-
- // Remember that this register needs to added to the machine PHI node as
- // the input for this MBB.
- MVT VT = TLI.getValueType(PN->getType());
- unsigned NumRegisters = TLI.getNumRegisters(VT);
- for (unsigned i = 0, e = NumRegisters; i != e; ++i)
- PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i));
- }
- }
- ConstantsOut.clear();
-
- // Lower the terminator after the copies are emitted.
- SDL.visit(*LLVMBB->getTerminator());
-
- // Copy over any CaseBlock records that may now exist due to SwitchInst
- // lowering, as well as any jump table information.
- SwitchCases.clear();
- SwitchCases = SDL.SwitchCases;
- JTCases.clear();
- JTCases = SDL.JTCases;
- BitTestCases.clear();
- BitTestCases = SDL.BitTestCases;
+ // Handle PHI nodes in successor blocks.
+ if (Begin != End && End == LLVMBB->end())
+ HandlePHINodesInSuccessorBlocks(LLVMBB);
// Make sure the root of the DAG is up-to-date.
- DAG.setRoot(SDL.getControlRoot());
+ CurDAG->setRoot(SDL->getControlRoot());
// Check whether calls in this block are real tail calls. Fix up CALL nodes
// with correct tailcall attribute so that the target can rely on the tailcall
// attribute indicating whether the call is really eligible for tail call
// optimization.
- CheckDAGForTailCallsAndFixThem(DAG, TLI);
+ CheckDAGForTailCallsAndFixThem(*CurDAG, TLI);
+
+ // Final step, emit the lowered DAG as machine code.
+ CodeGenAndEmitDAG();
+ SDL->clear();
}
-void SelectionDAGISel::ComputeLiveOutVRegInfo(SelectionDAG &DAG) {
+void SelectionDAGISel::ComputeLiveOutVRegInfo() {
SmallPtrSet<SDNode*, 128> VisitedNodes;
SmallVector<SDNode*, 128> Worklist;
- Worklist.push_back(DAG.getRoot().Val);
+ Worklist.push_back(CurDAG->getRoot().Val);
APInt Mask;
APInt KnownZero;
continue;
// Ignore non-scalar or non-integer values.
- SDOperand Src = N->getOperand(2);
+ SDValue Src = N->getOperand(2);
MVT SrcVT = Src.getValueType();
if (!SrcVT.isInteger() || SrcVT.isVector())
continue;
- unsigned NumSignBits = DAG.ComputeNumSignBits(Src);
+ unsigned NumSignBits = CurDAG->ComputeNumSignBits(Src);
Mask = APInt::getAllOnesValue(SrcVT.getSizeInBits());
- DAG.ComputeMaskedBits(Src, Mask, KnownZero, KnownOne);
+ CurDAG->ComputeMaskedBits(Src, Mask, KnownZero, KnownOne);
// Only install this information if it tells us something.
if (NumSignBits != 1 || KnownZero != 0 || KnownOne != 0) {
DestReg -= TargetRegisterInfo::FirstVirtualRegister;
- FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo();
+ FunctionLoweringInfo &FLI = CurDAG->getFunctionLoweringInfo();
if (DestReg >= FLI.LiveOutRegInfo.size())
FLI.LiveOutRegInfo.resize(DestReg+1);
FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[DestReg];
}
}
-void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) {
- DOUT << "Lowered selection DAG:\n";
- DEBUG(DAG.dump());
+void SelectionDAGISel::CodeGenAndEmitDAG() {
+ std::string GroupName;
+ if (TimePassesIsEnabled)
+ GroupName = "Instruction Selection and Scheduling";
+ std::string BlockName;
+ if (ViewDAGCombine1 || ViewLegalizeTypesDAGs || ViewLegalizeDAGs ||
+ ViewDAGCombine2 || ViewISelDAGs || ViewSchedDAGs || ViewSUnitDAGs)
+ BlockName = CurDAG->getMachineFunction().getFunction()->getName() + ':' +
+ BB->getBasicBlock()->getName();
+
+ DOUT << "Initial selection DAG:\n";
+ DEBUG(CurDAG->dump());
+
+ if (ViewDAGCombine1) CurDAG->viewGraph("dag-combine1 input for " + BlockName);
// Run the DAG combiner in pre-legalize mode.
- DAG.Combine(false, *AA);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("DAG Combining 1", GroupName);
+ CurDAG->Combine(false, *AA, Fast);
+ } else {
+ CurDAG->Combine(false, *AA, Fast);
+ }
DOUT << "Optimized lowered selection DAG:\n";
- DEBUG(DAG.dump());
+ DEBUG(CurDAG->dump());
// Second step, hack on the DAG until it only uses operations and types that
// the target supports.
-#if 0 // Enable this some day.
- DAG.LegalizeTypes();
- // Someday even later, enable a dag combine pass here.
-#endif
- DAG.Legalize();
+ if (EnableLegalizeTypes) {// Enable this some day.
+ if (ViewLegalizeTypesDAGs) CurDAG->viewGraph("legalize-types input for " +
+ BlockName);
+
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Type Legalization", GroupName);
+ CurDAG->LegalizeTypes();
+ } else {
+ CurDAG->LegalizeTypes();
+ }
+
+ DOUT << "Type-legalized selection DAG:\n";
+ DEBUG(CurDAG->dump());
+
+ // TODO: enable a dag combine pass here.
+ }
+
+ if (ViewLegalizeDAGs) CurDAG->viewGraph("legalize input for " + BlockName);
+
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("DAG Legalization", GroupName);
+ CurDAG->Legalize();
+ } else {
+ CurDAG->Legalize();
+ }
DOUT << "Legalized selection DAG:\n";
- DEBUG(DAG.dump());
+ DEBUG(CurDAG->dump());
+ if (ViewDAGCombine2) CurDAG->viewGraph("dag-combine2 input for " + BlockName);
+
// Run the DAG combiner in post-legalize mode.
- DAG.Combine(true, *AA);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("DAG Combining 2", GroupName);
+ CurDAG->Combine(true, *AA, Fast);
+ } else {
+ CurDAG->Combine(true, *AA, Fast);
+ }
DOUT << "Optimized legalized selection DAG:\n";
- DEBUG(DAG.dump());
+ DEBUG(CurDAG->dump());
- if (ViewISelDAGs) DAG.viewGraph();
+ if (ViewISelDAGs) CurDAG->viewGraph("isel input for " + BlockName);
- if (EnableValueProp) // FIXME: Only do this if !fast.
- ComputeLiveOutVRegInfo(DAG);
+ if (!Fast && EnableValueProp)
+ ComputeLiveOutVRegInfo();
// Third, instruction select all of the operations to machine code, adding the
// code to the MachineBasicBlock.
- InstructionSelectBasicBlock(DAG);
-
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Selection", GroupName);
+ InstructionSelect();
+ } else {
+ InstructionSelect();
+ }
+
+ DOUT << "Selected selection DAG:\n";
+ DEBUG(CurDAG->dump());
+
+ if (ViewSchedDAGs) CurDAG->viewGraph("scheduler input for " + BlockName);
+
+ // Schedule machine code.
+ ScheduleDAG *Scheduler;
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Scheduling", GroupName);
+ Scheduler = Schedule();
+ } else {
+ Scheduler = Schedule();
+ }
+
+ if (ViewSUnitDAGs) Scheduler->viewGraph();
+
+ // Emit machine code to BB. This can change 'BB' to the last block being
+ // inserted into.
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Creation", GroupName);
+ BB = Scheduler->EmitSchedule();
+ } else {
+ BB = Scheduler->EmitSchedule();
+ }
+
+ // Free the scheduler state.
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Scheduling Cleanup", GroupName);
+ delete Scheduler;
+ } else {
+ delete Scheduler;
+ }
+
DOUT << "Selected machine code:\n";
DEBUG(BB->dump());
}
-void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
- FunctionLoweringInfo &FuncInfo) {
- std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
- {
- SelectionDAG DAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
- CurDAG = &DAG;
-
- // First step, lower LLVM code to some DAG. This DAG may use operations and
- // types that are not supported by the target.
- BuildSelectionDAG(DAG, LLVMBB, PHINodesToUpdate, FuncInfo);
+void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) {
+ for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
+ BasicBlock *LLVMBB = &*I;
+ BB = FuncInfo->MBBMap[LLVMBB];
+
+ BasicBlock::iterator Begin = LLVMBB->begin();
+ BasicBlock::iterator End = LLVMBB->end();
+ bool DoArgs = LLVMBB == &Fn.getEntryBlock();
+
+ // Before doing SelectionDAG ISel, see if FastISel has been requested.
+ // FastISel doesn't support EH landing pads, which require special handling.
+ if (EnableFastISel && !BB->isLandingPad()) {
+ if (FastISel *F = TLI.createFastISel(*FuncInfo->MF)) {
+ while (Begin != End) {
+ Begin = F->SelectInstructions(Begin, End, FuncInfo->ValueMap,
+ FuncInfo->MBBMap, BB);
+
+ if (Begin == End)
+ // The "fast" selector selected the entire block, so we're done.
+ break;
+
+ // Handle certain instructions as single-LLVM-Instruction blocks.
+ if (isa<CallInst>(Begin) || isa<LoadInst>(Begin) ||
+ isa<StoreInst>(Begin)) {
+ if (Begin->getType() != Type::VoidTy) {
+ unsigned &R = FuncInfo->ValueMap[Begin];
+ if (!R)
+ R = FuncInfo->CreateRegForValue(Begin);
+ }
+
+ SelectBasicBlock(LLVMBB, Begin, next(Begin), DoArgs);
- // Second step, emit the lowered DAG as machine code.
- CodeGenAndEmitDAG(DAG);
+ ++Begin;
+ DoArgs = false;
+ continue;
+ }
+
+ if (!DisableFastISelAbort &&
+ // For now, don't abort on non-conditional-branch terminators.
+ (!isa<TerminatorInst>(Begin) ||
+ (isa<BranchInst>(Begin) &&
+ cast<BranchInst>(Begin)->isUnconditional()))) {
+ // The "fast" selector couldn't handle something and bailed.
+ // For the purpose of debugging, just abort.
+#ifndef NDEBUG
+ Begin->dump();
+#endif
+ assert(0 && "FastISel didn't select the entire block");
+ }
+ break;
+ }
+ delete F;
+ }
+ }
+
+ if (Begin != End || DoArgs)
+ SelectBasicBlock(LLVMBB, Begin, End, DoArgs);
+
+ FinishBasicBlock();
}
+}
+
+void
+SelectionDAGISel::FinishBasicBlock() {
+
+ // Perform target specific isel post processing.
+ InstructionSelectPostProcessing();
+
+ DOUT << "Target-post-processed machine code:\n";
+ DEBUG(BB->dump());
DOUT << "Total amount of phi nodes to update: "
- << PHINodesToUpdate.size() << "\n";
- DEBUG(for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i)
- DOUT << "Node " << i << " : (" << PHINodesToUpdate[i].first
- << ", " << PHINodesToUpdate[i].second << ")\n";);
+ << SDL->PHINodesToUpdate.size() << "\n";
+ DEBUG(for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i)
+ DOUT << "Node " << i << " : (" << SDL->PHINodesToUpdate[i].first
+ << ", " << SDL->PHINodesToUpdate[i].second << ")\n";);
// Next, now that we know what the last MBB the LLVM BB expanded is, update
// PHI nodes in successors.
- if (SwitchCases.empty() && JTCases.empty() && BitTestCases.empty()) {
- for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i) {
- MachineInstr *PHI = PHINodesToUpdate[i].first;
+ if (SDL->SwitchCases.empty() &&
+ SDL->JTCases.empty() &&
+ SDL->BitTestCases.empty()) {
+ for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i) {
+ MachineInstr *PHI = SDL->PHINodesToUpdate[i].first;
assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
"This is not a machine PHI node that we are updating!");
- PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[i].second,
+ PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[i].second,
false));
PHI->addOperand(MachineOperand::CreateMBB(BB));
}
+ SDL->PHINodesToUpdate.clear();
return;
}
- for (unsigned i = 0, e = BitTestCases.size(); i != e; ++i) {
+ for (unsigned i = 0, e = SDL->BitTestCases.size(); i != e; ++i) {
// Lower header first, if it wasn't already lowered
- if (!BitTestCases[i].Emitted) {
- SelectionDAG HSDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
- CurDAG = &HSDAG;
- SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
+ if (!SDL->BitTestCases[i].Emitted) {
// Set the current basic block to the mbb we wish to insert the code into
- BB = BitTestCases[i].Parent;
- HSDL.setCurrentBasicBlock(BB);
+ BB = SDL->BitTestCases[i].Parent;
+ SDL->setCurrentBasicBlock(BB);
// Emit the code
- HSDL.visitBitTestHeader(BitTestCases[i]);
- HSDAG.setRoot(HSDL.getRoot());
- CodeGenAndEmitDAG(HSDAG);
+ SDL->visitBitTestHeader(SDL->BitTestCases[i]);
+ CurDAG->setRoot(SDL->getRoot());
+ CodeGenAndEmitDAG();
+ SDL->clear();
}
- for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) {
- SelectionDAG BSDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
- CurDAG = &BSDAG;
- SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GCI);
+ for (unsigned j = 0, ej = SDL->BitTestCases[i].Cases.size(); j != ej; ++j) {
// Set the current basic block to the mbb we wish to insert the code into
- BB = BitTestCases[i].Cases[j].ThisBB;
- BSDL.setCurrentBasicBlock(BB);
+ BB = SDL->BitTestCases[i].Cases[j].ThisBB;
+ SDL->setCurrentBasicBlock(BB);
// Emit the code
if (j+1 != ej)
- BSDL.visitBitTestCase(BitTestCases[i].Cases[j+1].ThisBB,
- BitTestCases[i].Reg,
- BitTestCases[i].Cases[j]);
+ SDL->visitBitTestCase(SDL->BitTestCases[i].Cases[j+1].ThisBB,
+ SDL->BitTestCases[i].Reg,
+ SDL->BitTestCases[i].Cases[j]);
else
- BSDL.visitBitTestCase(BitTestCases[i].Default,
- BitTestCases[i].Reg,
- BitTestCases[i].Cases[j]);
+ SDL->visitBitTestCase(SDL->BitTestCases[i].Default,
+ SDL->BitTestCases[i].Reg,
+ SDL->BitTestCases[i].Cases[j]);
- BSDAG.setRoot(BSDL.getRoot());
- CodeGenAndEmitDAG(BSDAG);
+ CurDAG->setRoot(SDL->getRoot());
+ CodeGenAndEmitDAG();
+ SDL->clear();
}
// Update PHI Nodes
- for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) {
- MachineInstr *PHI = PHINodesToUpdate[pi].first;
+ for (unsigned pi = 0, pe = SDL->PHINodesToUpdate.size(); pi != pe; ++pi) {
+ MachineInstr *PHI = SDL->PHINodesToUpdate[pi].first;
MachineBasicBlock *PHIBB = PHI->getParent();
assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
"This is not a machine PHI node that we are updating!");
// This is "default" BB. We have two jumps to it. From "header" BB and
// from last "case" BB.
- if (PHIBB == BitTestCases[i].Default) {
- PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second,
+ if (PHIBB == SDL->BitTestCases[i].Default) {
+ PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
false));
- PHI->addOperand(MachineOperand::CreateMBB(BitTestCases[i].Parent));
- PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second,
+ PHI->addOperand(MachineOperand::CreateMBB(SDL->BitTestCases[i].Parent));
+ PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
false));
- PHI->addOperand(MachineOperand::CreateMBB(BitTestCases[i].Cases.
+ PHI->addOperand(MachineOperand::CreateMBB(SDL->BitTestCases[i].Cases.
back().ThisBB));
}
// One of "cases" BB.
- for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) {
- MachineBasicBlock* cBB = BitTestCases[i].Cases[j].ThisBB;
+ for (unsigned j = 0, ej = SDL->BitTestCases[i].Cases.size();
+ j != ej; ++j) {
+ MachineBasicBlock* cBB = SDL->BitTestCases[i].Cases[j].ThisBB;
if (cBB->succ_end() !=
std::find(cBB->succ_begin(),cBB->succ_end(), PHIBB)) {
- PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second,
+ PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
false));
PHI->addOperand(MachineOperand::CreateMBB(cBB));
}
}
}
}
+ SDL->BitTestCases.clear();
// If the JumpTable record is filled in, then we need to emit a jump table.
// Updating the PHI nodes is tricky in this case, since we need to determine
// whether the PHI is a successor of the range check MBB or the jump table MBB
- for (unsigned i = 0, e = JTCases.size(); i != e; ++i) {
+ for (unsigned i = 0, e = SDL->JTCases.size(); i != e; ++i) {
// Lower header first, if it wasn't already lowered
- if (!JTCases[i].first.Emitted) {
- SelectionDAG HSDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
- CurDAG = &HSDAG;
- SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
+ if (!SDL->JTCases[i].first.Emitted) {
// Set the current basic block to the mbb we wish to insert the code into
- BB = JTCases[i].first.HeaderBB;
- HSDL.setCurrentBasicBlock(BB);
+ BB = SDL->JTCases[i].first.HeaderBB;
+ SDL->setCurrentBasicBlock(BB);
// Emit the code
- HSDL.visitJumpTableHeader(JTCases[i].second, JTCases[i].first);
- HSDAG.setRoot(HSDL.getRoot());
- CodeGenAndEmitDAG(HSDAG);
+ SDL->visitJumpTableHeader(SDL->JTCases[i].second, SDL->JTCases[i].first);
+ CurDAG->setRoot(SDL->getRoot());
+ CodeGenAndEmitDAG();
+ SDL->clear();
}
- SelectionDAG JSDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
- CurDAG = &JSDAG;
- SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GCI);
// Set the current basic block to the mbb we wish to insert the code into
- BB = JTCases[i].second.MBB;
- JSDL.setCurrentBasicBlock(BB);
+ BB = SDL->JTCases[i].second.MBB;
+ SDL->setCurrentBasicBlock(BB);
// Emit the code
- JSDL.visitJumpTable(JTCases[i].second);
- JSDAG.setRoot(JSDL.getRoot());
- CodeGenAndEmitDAG(JSDAG);
+ SDL->visitJumpTable(SDL->JTCases[i].second);
+ CurDAG->setRoot(SDL->getRoot());
+ CodeGenAndEmitDAG();
+ SDL->clear();
// Update PHI Nodes
- for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) {
- MachineInstr *PHI = PHINodesToUpdate[pi].first;
+ for (unsigned pi = 0, pe = SDL->PHINodesToUpdate.size(); pi != pe; ++pi) {
+ MachineInstr *PHI = SDL->PHINodesToUpdate[pi].first;
MachineBasicBlock *PHIBB = PHI->getParent();
assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
"This is not a machine PHI node that we are updating!");
// "default" BB. We can go there only from header BB.
- if (PHIBB == JTCases[i].second.Default) {
- PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second,
+ if (PHIBB == SDL->JTCases[i].second.Default) {
+ PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
false));
- PHI->addOperand(MachineOperand::CreateMBB(JTCases[i].first.HeaderBB));
+ PHI->addOperand(MachineOperand::CreateMBB(SDL->JTCases[i].first.HeaderBB));
}
// JT BB. Just iterate over successors here
if (BB->succ_end() != std::find(BB->succ_begin(),BB->succ_end(), PHIBB)) {
- PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second,
+ PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
false));
PHI->addOperand(MachineOperand::CreateMBB(BB));
}
}
}
+ SDL->JTCases.clear();
// If the switch block involved a branch to one of the actual successors, we
// need to update PHI nodes in that block.
- for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i) {
- MachineInstr *PHI = PHINodesToUpdate[i].first;
+ for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i) {
+ MachineInstr *PHI = SDL->PHINodesToUpdate[i].first;
assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
"This is not a machine PHI node that we are updating!");
if (BB->isSuccessor(PHI->getParent())) {
- PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[i].second,
+ PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[i].second,
false));
PHI->addOperand(MachineOperand::CreateMBB(BB));
}
// If we generated any switch lowering information, build and codegen any
// additional DAGs necessary.
- for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
- SelectionDAG SDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
- CurDAG = &SDAG;
- SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI);
-
+ for (unsigned i = 0, e = SDL->SwitchCases.size(); i != e; ++i) {
// Set the current basic block to the mbb we wish to insert the code into
- BB = SwitchCases[i].ThisBB;
- SDL.setCurrentBasicBlock(BB);
+ BB = SDL->SwitchCases[i].ThisBB;
+ SDL->setCurrentBasicBlock(BB);
// Emit the code
- SDL.visitSwitchCase(SwitchCases[i]);
- SDAG.setRoot(SDL.getRoot());
- CodeGenAndEmitDAG(SDAG);
+ SDL->visitSwitchCase(SDL->SwitchCases[i]);
+ CurDAG->setRoot(SDL->getRoot());
+ CodeGenAndEmitDAG();
+ SDL->clear();
// Handle any PHI nodes in successors of this chunk, as if we were coming
// from the original BB before switch expansion. Note that PHI nodes can
// occur multiple times in PHINodesToUpdate. We have to be very careful to
// handle them the right number of times.
- while ((BB = SwitchCases[i].TrueBB)) { // Handle LHS and RHS.
+ while ((BB = SDL->SwitchCases[i].TrueBB)) { // Handle LHS and RHS.
for (MachineBasicBlock::iterator Phi = BB->begin();
Phi != BB->end() && Phi->getOpcode() == TargetInstrInfo::PHI; ++Phi){
// This value for this PHI node is recorded in PHINodesToUpdate, get it.
for (unsigned pn = 0; ; ++pn) {
- assert(pn != PHINodesToUpdate.size() && "Didn't find PHI entry!");
- if (PHINodesToUpdate[pn].first == Phi) {
- Phi->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pn].
+ assert(pn != SDL->PHINodesToUpdate.size() &&
+ "Didn't find PHI entry!");
+ if (SDL->PHINodesToUpdate[pn].first == Phi) {
+ Phi->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pn].
second, false));
- Phi->addOperand(MachineOperand::CreateMBB(SwitchCases[i].ThisBB));
+ Phi->addOperand(MachineOperand::CreateMBB(SDL->SwitchCases[i].ThisBB));
break;
}
}
}
// Don't process RHS if same block as LHS.
- if (BB == SwitchCases[i].FalseBB)
- SwitchCases[i].FalseBB = 0;
+ if (BB == SDL->SwitchCases[i].FalseBB)
+ SDL->SwitchCases[i].FalseBB = 0;
// If we haven't handled the RHS, do so now. Otherwise, we're done.
- SwitchCases[i].TrueBB = SwitchCases[i].FalseBB;
- SwitchCases[i].FalseBB = 0;
+ SDL->SwitchCases[i].TrueBB = SDL->SwitchCases[i].FalseBB;
+ SDL->SwitchCases[i].FalseBB = 0;
}
- assert(SwitchCases[i].TrueBB == 0 && SwitchCases[i].FalseBB == 0);
+ assert(SDL->SwitchCases[i].TrueBB == 0 && SDL->SwitchCases[i].FalseBB == 0);
}
+ SDL->SwitchCases.clear();
+
+ SDL->PHINodesToUpdate.clear();
}
-//===----------------------------------------------------------------------===//
-/// ScheduleAndEmitDAG - Pick a safe ordering and emit instructions for each
+/// Schedule - Pick a safe ordering for instructions for each
/// target node in the graph.
-void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) {
- if (ViewSchedDAGs) DAG.viewGraph();
-
+///
+ScheduleDAG *SelectionDAGISel::Schedule() {
RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault();
if (!Ctor) {
RegisterScheduler::setDefault(Ctor);
}
- ScheduleDAG *SL = Ctor(this, &DAG, BB);
- BB = SL->Run();
-
- if (ViewSUnitDAGs) SL->viewGraph();
+ ScheduleDAG *Scheduler = Ctor(this, CurDAG, BB, Fast);
+ Scheduler->Run();
- delete SL;
+ return Scheduler;
}
/// the dag combiner simplified the 255, we still want to match. RHS is the
/// actual value in the DAG on the RHS of an AND, and DesiredMaskS is the value
/// specified in the .td file (e.g. 255).
-bool SelectionDAGISel::CheckAndMask(SDOperand LHS, ConstantSDNode *RHS,
+bool SelectionDAGISel::CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
int64_t DesiredMaskS) const {
const APInt &ActualMask = RHS->getAPIntValue();
const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
/// the dag combiner simplified the 255, we still want to match. RHS is the
/// actual value in the DAG on the RHS of an OR, and DesiredMaskS is the value
/// specified in the .td file (e.g. 255).
-bool SelectionDAGISel::CheckOrMask(SDOperand LHS, ConstantSDNode *RHS,
+bool SelectionDAGISel::CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
int64_t DesiredMaskS) const {
const APInt &ActualMask = RHS->getAPIntValue();
const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
/// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
/// by tblgen. Others should not call it.
void SelectionDAGISel::
-SelectInlineAsmMemoryOperands(std::vector<SDOperand> &Ops, SelectionDAG &DAG) {
- std::vector<SDOperand> InOps;
+SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops) {
+ std::vector<SDValue> InOps;
std::swap(InOps, Ops);
Ops.push_back(InOps[0]); // input chain.
} else {
assert((Flags >> 3) == 1 && "Memory operand with multiple values?");
// Otherwise, this is a memory operand. Ask the target to select it.
- std::vector<SDOperand> SelOps;
- if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps, DAG)) {
+ std::vector<SDValue> SelOps;
+ if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) {
cerr << "Could not match memory address. Inline asm failure!\n";
exit(1);
}
// Add this to the output node.
- MVT IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
- Ops.push_back(DAG.getTargetConstant(4/*MEM*/ | (SelOps.size() << 3),
- IntPtrTy));
+ MVT IntPtrTy = CurDAG->getTargetLoweringInfo().getPointerTy();
+ Ops.push_back(CurDAG->getTargetConstant(4/*MEM*/ | (SelOps.size() << 3),
+ IntPtrTy));
Ops.insert(Ops.end(), SelOps.begin(), SelOps.end());
i += 2;
}