34 #define DEBUG_TYPE "bpf-lower" 38 cl::desc(
"Expand memcpy into load/store pairs in order"));
156 unsigned CommonMaxStores =
173 std::pair<unsigned, const TargetRegisterClass *>
177 if (Constraint.
size() == 1)
179 switch (Constraint[0]) {
181 return std::make_pair(0U, &BPF::GPRRegClass);
192 return LowerBR_CC(Op, DAG);
194 return LowerGlobalAddress(Op, DAG);
196 return LowerSELECT_CC(Op, DAG);
203 #include "BPFGenCallingConv.inc" 205 SDValue BPFTargetLowering::LowerFormalArguments(
225 for (
auto &VA : ArgLocs) {
228 EVT RegVT = VA.getLocVT();
232 errs() <<
"LowerFormalArguments Unhandled argument type: " 240 &BPF::GPR32RegClass);
261 fail(DL, DAG,
"defined with too many args");
267 fail(DL, DAG,
"functions with VarArgs or StructRet are not supported");
273 const unsigned BPFTargetLowering::MaxArgs = 5;
278 auto &Outs = CLI.
Outs;
305 unsigned NumBytes = CCInfo.getNextStackOffset();
307 if (Outs.size() > MaxArgs)
308 fail(CLI.
DL, DAG,
"too many args to ", Callee);
310 for (
auto &
Arg : Outs) {
315 fail(CLI.
DL, DAG,
"pass by value not supported ", Callee);
325 e = std::min(static_cast<unsigned>(ArgLocs.
size()), MaxArgs);
359 for (
auto &
Reg : RegsToPass) {
372 fail(CLI.
DL, DAG,
Twine(
"A call to built-in function '" 374 +
"' is not supported."));
385 for (
auto &
Reg : RegsToPass)
402 return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, Ins, CLI.
DL, DAG,
422 fail(DL, DAG,
"only integer returns supported");
427 CCInfo.AnalyzeReturn(Outs,
getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
433 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
454 SDValue BPFTargetLowering::LowerCallResult(
464 if (Ins.
size() >= 2) {
465 fail(DL, DAG,
"only small returns supported");
466 for (
unsigned i = 0, e = Ins.
size(); i != e; ++i)
471 CCInfo.AnalyzeCallResult(Ins,
getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
474 for (
auto &Val : RVLocs) {
476 Val.getValVT(), InFlag).getValue(1);
526 SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
536 return "BPFISD::RET_FLAG";
538 return "BPFISD::CALL";
540 return "BPFISD::SELECT_CC";
542 return "BPFISD::BR_CC";
544 return "BPFISD::Wrapper";
546 return "BPFISD::MEMCPY";
553 auto N = cast<GlobalAddressSDNode>(
Op);
554 assert(
N->getOffset() == 0 &&
"Invalid offset for global address");
565 unsigned Reg,
bool isSigned)
const {
568 int RShiftOp = isSigned ? BPF::SRA_ri : BPF::SRL_ri;
576 BuildMI(BB, DL, TII.
get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
577 BuildMI(BB, DL, TII.
get(BPF::SLL_ri), PromotedReg1)
578 .addReg(PromotedReg0).
addImm(32);
579 BuildMI(BB, DL, TII.
get(RShiftOp), PromotedReg2)
580 .addReg(PromotedReg1).
addImm(32);
586 BPFTargetLowering::EmitInstrWithCustomInserterMemcpy(
MachineInstr &MI,
623 Opc == BPF::Select_64_32 ||
624 Opc == BPF::Select_32 ||
625 Opc == BPF::Select_32_64);
630 bool isSelectRIOp = (Opc == BPF::Select_Ri ||
631 Opc == BPF::Select_Ri_64_32 ||
632 Opc == BPF::Select_Ri_32 ||
633 Opc == BPF::Select_Ri_32_64);
636 assert((isSelectRROp || isSelectRIOp || isMemcpyOp) &&
637 "Unexpected instr type to insert");
641 return EmitInstrWithCustomInserterMemcpy(MI, BB);
643 bool is32BitCmp = (Opc == BPF::Select_32 ||
644 Opc == BPF::Select_32_64 ||
645 Opc == BPF::Select_Ri_32 ||
646 Opc == BPF::Select_Ri_32_64);
681 NewCC = isSelectRROp ? BPF::JSGT_rr : BPF::JSGT_ri;
684 NewCC = isSelectRROp ? BPF::JUGT_rr : BPF::JUGT_ri;
687 NewCC = isSelectRROp ? BPF::JSGE_rr : BPF::JSGE_ri;
690 NewCC = isSelectRROp ? BPF::JUGE_rr : BPF::JUGE_ri;
693 NewCC = isSelectRROp ? BPF::JEQ_rr : BPF::JEQ_ri;
696 NewCC = isSelectRROp ? BPF::JNE_rr : BPF::JNE_ri;
699 NewCC = isSelectRROp ? BPF::JSLT_rr : BPF::JSLT_ri;
702 NewCC = isSelectRROp ? BPF::JULT_rr : BPF::JULT_ri;
705 NewCC = isSelectRROp ? BPF::JSLE_rr : BPF::JSLE_ri;
708 NewCC = isSelectRROp ? BPF::JULE_rr : BPF::JULE_ri;
728 LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp);
734 RHS = EmitSubregExt(MI, BB, RHS, isSignedCmp);
A parsed version of the target data layout string in and methods for querying it. ...
EVT getValueType() const
Return the ValueType of the referenced return value.
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...
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
C - The default llvm calling convention, compatible with C.
static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC)
Diagnostic information for unsupported feature in backend.
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)...
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
BR_CC - Conditional branch.
This class represents lattice values for constants.
void addLiveIn(unsigned Reg, unsigned vreg=0)
addLiveIn - Add the specified register as a live-in.
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
unsigned getReg() const
getReg - Returns the register number.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
Return the register class that should be used for the specified value type.
unsigned const TargetRegisterInfo * TRI
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations...
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override
EVT is not used in-tree, but is used by out-of-tree target.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const HexagonInstrInfo * TII
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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...
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LocInfo getLocInfo() const
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
SmallVector< ISD::InputArg, 32 > Ins
STACKSAVE - STACKSAVE has one operand, an input chain.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
MachineFunction & getMachineFunction() const
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose...
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"))
SmallVector< ISD::OutputArg, 32 > Outs
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
virtual const TargetInstrInfo * getInstrInfo() const
amdgpu Simplify well known AMD library false Value * Callee
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
Type * getReturnType() const
Returns the type of the ret val.
unsigned const MachineRegisterInfo * MRI
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...
LLVM Basic Block Representation.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This is an important class for using LLVM in a threaded context.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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 ...
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned getCommonMaxStoresPerMemFunc() const
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
void setPrefFunctionAlignment(unsigned Align)
Set the target's preferred function alignment.
self_iterator getIterator()
CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y)...
unsigned MaxStoresPerMemmove
Specify maximum bytes of store instructions per memmove call.
Bit counting operators with an undefined result for zero inputs.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This structure contains all information that is necessary for lowering calls.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const TargetRegisterInfo * getRegisterInfo() const override
Iterator for intrusive lists based on ilist_node.
CCState - This class holds information needed while lowering arguments and return values...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
constexpr bool isInt< 32 >(int64_t x)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const DebugLoc & getDebugLoc() const
CCValAssign - Represent assignment of one arg/retval to a location.
BRCOND - Conditional branch.
bool isAggregateType() const
Return true if the type is an aggregate type.
Byte Swap and Counting operators.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const BPFSelectionDAGInfo * getSelectionDAGInfo() const override
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
const Function & getFunction() const
Return the LLVM function that this machine code represents.
static mvt_range integer_valuetypes()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Select(COND, TRUEVAL, FALSEVAL).
void setMinFunctionAlignment(unsigned Align)
Set the target's minimum function alignment (in log2(bytes))
ZERO_EXTEND - Used for integer types, zeroing the new bits.
void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
ANY_EXTEND - Used for integer types. The high bits are undefined.
amdgpu Simplify well known AMD library false Value Value * Arg
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
BR_JT - Jumptable branch.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
SmallVector< SDValue, 32 > OutVals
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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 '...
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
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.
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
bool getHasJmpExt() const
unsigned MaxStoresPerMemmoveOptSize
Maximum number of store instructions that may be substituted for a call to memmove, used for functions with OptSize attribute.
unsigned MaxStoresPerMemcpyOptSize
Maximum number of store operations that may be substituted for a call to memcpy, used for functions w...
void setStackPointerRegisterToSaveRestore(unsigned R)
If set to a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save and restore.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
unsigned getOpcode() const
SDValue getValue(unsigned R) const
unsigned MaxStoresPerMemcpy
Specify maximum bytes of store instructions per memcpy call.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
BPFTargetLowering(const TargetMachine &TM, const BPFSubtarget &STI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
A raw_ostream that writes to an std::string.
void print(raw_ostream &OS, const SelectionDAG *G=nullptr) const
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getValueType(EVT)
Primary interface to the complete machine description for the target machine.
StringRef - Represent a constant reference to a string, i.e.
SetCC operator - This evaluates to a true value iff the condition is true.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
unsigned MaxStoresPerMemsetOptSize
Maximum number of stores operations that may be substituted for the call to memset, used for functions with OptSize attribute.
const SDValue & getOperand(unsigned i) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
unsigned getLocReg() const
TRUNCATE - Completely drop the high bits.
const MachineOperand & getOperand(unsigned i) const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
bool getHasJmpExt() const
static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg)
LLVMContext * getContext() const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
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...
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary...