Go to the documentation of this file.
32 #define DEBUG_TYPE "bpf-lower"
36 cl::desc(
"Expand memcpy into load/store pairs in order"));
173 unsigned CommonMaxStores =
192 bool BPFTargetLowering::isTruncateFree(
Type *Ty1,
Type *Ty2)
const {
197 return NumBits1 > NumBits2;
200 bool BPFTargetLowering::isTruncateFree(
EVT VT1,
EVT VT2)
const {
205 return NumBits1 > NumBits2;
208 bool BPFTargetLowering::isZExtFree(
Type *Ty1,
Type *Ty2)
const {
213 return NumBits1 == 32 && NumBits2 == 64;
216 bool BPFTargetLowering::isZExtFree(
EVT VT1,
EVT VT2)
const {
221 return NumBits1 == 32 && NumBits2 == 64;
226 if (Constraint.
size() == 1) {
227 switch (Constraint[0]) {
238 std::pair<unsigned, const TargetRegisterClass *>
242 if (Constraint.
size() == 1)
244 switch (Constraint[0]) {
246 return std::make_pair(0U, &BPF::GPRRegClass);
249 return std::make_pair(0U, &BPF::GPR32RegClass);
258 void BPFTargetLowering::ReplaceNodeResults(
272 err_msg =
"Unsupported atomic operations, please use 32/64 bit version";
274 err_msg =
"Unsupported atomic operations, please use 64 bit version";
283 switch (
Op.getOpcode()) {
285 return LowerBR_CC(
Op, DAG);
287 return LowerGlobalAddress(
Op, DAG);
289 return LowerSELECT_CC(
Op, DAG);
298 #include "BPFGenCallingConv.inc"
300 SDValue BPFTargetLowering::LowerFormalArguments(
318 CCInfo.AnalyzeFormalArguments(
Ins,
getHasAlu32() ? CC_BPF32 : CC_BPF64);
320 for (
auto &VA : ArgLocs) {
323 EVT RegVT = VA.getLocVT();
327 errs() <<
"LowerFormalArguments Unhandled argument type: "
334 SimpleTy ==
MVT::i64 ? &BPF::GPRRegClass : &BPF::GPR32RegClass);
350 InVals.push_back(ArgValue);
355 fail(
DL, DAG,
"defined with too many args");
361 fail(
DL, DAG,
"functions with VarArgs or StructRet are not supported");
367 const unsigned BPFTargetLowering::MaxArgs = 5;
372 auto &Outs = CLI.
Outs;
397 CCInfo.AnalyzeCallOperands(Outs,
getHasAlu32() ? CC_BPF32 : CC_BPF64);
399 unsigned NumBytes = CCInfo.getNextStackOffset();
401 if (Outs.size() > MaxArgs)
402 fail(CLI.
DL, DAG,
"too many args to ", Callee);
404 for (
auto &
Arg : Outs) {
409 fail(CLI.
DL, DAG,
"pass by value not supported ", Callee);
419 e =
std::min(
static_cast<unsigned>(ArgLocs.size()), MaxArgs);
443 RegsToPass.push_back(std::make_pair(VA.
getLocReg(),
Arg));
453 for (
auto &
Reg : RegsToPass) {
466 fail(CLI.
DL, DAG,
Twine(
"A call to built-in function '"
468 +
"' is not supported."));
474 Ops.push_back(Chain);
475 Ops.push_back(Callee);
479 for (
auto &
Reg : RegsToPass)
483 Ops.push_back(InFlag);
496 return LowerCallResult(Chain, InFlag, CallConv, IsVarArg,
Ins, CLI.
DL, DAG,
516 fail(
DL, DAG,
"only integer returns supported");
521 CCInfo.AnalyzeReturn(Outs,
getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
527 for (
unsigned i = 0;
i != RVLocs.size(); ++
i) {
543 RetOps.push_back(
Flag);
548 SDValue BPFTargetLowering::LowerCallResult(
558 if (
Ins.size() >= 2) {
559 fail(
DL, DAG,
"only small returns supported");
560 for (
unsigned i = 0,
e =
Ins.size();
i !=
e; ++
i)
565 CCInfo.AnalyzeCallResult(
Ins,
getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
568 for (
auto &Val : RVLocs) {
570 Val.getValVT(), InFlag).
getValue(1);
572 InVals.push_back(Chain.
getValue(0));
630 return "BPFISD::RET_FLAG";
632 return "BPFISD::CALL";
634 return "BPFISD::SELECT_CC";
636 return "BPFISD::BR_CC";
638 return "BPFISD::Wrapper";
640 return "BPFISD::MEMCPY";
647 auto N = cast<GlobalAddressSDNode>(
Op);
648 assert(
N->getOffset() == 0 &&
"Invalid offset for global address");
659 unsigned Reg,
bool isSigned)
const {
662 int RShiftOp = isSigned ? BPF::SRA_ri : BPF::SRL_ri;
686 BPFTargetLowering::EmitInstrWithCustomInserterMemcpy(
MachineInstr &
MI,
710 MIB.addReg(ScratchReg,
721 unsigned Opc =
MI.getOpcode();
723 Opc == BPF::Select_64_32 ||
724 Opc == BPF::Select_32 ||
725 Opc == BPF::Select_32_64);
730 bool isSelectRIOp = (Opc == BPF::Select_Ri ||
731 Opc == BPF::Select_Ri_64_32 ||
732 Opc == BPF::Select_Ri_32 ||
733 Opc == BPF::Select_Ri_32_64);
736 assert((isSelectRROp || isSelectRIOp || isMemcpyOp) &&
737 "Unexpected instr type to insert");
741 return EmitInstrWithCustomInserterMemcpy(
MI,
BB);
743 bool is32BitCmp = (Opc == BPF::Select_32 ||
744 Opc == BPF::Select_32_64 ||
745 Opc == BPF::Select_Ri_32 ||
746 Opc == BPF::Select_Ri_32_64);
765 F->insert(
I, Copy0MBB);
766 F->insert(
I, Copy1MBB);
773 BB->addSuccessor(Copy0MBB);
774 BB->addSuccessor(Copy1MBB);
777 int CC =
MI.getOperand(3).getImm();
780 #define SET_NEWCC(X, Y) \
782 if (is32BitCmp && HasJmp32) \
783 NewCC = isSelectRROp ? BPF::Y##_rr_32 : BPF::Y##_ri_32; \
785 NewCC = isSelectRROp ? BPF::Y##_rr : BPF::Y##_ri; \
814 if (is32BitCmp && !HasJmp32)
815 LHS = EmitSubregExt(
MI,
BB,
LHS, isSignedCmp);
820 if (is32BitCmp && !HasJmp32)
821 RHS = EmitSubregExt(
MI,
BB,
RHS, isSignedCmp);
825 int64_t imm32 =
MI.getOperand(2).getImm();
838 BB->addSuccessor(Copy1MBB);
850 MI.eraseFromParent();
864 bool BPFTargetLowering::isLegalAddressingMode(
const DataLayout &
DL,
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
A parsed version of the target data layout string in and methods for querying it.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
@ BR_JT
BR_JT - Jumptable branch.
Diagnostic information for unsupported feature in backend.
CCState - This class holds information needed while lowering arguments and return values.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
SDNode * getNode() const
get the SDNode which holds the desired result
@ BSWAP
Byte Swap and Counting operators.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
SDValue getValueType(EVT)
A raw_ostream that writes to an std::string.
const TargetRegisterInfo * getRegisterInfo() const override
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
BPFTargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
bool getHasJmpExt() const
Reg
All possible values of the reg field in the ModR/M byte.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Represents one node in the SelectionDAG.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
Function Alias Analysis Results
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
unsigned const TargetRegisterInfo * TRI
LLVMContext * getContext() const
@ BRCOND
BRCOND - Conditional branch.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
SDValue getRegister(unsigned Reg, EVT VT)
LLVM Basic Block Representation.
@ EarlyClobber
Register definition happens before uses.
@ BRIND
BRIND - Indirect branch.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static auto integer_valuetypes()
@ BR_CC
BR_CC - Conditional branch.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the ValueType of the result of SETCC operations.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
TargetInstrInfo - Interface to description of machine instruction set.
CCValAssign - Represent assignment of one arg/retval to a location.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Register getLocReg() const
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
BPFTargetLowering(const TargetMachine &TM, const BPFSubtarget &STI)
const HexagonInstrInfo * TII
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
bool isInteger() const
Return true if this is an integer or a vector integer type.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
LocInfo getLocInfo() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
bool isIntegerTy() const
True if this is an instance of IntegerType.
SmallVector< ISD::OutputArg, 32 > Outs
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
constexpr bool isInt< 32 >(int64_t x)
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Type * getReturnType() const
Returns the type of the ret val.
Representation of each machine instruction.
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
This is an important class for using LLVM in a threaded context.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
initializer< Ty > init(const Ty &Val)
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
SDValue getValue(unsigned R) const
This structure contains all information that is necessary for lowering calls.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const BPFSelectionDAGInfo * getSelectionDAGInfo() const override
Primary interface to the complete machine description for the target machine.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
void print(raw_ostream &OS, const SelectionDAG *G=nullptr) const
static cl::opt< bool > BPFExpandMemcpyInOrder("bpf-expand-memcpy-in-order", cl::Hidden, cl::init(false), cl::desc("Expand memcpy into load/store pairs in order"))
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
@ C
C - The default llvm calling convention, compatible with C.
SmallVector< ISD::InputArg, 32 > Ins
@ Fast
Fast - This calling convention attempts to make calls as fast as possible (e.g.
unsigned getCommonMaxStoresPerMemFunc() const
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
StringRef - Represent a constant reference to a string, i.e.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
const CustomOperand< const MCSubtargetInfo & > Msg[]
amdgpu Simplify well known AMD library false FunctionCallee Callee
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override
Return the type to use for a scalar shift opcode, given the shifted amount type.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
Function & getFunction()
Return the LLVM function that this machine code represents.
Iterator for intrusive lists based on ilist_node.
CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
@ Define
Register definition.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
@ ZeroOrOneBooleanContent
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
SmallVector< SDValue, 32 > OutVals
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const char LLVMTargetMachineRef TM
bool getHasJmpExt() const
MachineFunction & getMachineFunction() const
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
bool isAggregateType() const
Return true if the type is an aggregate type.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
@ SIGN_EXTEND
Conversion operators.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.