[FastISel] Some long overdue spring cleaning of FastISel.

Things got a little bit messy over the years and it is time for a little bit
spring cleaning.

This first commit is focused on the FastISel base class itself. It doxyfies all
comments, C++11fies the code where it makes sense, renames internal methods to
adhere to the coding standard, and clang-formats the files.

Reviewed by Eric

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217060 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Juergen Ributzka 2014-09-03 18:46:45 +00:00
parent 75899aab35
commit 39af4e655a
3 changed files with 554 additions and 650 deletions

View File

@ -24,66 +24,46 @@
namespace llvm {
class AllocaInst;
class Constant;
class ConstantFP;
class CallInst;
class DataLayout;
class FunctionLoweringInfo;
class Instruction;
class LoadInst;
class MVT;
class MachineConstantPool;
class MachineFrameInfo;
class MachineFunction;
class MachineInstr;
class MachineRegisterInfo;
class TargetInstrInfo;
class TargetLibraryInfo;
class TargetLowering;
class TargetMachine;
class TargetRegisterClass;
class TargetRegisterInfo;
class User;
class Value;
/// This is a fast-path instruction selection class that generates poor code and
/// doesn't support illegal types or non-trivial lowering, but runs quickly.
/// \brief This is a fast-path instruction selection class that generates poor
/// code and doesn't support illegal types or non-trivial lowering, but runs
/// quickly.
class FastISel {
public:
public:
struct ArgListEntry {
Value *Val;
Type *Ty;
bool isSExt : 1;
bool isZExt : 1;
bool isInReg : 1;
bool isSRet : 1;
bool isNest : 1;
bool isByVal : 1;
bool isInAlloca : 1;
bool isReturned : 1;
bool IsSExt : 1;
bool IsZExt : 1;
bool IsInReg : 1;
bool IsSRet : 1;
bool IsNest : 1;
bool IsByVal : 1;
bool IsInAlloca : 1;
bool IsReturned : 1;
uint16_t Alignment;
ArgListEntry()
: Val(nullptr), Ty(nullptr), isSExt(false), isZExt(false), isInReg(false),
isSRet(false), isNest(false), isByVal(false), isInAlloca(false),
isReturned(false), Alignment(0) { }
: Val(nullptr), Ty(nullptr), IsSExt(false), IsZExt(false),
IsInReg(false), IsSRet(false), IsNest(false), IsByVal(false),
IsInAlloca(false), IsReturned(false), Alignment(0) {}
/// \brief Set CallLoweringInfo attribute flags based on a call instruction
/// and called function attributes.
void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
};
typedef std::vector<ArgListEntry> ArgListTy;
struct CallLoweringInfo {
Type *RetTy;
bool RetSExt : 1;
bool RetZExt : 1;
bool IsVarArg : 1;
bool IsInReg : 1;
bool DoesNotReturn : 1;
bool RetSExt : 1;
bool RetZExt : 1;
bool IsVarArg : 1;
bool IsInReg : 1;
bool DoesNotReturn : 1;
bool IsReturnValueUsed : 1;
// IsTailCall should be modified by implementations of
// FastLowerCall that perform tail call conversions.
// \brief IsTailCall Should be modified by implementations of FastLowerCall
// that perform tail call conversions.
bool IsTailCall;
unsigned NumFixedArgs;
@ -103,12 +83,11 @@ class FastISel {
SmallVector<unsigned, 4> InRegs;
CallLoweringInfo()
: RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false),
IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true),
IsTailCall(false), NumFixedArgs(-1), CallConv(CallingConv::C),
Callee(nullptr), SymName(nullptr), CS(nullptr), Call(nullptr),
ResultReg(0), NumResultRegs(0)
{}
: RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false),
IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true),
IsTailCall(false), NumFixedArgs(-1), CallConv(CallingConv::C),
Callee(nullptr), SymName(nullptr), CS(nullptr), Call(nullptr),
ResultReg(0), NumResultRegs(0) {}
CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
const Value *Target, ArgListTy &&ArgsList,
@ -172,9 +151,7 @@ class FastISel {
return *this;
}
ArgListTy &getArgs() {
return Args;
}
ArgListTy &getArgs() { return Args; }
void clearOuts() {
OutVals.clear();
@ -204,60 +181,62 @@ protected:
const TargetLibraryInfo *LibInfo;
bool SkipTargetIndependentISel;
/// The position of the last instruction for materializing constants for use
/// in the current block. It resets to EmitStartPt when it makes sense (for
/// example, it's usually profitable to avoid function calls between the
/// \brief The position of the last instruction for materializing constants
/// for use in the current block. It resets to EmitStartPt when it makes sense
/// (for example, it's usually profitable to avoid function calls between the
/// definition and the use)
MachineInstr *LastLocalValue;
/// The top most instruction in the current block that is allowed for emitting
/// local variables. LastLocalValue resets to EmitStartPt when it makes sense
/// (for example, on function calls)
/// \brief The top most instruction in the current block that is allowed for
/// emitting local variables. LastLocalValue resets to EmitStartPt when it
/// makes sense (for example, on function calls)
MachineInstr *EmitStartPt;
public:
/// Return the position of the last instruction emitted for materializing
/// constants for use in the current block.
/// \brief Return the position of the last instruction emitted for
/// materializing constants for use in the current block.
MachineInstr *getLastLocalValue() { return LastLocalValue; }
/// Update the position of the last instruction emitted for materializing
/// constants for use in the current block.
/// \brief Update the position of the last instruction emitted for
/// materializing constants for use in the current block.
void setLastLocalValue(MachineInstr *I) {
EmitStartPt = I;
LastLocalValue = I;
}
/// Set the current block to which generated machine instructions will be
/// appended, and clear the local CSE map.
/// \brief Set the current block to which generated machine instructions will
/// be appended, and clear the local CSE map.
void startNewBlock();
/// Return current debug location information.
/// \brief Return current debug location information.
DebugLoc getCurDebugLoc() const { return DbgLoc; }
/// Do "fast" instruction selection for function arguments and append machine
/// instructions to the current block. Return true if it is successful.
/// \brief Do "fast" instruction selection for function arguments and append
/// the machine instructions to the current block. Returns true when
/// successful.
bool LowerArguments();
/// Do "fast" instruction selection for the given LLVM IR instruction, and
/// append generated machine instructions to the current block. Return true if
/// selection was successful.
/// \brief Do "fast" instruction selection for the given LLVM IR instruction
/// and append the generated machine instructions to the current block.
/// Returns true if selection was successful.
bool SelectInstruction(const Instruction *I);
/// Do "fast" instruction selection for the given LLVM IR operator
/// \brief Do "fast" instruction selection for the given LLVM IR operator
/// (Instruction or ConstantExpr), and append generated machine instructions
/// to the current block. Return true if selection was successful.
bool SelectOperator(const User *I, unsigned Opcode);
bool selectOperator(const User *I, unsigned Opcode);
/// Create a virtual register and arrange for it to be assigned the value for
/// the given LLVM value.
/// \brief Create a virtual register and arrange for it to be assigned the
/// value for the given LLVM value.
unsigned getRegForValue(const Value *V);
/// Look up the value to see if its value is already cached in a register. It
/// may be defined by instructions across blocks or defined locally.
/// \brief Look up the value to see if its value is already cached in a
/// register. It may be defined by instructions across blocks or defined
/// locally.
unsigned lookUpRegForValue(const Value *V);
/// This is a wrapper around getRegForValue that also takes care of truncating
/// or sign-extending the given getelementptr index value.
/// \brief This is a wrapper around getRegForValue that also takes care of
/// truncating or sign-extending the given getelementptr index value.
std::pair<unsigned, bool> getRegForGEPIndex(const Value *V);
/// \brief We're checking to see if we can fold \p LI into \p FoldInst. Note
@ -285,11 +264,11 @@ public:
return false;
}
/// Reset InsertPt to prepare for inserting instructions into the current
/// block.
/// \brief Reset InsertPt to prepare for inserting instructions into the
/// current block.
void recomputeInsertPt();
/// Remove all dead instructions between the I and E.
/// \brief Remove all dead instructions between the I and E.
void removeDeadCode(MachineBasicBlock::iterator I,
MachineBasicBlock::iterator E);
@ -298,11 +277,11 @@ public:
DebugLoc DL;
};
/// Prepare InsertPt to begin inserting instructions into the local value area
/// and return the old insert position.
/// \brief Prepare InsertPt to begin inserting instructions into the local
/// value area and return the old insert position.
SavePoint enterLocalValueArea();
/// Reset InsertPt to the given old insert position.
/// \brief Reset InsertPt to the given old insert position.
void leaveLocalValueArea(SavePoint Old);
virtual ~FastISel();
@ -312,208 +291,181 @@ protected:
const TargetLibraryInfo *LibInfo,
bool SkipTargetIndependentISel = false);
/// This method is called by target-independent code when the normal FastISel
/// process fails to select an instruction. This gives targets a chance to
/// emit code for anything that doesn't fit into FastISel's framework. It
/// returns true if it was successful.
/// \brief This method is called by target-independent code when the normal
/// FastISel process fails to select an instruction. This gives targets a
/// chance to emit code for anything that doesn't fit into FastISel's
/// framework. It returns true if it was successful.
virtual bool TargetSelectInstruction(const Instruction *I) = 0;
/// This method is called by target-independent code to do target specific
/// argument lowering. It returns true if it was successful.
/// \brief This method is called by target-independent code to do target-
/// specific argument lowering. It returns true if it was successful.
virtual bool FastLowerArguments();
/// \brief This method is called by target-independent code to do target
/// \brief This method is called by target-independent code to do target-
/// specific call lowering. It returns true if it was successful.
virtual bool FastLowerCall(CallLoweringInfo &CLI);
/// \brief This method is called by target-independent code to do target
/// \brief This method is called by target-independent code to do target-
/// specific intrinsic lowering. It returns true if it was successful.
virtual bool FastLowerIntrinsicCall(const IntrinsicInst *II);
/// This method is called by target-independent code to request that an
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type and opcode be emitted.
virtual unsigned FastEmit_(MVT VT,
MVT RetVT,
unsigned Opcode);
virtual unsigned FastEmit_(MVT VT, MVT RetVT, unsigned Opcode);
/// This method is called by target-independent code to request that an
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type, opcode, and register operand be emitted.
virtual unsigned FastEmit_r(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill);
virtual unsigned FastEmit_r(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
bool Op0IsKill);
/// This method is called by target-independent code to request that an
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type, opcode, and register operands be emitted.
virtual unsigned FastEmit_rr(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill);
virtual unsigned FastEmit_rr(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
bool Op0IsKill, unsigned Op1, bool Op1IsKill);
/// This method is called by target-independent code to request that an
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type, opcode, and register and immediate
/// operands be emitted.
virtual unsigned FastEmit_ri(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
uint64_t Imm);
// operands be emitted.
virtual unsigned FastEmit_ri(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
bool Op0IsKill, uint64_t Imm);
/// This method is called by target-independent code to request that an
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type, opcode, and register and floating-point
/// immediate operands be emitted.
virtual unsigned FastEmit_rf(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
const ConstantFP *FPImm);
virtual unsigned FastEmit_rf(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
bool Op0IsKill, const ConstantFP *FPImm);
/// This method is called by target-independent code to request that an
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type, opcode, and register and immediate
/// operands be emitted.
virtual unsigned FastEmit_rri(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill,
uint64_t Imm);
virtual unsigned FastEmit_rri(MVT VT, MVT RetVT, unsigned Opcode,
unsigned Op0, bool Op0IsKill, unsigned Op1,
bool Op1IsKill, uint64_t Imm);
/// \brief This method is a wrapper of FastEmit_ri.
///
///
/// It first tries to emit an instruction with an immediate operand using
/// FastEmit_ri. If that fails, it materializes the immediate into a register
/// and try FastEmit_rr instead.
unsigned FastEmit_ri_(MVT VT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
unsigned FastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0, bool Op0IsKill,
uint64_t Imm, MVT ImmType);
/// This method is called by target-independent code to request that an
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type, opcode, and immediate operand be emitted.
virtual unsigned FastEmit_i(MVT VT,
MVT RetVT,
unsigned Opcode,
uint64_t Imm);
virtual unsigned FastEmit_i(MVT VT, MVT RetVT, unsigned Opcode, uint64_t Imm);
/// This method is called by target-independent code to request that an
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type, opcode, and floating-point immediate
/// operand be emitted.
virtual unsigned FastEmit_f(MVT VT,
MVT RetVT,
unsigned Opcode,
virtual unsigned FastEmit_f(MVT VT, MVT RetVT, unsigned Opcode,
const ConstantFP *FPImm);
/// Emit a MachineInstr with no operands and a result register in the given
/// register class.
/// \brief Emit a MachineInstr with no operands and a result register in the
/// given register class.
unsigned FastEmitInst_(unsigned MachineInstOpcode,
const TargetRegisterClass *RC);
/// Emit a MachineInstr with one register operand and a result register in the
/// given register class.
/// \brief Emit a MachineInstr with one register operand and a result register
/// in the given register class.
unsigned FastEmitInst_r(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill);
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill);
/// Emit a MachineInstr with two register operands and a result register in
/// the given register class.
/// \brief Emit a MachineInstr with two register operands and a result
/// register in the given register class.
unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill);
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, unsigned Op1, bool Op1IsKill);
/// Emit a MachineInstr with three register operands and a result register in
/// the given register class.
/// \brief Emit a MachineInstr with three register operands and a result
/// register in the given register class.
unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill,
unsigned Op2, bool Op2IsKill);
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, unsigned Op1, bool Op1IsKill,
unsigned Op2, bool Op2IsKill);
/// Emit a MachineInstr with a register operand, an immediate, and a result
/// register in the given register class.
/// \brief Emit a MachineInstr with a register operand, an immediate, and a
/// result register in the given register class.
unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
uint64_t Imm);
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, uint64_t Imm);
/// Emit a MachineInstr with one register operand and two immediate operands.
/// \brief Emit a MachineInstr with one register operand and two immediate
/// operands.
unsigned FastEmitInst_rii(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
uint64_t Imm1, uint64_t Imm2);
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, uint64_t Imm1, uint64_t Imm2);
/// Emit a MachineInstr with two register operands and a result register in
/// the given register class.
unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
const ConstantFP *FPImm);
/// Emit a MachineInstr with two register operands, an immediate, and a result
/// \brief Emit a MachineInstr with two register operands and a result
/// register in the given register class.
unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, const ConstantFP *FPImm);
/// \brief Emit a MachineInstr with two register operands, an immediate, and a
/// result register in the given register class.
unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, unsigned Op1, bool Op1IsKill,
uint64_t Imm);
/// Emit a MachineInstr with two register operands, two immediates operands,
/// and a result register in the given register class.
/// \brief Emit a MachineInstr with two register operands, two immediates
/// operands, and a result register in the given register class.
unsigned FastEmitInst_rrii(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, unsigned Op1, bool Op1IsKill,
uint64_t Imm1, uint64_t Imm2);
/// Emit a MachineInstr with a single immediate operand, and a result register
/// in the given register class.
/// \brief Emit a MachineInstr with a single immediate operand, and a result
/// register in the given register class.
unsigned FastEmitInst_i(unsigned MachineInstrOpcode,
const TargetRegisterClass *RC,
uint64_t Imm);
const TargetRegisterClass *RC, uint64_t Imm);
/// Emit a MachineInstr with a two immediate operands.
/// \brief Emit a MachineInstr with a two immediate operands.
unsigned FastEmitInst_ii(unsigned MachineInstrOpcode,
const TargetRegisterClass *RC,
uint64_t Imm1, uint64_t Imm2);
const TargetRegisterClass *RC, uint64_t Imm1,
uint64_t Imm2);
/// Emit a MachineInstr for an extract_subreg from a specified index of a
/// superregister to a specified type.
unsigned FastEmitInst_extractsubreg(MVT RetVT,
unsigned Op0, bool Op0IsKill,
/// \brief Emit a MachineInstr for an extract_subreg from a specified index of
/// a superregister to a specified type.
unsigned FastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, bool Op0IsKill,
uint32_t Idx);
/// Emit MachineInstrs to compute the value of Op with all but the least
/// significant bit set to zero.
unsigned FastEmitZExtFromI1(MVT VT,
unsigned Op0, bool Op0IsKill);
/// \brief Emit MachineInstrs to compute the value of Op with all but the
/// least significant bit set to zero.
unsigned FastEmitZExtFromI1(MVT VT, unsigned Op0, bool Op0IsKill);
/// Emit an unconditional branch to the given block, unless it is the
/// \brief Emit an unconditional branch to the given block, unless it is the
/// immediate (fall-through) successor, and update the CFG.
void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL);
void UpdateValueMap(const Value* I, unsigned Reg, unsigned NumRegs = 1);
/// \brief Update the value map to include the new mapping for this
/// instruction, or insert an extra copy to get the result in a previous
/// determined register.
///
/// NOTE: This is only necessary because we might select a block that uses a
/// value before we select the block that defines the value. It might be
/// possible to fix this by selecting blocks in reverse postorder.
void UpdateValueMap(const Value *I, unsigned Reg, unsigned NumRegs = 1);
unsigned createResultReg(const TargetRegisterClass *RC);
/// Try to constrain Op so that it is usable by argument OpNum of the provided
/// MCInstrDesc. If this fails, create a new virtual register in the correct
/// class and COPY the value there.
/// \brief Try to constrain Op so that it is usable by argument OpNum of the
/// provided MCInstrDesc. If this fails, create a new virtual register in the
/// correct class and COPY the value there.
unsigned constrainOperandRegClass(const MCInstrDesc &II, unsigned Op,
unsigned OpNum);
/// Emit a constant in a register using target-specific logic, such as
/// \brief Emit a constant in a register using target-specific logic, such as
/// constant pool loads.
virtual unsigned TargetMaterializeConstant(const Constant* C) {
return 0;
}
virtual unsigned TargetMaterializeConstant(const Constant *C) { return 0; }
/// Emit an alloca address in a register using target-specific logic.
virtual unsigned TargetMaterializeAlloca(const AllocaInst* C) {
return 0;
}
/// \brief Emit an alloca address in a register using target-specific logic.
virtual unsigned TargetMaterializeAlloca(const AllocaInst *C) { return 0; }
virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) {
/// \brief Emit the floating-point constant +0.0 in a register using target-
/// specific logic.
virtual unsigned TargetMaterializeFloatZero(const ConstantFP *CF) {
return 0;
}
@ -526,14 +478,14 @@ protected:
/// - \c Add has a constant operand.
bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
/// Test whether the given value has exactly one use.
/// \brief Test whether the given value has exactly one use.
bool hasTrivialKill(const Value *V);
/// \brief Create a machine mem operand from the given instruction.
MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const;
bool LowerCallTo(const CallInst *CI, const char *SymName, unsigned NumArgs);
bool LowerCallTo(CallLoweringInfo &CLI);
bool lowerCallTo(CallLoweringInfo &CLI);
bool isCommutativeIntrinsic(IntrinsicInst const *II) {
switch (II->getIntrinsicID()) {
@ -547,25 +499,20 @@ protected:
}
}
bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
bool SelectFNeg(const User *I);
bool SelectGetElementPtr(const User *I);
bool SelectStackmap(const CallInst *I);
bool SelectPatchpoint(const CallInst *I);
bool LowerCall(const CallInst *I);
bool SelectCall(const User *Call);
bool SelectIntrinsicCall(const IntrinsicInst *II);
bool SelectBitCast(const User *I);
bool SelectCast(const User *I, unsigned Opcode);
bool SelectExtractValue(const User *I);
bool SelectInsertValue(const User *I);
/// \brief Select and emit code for a binary operator instruction, which has
/// an opcode which directly corresponds to the given ISD opcode.
bool selectBinaryOp(const User *I, unsigned ISDOpcode);
bool selectFNeg(const User *I);
bool selectGetElementPtr(const User *I);
bool selectStackmap(const CallInst *I);
bool selectPatchpoint(const CallInst *I);
bool lowerCall(const CallInst *I);
bool selectCall(const User *Call);
bool selectIntrinsicCall(const IntrinsicInst *II);
bool selectBitCast(const User *I);
bool selectCast(const User *I, unsigned Opcode);
bool selectExtractValue(const User *I);
bool selectInsertValue(const User *I);
private:
/// \brief Handle PHI nodes in successor blocks.
@ -575,22 +522,24 @@ private:
/// 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.
bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
bool handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
/// \brief Helper for materializeRegForValue to materialize a constant in a
/// target-independent way.
unsigned MaterializeConstant(const Value *V, MVT VT);
unsigned materializeConstant(const Value *V, MVT VT);
/// Helper for getRegForVale. This function is called when the value isn't
/// already available in a register and must be materialized with new
/// \brief Helper for getRegForVale. This function is called when the value
/// isn't already available in a register and must be materialized with new
/// instructions.
unsigned materializeRegForValue(const Value *V, MVT VT);
/// Clears LocalValueMap and moves the area for the new local variables to the
/// beginning of the block. It helps to avoid spilling cached variables across
/// heavy instructions like calls.
/// \brief Clears LocalValueMap and moves the area for the new local variables
/// to the beginning of the block. It helps to avoid spilling cached variables
/// across heavy instructions like calls.
void flushLocalValueMap();
/// \brief Add a stackmap or patchpoint intrinsic call's live variable
/// operands to a stackmap or patchpoint machine instruction.
bool addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,
const CallInst *CI, unsigned StartIdx);
bool lowerCallOperands(const CallInst *CI, unsigned ArgIdx, unsigned NumArgs,
@ -598,6 +547,6 @@ private:
CallLoweringInfo &CLI);
};
}
} // end namespace llvm
#endif

File diff suppressed because it is too large Load Diff

View File

@ -3422,61 +3422,61 @@ bool AArch64FastISel::TargetSelectInstruction(const Instruction *I) {
return false;
case Instruction::Add:
if (!selectAddSub(I))
return SelectBinaryOp(I, ISD::ADD);
return selectBinaryOp(I, ISD::ADD);
return true;
case Instruction::Sub:
if (!selectAddSub(I))
return SelectBinaryOp(I, ISD::SUB);
return selectBinaryOp(I, ISD::SUB);
return true;
case Instruction::FAdd:
return SelectBinaryOp(I, ISD::FADD);
return selectBinaryOp(I, ISD::FADD);
case Instruction::FSub:
// FNeg is currently represented in LLVM IR as a special case of FSub.
if (BinaryOperator::isFNeg(I))
return SelectFNeg(I);
return SelectBinaryOp(I, ISD::FSUB);
return selectFNeg(I);
return selectBinaryOp(I, ISD::FSUB);
case Instruction::Mul:
if (!SelectBinaryOp(I, ISD::MUL))
if (!selectBinaryOp(I, ISD::MUL))
return SelectMul(I);
return true;
case Instruction::FMul:
return SelectBinaryOp(I, ISD::FMUL);
return selectBinaryOp(I, ISD::FMUL);
case Instruction::SDiv:
return SelectBinaryOp(I, ISD::SDIV);
return selectBinaryOp(I, ISD::SDIV);
case Instruction::UDiv:
return SelectBinaryOp(I, ISD::UDIV);
return selectBinaryOp(I, ISD::UDIV);
case Instruction::FDiv:
return SelectBinaryOp(I, ISD::FDIV);
return selectBinaryOp(I, ISD::FDIV);
case Instruction::SRem:
if (!SelectBinaryOp(I, ISD::SREM))
if (!selectBinaryOp(I, ISD::SREM))
return SelectRem(I, ISD::SREM);
return true;
case Instruction::URem:
if (!SelectBinaryOp(I, ISD::UREM))
if (!selectBinaryOp(I, ISD::UREM))
return SelectRem(I, ISD::UREM);
return true;
case Instruction::FRem:
return SelectBinaryOp(I, ISD::FREM);
return selectBinaryOp(I, ISD::FREM);
case Instruction::Shl:
if (!SelectShift(I))
return SelectBinaryOp(I, ISD::SHL);
return selectBinaryOp(I, ISD::SHL);
return true;
case Instruction::LShr:
if (!SelectShift(I))
return SelectBinaryOp(I, ISD::SRL);
return selectBinaryOp(I, ISD::SRL);
return true;
case Instruction::AShr:
if (!SelectShift(I))
return SelectBinaryOp(I, ISD::SRA);
return selectBinaryOp(I, ISD::SRA);
return true;
case Instruction::And:
return SelectBinaryOp(I, ISD::AND);
return selectBinaryOp(I, ISD::AND);
case Instruction::Or:
return SelectBinaryOp(I, ISD::OR);
return selectBinaryOp(I, ISD::OR);
case Instruction::Xor:
return SelectBinaryOp(I, ISD::XOR);
return selectBinaryOp(I, ISD::XOR);
case Instruction::GetElementPtr:
return SelectGetElementPtr(I);
return selectGetElementPtr(I);
case Instruction::Br:
return SelectBranch(I);
case Instruction::IndirectBr:
@ -3493,27 +3493,27 @@ bool AArch64FastISel::TargetSelectInstruction(const Instruction *I) {
// Dynamic-sized alloca is not handled yet.
return false;
case Instruction::Call:
return SelectCall(I);
return selectCall(I);
case Instruction::BitCast:
if (!FastISel::SelectBitCast(I))
if (!FastISel::selectBitCast(I))
return SelectBitCast(I);
return true;
case Instruction::FPToSI:
if (!SelectCast(I, ISD::FP_TO_SINT))
if (!selectCast(I, ISD::FP_TO_SINT))
return SelectFPToInt(I, /*Signed=*/true);
return true;
case Instruction::FPToUI:
return SelectFPToInt(I, /*Signed=*/false);
case Instruction::ZExt:
if (!SelectCast(I, ISD::ZERO_EXTEND))
if (!selectCast(I, ISD::ZERO_EXTEND))
return SelectIntExt(I);
return true;
case Instruction::SExt:
if (!SelectCast(I, ISD::SIGN_EXTEND))
if (!selectCast(I, ISD::SIGN_EXTEND))
return SelectIntExt(I);
return true;
case Instruction::Trunc:
if (!SelectCast(I, ISD::TRUNCATE))
if (!selectCast(I, ISD::TRUNCATE))
return SelectTrunc(I);
return true;
case Instruction::FPExt:
@ -3521,7 +3521,7 @@ bool AArch64FastISel::TargetSelectInstruction(const Instruction *I) {
case Instruction::FPTrunc:
return SelectFPTrunc(I);
case Instruction::SIToFP:
if (!SelectCast(I, ISD::SINT_TO_FP))
if (!selectCast(I, ISD::SINT_TO_FP))
return SelectIntToFP(I, /*Signed=*/true);
return true;
case Instruction::UIToFP:
@ -3531,9 +3531,9 @@ bool AArch64FastISel::TargetSelectInstruction(const Instruction *I) {
EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
EVT DstVT = TLI.getValueType(I->getType());
if (DstVT.bitsGT(SrcVT))
return SelectCast(I, ISD::ZERO_EXTEND);
return selectCast(I, ISD::ZERO_EXTEND);
if (DstVT.bitsLT(SrcVT))
return SelectCast(I, ISD::TRUNCATE);
return selectCast(I, ISD::TRUNCATE);
unsigned Reg = getRegForValue(I->getOperand(0));
if (!Reg)
return false;
@ -3541,7 +3541,7 @@ bool AArch64FastISel::TargetSelectInstruction(const Instruction *I) {
return true;
}
case Instruction::ExtractValue:
return SelectExtractValue(I);
return selectExtractValue(I);
case Instruction::PHI:
llvm_unreachable("FastISel shouldn't visit PHI nodes!");
case Instruction::Load: