diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Target/BPF | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/Target/BPF')
20 files changed, 435 insertions, 145 deletions
diff --git a/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp b/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp index ce1d2ecd9d266..1f5d5025bc7bc 100644 --- a/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp +++ b/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp @@ -493,7 +493,7 @@ bool BPFAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, bool BPFAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } -extern "C" void LLVMInitializeBPFAsmParser() { +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFAsmParser() { RegisterMCAsmParser<BPFAsmParser> X(getTheBPFTarget()); RegisterMCAsmParser<BPFAsmParser> Y(getTheBPFleTarget()); RegisterMCAsmParser<BPFAsmParser> Z(getTheBPFbeTarget()); diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp index 400701c4e5c22..a28816cc87b7d 100644 --- a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp +++ b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp @@ -117,6 +117,7 @@ public: struct CallInfo { uint32_t Kind; uint32_t AccessIndex; + uint32_t RecordAlignment; MDNode *Metadata; Value *Base; }; @@ -130,6 +131,8 @@ private: BPFPreserveFieldInfoAI = 4, }; + const DataLayout *DL = nullptr; + std::map<std::string, GlobalVariable *> GEPGlobals; // A map to link preserve_*_access_index instrinsic calls. std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain; @@ -154,11 +157,11 @@ private: void replaceWithGEP(std::vector<CallInst *> &CallList, uint32_t NumOfZerosIndex, uint32_t DIIndex); bool HasPreserveFieldInfoCall(CallInfoStack &CallStack); - void GetStorageBitRange(DICompositeType *CTy, DIDerivedType *MemberTy, - uint32_t AccessIndex, uint32_t &StartBitOffset, - uint32_t &EndBitOffset); + void GetStorageBitRange(DIDerivedType *MemberTy, uint32_t RecordAlignment, + uint32_t &StartBitOffset, uint32_t &EndBitOffset); uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy, - uint32_t AccessIndex, uint32_t PatchImm); + uint32_t AccessIndex, uint32_t PatchImm, + uint32_t RecordAlignment); Value *computeBaseAndAccessKey(CallInst *Call, CallInfo &CInfo, std::string &AccessKey, MDNode *&BaseMeta); @@ -182,6 +185,7 @@ bool BPFAbstractMemberAccess::runOnModule(Module &M) { if (M.debug_compile_units().empty()) return false; + DL = &M.getDataLayout(); return doTransformation(M); } @@ -243,6 +247,8 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, report_fatal_error("Missing metadata for llvm.preserve.array.access.index intrinsic"); CInfo.AccessIndex = getConstant(Call->getArgOperand(2)); CInfo.Base = Call->getArgOperand(0); + CInfo.RecordAlignment = + DL->getABITypeAlignment(CInfo.Base->getType()->getPointerElementType()); return true; } if (GV->getName().startswith("llvm.preserve.union.access.index")) { @@ -252,6 +258,8 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, report_fatal_error("Missing metadata for llvm.preserve.union.access.index intrinsic"); CInfo.AccessIndex = getConstant(Call->getArgOperand(1)); CInfo.Base = Call->getArgOperand(0); + CInfo.RecordAlignment = + DL->getABITypeAlignment(CInfo.Base->getType()->getPointerElementType()); return true; } if (GV->getName().startswith("llvm.preserve.struct.access.index")) { @@ -261,6 +269,8 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, report_fatal_error("Missing metadata for llvm.preserve.struct.access.index intrinsic"); CInfo.AccessIndex = getConstant(Call->getArgOperand(2)); CInfo.Base = Call->getArgOperand(0); + CInfo.RecordAlignment = + DL->getABITypeAlignment(CInfo.Base->getType()->getPointerElementType()); return true; } if (GV->getName().startswith("llvm.bpf.preserve.field.info")) { @@ -509,40 +519,29 @@ uint64_t BPFAbstractMemberAccess::getConstant(const Value *IndexValue) { } /// Get the start and the end of storage offset for \p MemberTy. -/// The storage bits are corresponding to the LLVM internal types, -/// and the storage bits for the member determines what load width -/// to use in order to extract the bitfield value. -void BPFAbstractMemberAccess::GetStorageBitRange(DICompositeType *CTy, - DIDerivedType *MemberTy, - uint32_t AccessIndex, +void BPFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy, + uint32_t RecordAlignment, uint32_t &StartBitOffset, uint32_t &EndBitOffset) { - auto SOff = dyn_cast<ConstantInt>(MemberTy->getStorageOffsetInBits()); - assert(SOff); - StartBitOffset = SOff->getZExtValue(); - - EndBitOffset = CTy->getSizeInBits(); - uint32_t Index = AccessIndex + 1; - for (; Index < CTy->getElements().size(); ++Index) { - auto Member = cast<DIDerivedType>(CTy->getElements()[Index]); - if (!Member->getStorageOffsetInBits()) { - EndBitOffset = Member->getOffsetInBits(); - break; - } - SOff = dyn_cast<ConstantInt>(Member->getStorageOffsetInBits()); - assert(SOff); - unsigned BitOffset = SOff->getZExtValue(); - if (BitOffset != StartBitOffset) { - EndBitOffset = BitOffset; - break; - } - } + uint32_t MemberBitSize = MemberTy->getSizeInBits(); + uint32_t MemberBitOffset = MemberTy->getOffsetInBits(); + uint32_t AlignBits = RecordAlignment * 8; + if (RecordAlignment > 8 || MemberBitSize > AlignBits) + report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, " + "requiring too big alignment"); + + StartBitOffset = MemberBitOffset & ~(AlignBits - 1); + if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize)) + report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, " + "cross alignment boundary"); + EndBitOffset = StartBitOffset + AlignBits; } uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy, uint32_t AccessIndex, - uint32_t PatchImm) { + uint32_t PatchImm, + uint32_t RecordAlignment) { if (InfoKind == BPFCoreSharedInfo::FIELD_EXISTENCE) return 1; @@ -557,9 +556,10 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, if (!MemberTy->isBitField()) { PatchImm += MemberTy->getOffsetInBits() >> 3; } else { - auto SOffset = dyn_cast<ConstantInt>(MemberTy->getStorageOffsetInBits()); - assert(SOffset); - PatchImm += SOffset->getZExtValue() >> 3; + unsigned SBitOffset, NextSBitOffset; + GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, + NextSBitOffset); + PatchImm += SBitOffset >> 3; } } return PatchImm; @@ -576,7 +576,7 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, return SizeInBits >> 3; unsigned SBitOffset, NextSBitOffset; - GetStorageBitRange(CTy, MemberTy, AccessIndex, SBitOffset, NextSBitOffset); + GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset); SizeInBits = NextSBitOffset - SBitOffset; if (SizeInBits & (SizeInBits - 1)) report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info"); @@ -636,7 +636,7 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, } unsigned SBitOffset, NextSBitOffset; - GetStorageBitRange(CTy, MemberTy, AccessIndex, SBitOffset, NextSBitOffset); + GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset); if (NextSBitOffset - SBitOffset > 64) report_fatal_error("too big field size for llvm.bpf.preserve.field.info"); @@ -667,7 +667,7 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, } unsigned SBitOffset, NextSBitOffset; - GetStorageBitRange(CTy, MemberTy, AccessIndex, SBitOffset, NextSBitOffset); + GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset); if (NextSBitOffset - SBitOffset > 64) report_fatal_error("too big field size for llvm.bpf.preserve.field.info"); @@ -822,14 +822,20 @@ Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call, AccessKey += ":" + std::to_string(AccessIndex); MDNode *MDN = CInfo.Metadata; + uint32_t RecordAlignment = CInfo.RecordAlignment; // At this stage, it cannot be pointer type. auto *CTy = cast<DICompositeType>(stripQualifiers(cast<DIType>(MDN))); - PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm); + PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm, + RecordAlignment); } - // Access key is the type name + reloc type + patched imm + access string, + // Access key is the + // "llvm." + type name + ":" + reloc type + ":" + patched imm + "$" + + // access string, // uniquely identifying one relocation. - AccessKey = TypeName + ":" + std::to_string(InfoKind) + ":" + + // The prefix "llvm." indicates this is a temporary global, which should + // not be emitted to ELF file. + AccessKey = "llvm." + TypeName + ":" + std::to_string(InfoKind) + ":" + std::to_string(PatchImm) + "$" + AccessKey; return Base; diff --git a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp index 218b0302927c5..b81386f479d30 100644 --- a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp +++ b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp @@ -148,7 +148,7 @@ void BPFAsmPrinter::EmitInstruction(const MachineInstr *MI) { } // Force static initialization. -extern "C" void LLVMInitializeBPFAsmPrinter() { +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFAsmPrinter() { RegisterAsmPrinter<BPFAsmPrinter> X(getTheBPFleTarget()); RegisterAsmPrinter<BPFAsmPrinter> Y(getTheBPFbeTarget()); RegisterAsmPrinter<BPFAsmPrinter> Z(getTheBPFTarget()); diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp index f2be0ff070d2f..6f5f58554d09c 100644 --- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp +++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp @@ -24,6 +24,7 @@ #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/IR/Constants.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/IntrinsicsBPF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.cpp b/llvm/lib/Target/BPF/BPFInstrInfo.cpp index 6de3a4084d3d4..626c204e99e6a 100644 --- a/llvm/lib/Target/BPF/BPFInstrInfo.cpp +++ b/llvm/lib/Target/BPF/BPFInstrInfo.cpp @@ -30,8 +30,8 @@ BPFInstrInfo::BPFInstrInfo() void BPFInstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - const DebugLoc &DL, unsigned DestReg, - unsigned SrcReg, bool KillSrc) const { + const DebugLoc &DL, MCRegister DestReg, + MCRegister SrcReg, bool KillSrc) const { if (BPF::GPRRegClass.contains(DestReg, SrcReg)) BuildMI(MBB, I, DL, get(BPF::MOV_rr), DestReg) .addReg(SrcReg, getKillRegState(KillSrc)); diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.h b/llvm/lib/Target/BPF/BPFInstrInfo.h index e4bd757da5608..22413d530e176 100644 --- a/llvm/lib/Target/BPF/BPFInstrInfo.h +++ b/llvm/lib/Target/BPF/BPFInstrInfo.h @@ -30,7 +30,7 @@ public: const BPFRegisterInfo &getRegisterInfo() const { return RI; } void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, + const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override; bool expandPostRAPseudo(MachineInstr &MI) const override; diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td index ae5a82a993033..0f39294daa2b9 100644 --- a/llvm/lib/Target/BPF/BPFInstrInfo.td +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td @@ -437,6 +437,25 @@ class LOAD<BPFWidthModifer SizeOp, string OpcodeStr, list<dag> Pattern> class LOADi64<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode> : LOAD<SizeOp, OpcodeStr, [(set i64:$dst, (OpNode ADDRri:$addr))]>; +let isCodeGenOnly = 1 in { + def CORE_MEM : TYPE_LD_ST<BPF_MEM.Value, BPF_W.Value, + (outs GPR:$dst), + (ins u64imm:$opcode, GPR:$src, u64imm:$offset), + "$dst = core_mem($opcode, $src, $offset)", + []>; + def CORE_ALU32_MEM : TYPE_LD_ST<BPF_MEM.Value, BPF_W.Value, + (outs GPR32:$dst), + (ins u64imm:$opcode, GPR:$src, u64imm:$offset), + "$dst = core_alu32_mem($opcode, $src, $offset)", + []>; + let Constraints = "$dst = $src" in { + def CORE_SHIFT : ALU_RR<BPF_ALU64, BPF_LSH, + (outs GPR:$dst), + (ins u64imm:$opcode, GPR:$src, u64imm:$offset), + "$dst = core_shift($opcode, $src, $offset)", + []>; + } +} let Predicates = [BPFNoALU32] in { def LDW : LOADi64<BPF_W, "u32", zextloadi32>; diff --git a/llvm/lib/Target/BPF/BPFMIPeephole.cpp b/llvm/lib/Target/BPF/BPFMIPeephole.cpp index e9eecc55c3c32..022267fbe3c21 100644 --- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp +++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp @@ -51,9 +51,14 @@ private: // Initialize class variables. void initialize(MachineFunction &MFParm); + bool isCopyFrom32Def(MachineInstr *CopyMI); + bool isInsnFrom32Def(MachineInstr *DefInsn); + bool isPhiFrom32Def(MachineInstr *MovMI); bool isMovFrom32Def(MachineInstr *MovMI); bool eliminateZExtSeq(void); + std::set<MachineInstr *> PhiInsns; + public: // Main entry point for this pass. @@ -75,42 +80,86 @@ void BPFMIPeephole::initialize(MachineFunction &MFParm) { LLVM_DEBUG(dbgs() << "*** BPF MachineSSA ZEXT Elim peephole pass ***\n\n"); } -bool BPFMIPeephole::isMovFrom32Def(MachineInstr *MovMI) +bool BPFMIPeephole::isCopyFrom32Def(MachineInstr *CopyMI) { - MachineInstr *DefInsn = MRI->getVRegDef(MovMI->getOperand(1).getReg()); + MachineOperand &opnd = CopyMI->getOperand(1); - LLVM_DEBUG(dbgs() << " Def of Mov Src:"); - LLVM_DEBUG(DefInsn->dump()); + if (!opnd.isReg()) + return false; - if (!DefInsn) + // Return false if getting value from a 32bit physical register. + // Most likely, this physical register is aliased to + // function call return value or current function parameters. + Register Reg = opnd.getReg(); + if (!Register::isVirtualRegister(Reg)) return false; - if (DefInsn->isPHI()) { - for (unsigned i = 1, e = DefInsn->getNumOperands(); i < e; i += 2) { - MachineOperand &opnd = DefInsn->getOperand(i); + if (MRI->getRegClass(Reg) == &BPF::GPRRegClass) + return false; - if (!opnd.isReg()) - return false; + MachineInstr *DefInsn = MRI->getVRegDef(Reg); + if (!isInsnFrom32Def(DefInsn)) + return false; - MachineInstr *PhiDef = MRI->getVRegDef(opnd.getReg()); - // quick check on PHI incoming definitions. - if (!PhiDef || PhiDef->isPHI() || PhiDef->getOpcode() == BPF::COPY) + return true; +} + +bool BPFMIPeephole::isPhiFrom32Def(MachineInstr *PhiMI) +{ + for (unsigned i = 1, e = PhiMI->getNumOperands(); i < e; i += 2) { + MachineOperand &opnd = PhiMI->getOperand(i); + + if (!opnd.isReg()) + return false; + + MachineInstr *PhiDef = MRI->getVRegDef(opnd.getReg()); + if (!PhiDef) + return false; + if (PhiDef->isPHI()) { + if (PhiInsns.find(PhiDef) != PhiInsns.end()) + return false; + PhiInsns.insert(PhiDef); + if (!isPhiFrom32Def(PhiDef)) return false; } + if (PhiDef->getOpcode() == BPF::COPY && !isCopyFrom32Def(PhiDef)) + return false; } - if (DefInsn->getOpcode() == BPF::COPY) { - MachineOperand &opnd = DefInsn->getOperand(1); + return true; +} - if (!opnd.isReg()) - return false; +// The \p DefInsn instruction defines a virtual register. +bool BPFMIPeephole::isInsnFrom32Def(MachineInstr *DefInsn) +{ + if (!DefInsn) + return false; - Register Reg = opnd.getReg(); - if ((Register::isVirtualRegister(Reg) && - MRI->getRegClass(Reg) == &BPF::GPRRegClass)) + if (DefInsn->isPHI()) { + if (PhiInsns.find(DefInsn) != PhiInsns.end()) + return false; + PhiInsns.insert(DefInsn); + if (!isPhiFrom32Def(DefInsn)) + return false; + } else if (DefInsn->getOpcode() == BPF::COPY) { + if (!isCopyFrom32Def(DefInsn)) return false; } + return true; +} + +bool BPFMIPeephole::isMovFrom32Def(MachineInstr *MovMI) +{ + MachineInstr *DefInsn = MRI->getVRegDef(MovMI->getOperand(1).getReg()); + + LLVM_DEBUG(dbgs() << " Def of Mov Src:"); + LLVM_DEBUG(DefInsn->dump()); + + PhiInsns.clear(); + if (!isInsnFrom32Def(DefInsn)) + return false; + LLVM_DEBUG(dbgs() << " One ZExt elim sequence identified.\n"); return true; diff --git a/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp b/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp index 9c689aed64178..5310f0f07b65f 100644 --- a/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp +++ b/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp @@ -53,6 +53,19 @@ private: void initialize(MachineFunction &MFParm); bool removeLD(void); + void processCandidate(MachineRegisterInfo *MRI, MachineBasicBlock &MBB, + MachineInstr &MI, Register &SrcReg, Register &DstReg, + const GlobalValue *GVal); + void processDstReg(MachineRegisterInfo *MRI, Register &DstReg, + Register &SrcReg, const GlobalValue *GVal, + bool doSrcRegProp); + void processInst(MachineRegisterInfo *MRI, MachineInstr *Inst, + MachineOperand *RelocOp, const GlobalValue *GVal); + void checkADDrr(MachineRegisterInfo *MRI, MachineOperand *RelocOp, + const GlobalValue *GVal); + void checkShift(MachineRegisterInfo *MRI, MachineBasicBlock &MBB, + MachineOperand *RelocOp, const GlobalValue *GVal, + unsigned Opcode); public: // Main entry point for this pass. @@ -71,6 +84,146 @@ void BPFMISimplifyPatchable::initialize(MachineFunction &MFParm) { LLVM_DEBUG(dbgs() << "*** BPF simplify patchable insts pass ***\n\n"); } +void BPFMISimplifyPatchable::checkADDrr(MachineRegisterInfo *MRI, + MachineOperand *RelocOp, const GlobalValue *GVal) { + const MachineInstr *Inst = RelocOp->getParent(); + const MachineOperand *Op1 = &Inst->getOperand(1); + const MachineOperand *Op2 = &Inst->getOperand(2); + const MachineOperand *BaseOp = (RelocOp == Op1) ? Op2 : Op1; + + // Go through all uses of %1 as in %1 = ADD_rr %2, %3 + const MachineOperand Op0 = Inst->getOperand(0); + auto Begin = MRI->use_begin(Op0.getReg()), End = MRI->use_end(); + decltype(End) NextI; + for (auto I = Begin; I != End; I = NextI) { + NextI = std::next(I); + // The candidate needs to have a unique definition. + if (!MRI->getUniqueVRegDef(I->getReg())) + continue; + + MachineInstr *DefInst = I->getParent(); + unsigned Opcode = DefInst->getOpcode(); + unsigned COREOp; + if (Opcode == BPF::LDB || Opcode == BPF::LDH || Opcode == BPF::LDW || + Opcode == BPF::LDD || Opcode == BPF::STB || Opcode == BPF::STH || + Opcode == BPF::STW || Opcode == BPF::STD) + COREOp = BPF::CORE_MEM; + else if (Opcode == BPF::LDB32 || Opcode == BPF::LDH32 || + Opcode == BPF::LDW32 || Opcode == BPF::STB32 || + Opcode == BPF::STH32 || Opcode == BPF::STW32) + COREOp = BPF::CORE_ALU32_MEM; + else + continue; + + // It must be a form of %1 = *(type *)(%2 + 0) or *(type *)(%2 + 0) = %1. + const MachineOperand &ImmOp = DefInst->getOperand(2); + if (!ImmOp.isImm() || ImmOp.getImm() != 0) + continue; + + BuildMI(*DefInst->getParent(), *DefInst, DefInst->getDebugLoc(), TII->get(COREOp)) + .add(DefInst->getOperand(0)).addImm(Opcode).add(*BaseOp) + .addGlobalAddress(GVal); + DefInst->eraseFromParent(); + } +} + +void BPFMISimplifyPatchable::checkShift(MachineRegisterInfo *MRI, + MachineBasicBlock &MBB, MachineOperand *RelocOp, const GlobalValue *GVal, + unsigned Opcode) { + // Relocation operand should be the operand #2. + MachineInstr *Inst = RelocOp->getParent(); + if (RelocOp != &Inst->getOperand(2)) + return; + + BuildMI(MBB, *Inst, Inst->getDebugLoc(), TII->get(BPF::CORE_SHIFT)) + .add(Inst->getOperand(0)).addImm(Opcode) + .add(Inst->getOperand(1)).addGlobalAddress(GVal); + Inst->eraseFromParent(); +} + +void BPFMISimplifyPatchable::processCandidate(MachineRegisterInfo *MRI, + MachineBasicBlock &MBB, MachineInstr &MI, Register &SrcReg, + Register &DstReg, const GlobalValue *GVal) { + if (MRI->getRegClass(DstReg) == &BPF::GPR32RegClass) { + // We can optimize such a pattern: + // %1:gpr = LD_imm64 @"llvm.s:0:4$0:2" + // %2:gpr32 = LDW32 %1:gpr, 0 + // %3:gpr = SUBREG_TO_REG 0, %2:gpr32, %subreg.sub_32 + // %4:gpr = ADD_rr %0:gpr, %3:gpr + // or similar patterns below for non-alu32 case. + auto Begin = MRI->use_begin(DstReg), End = MRI->use_end(); + decltype(End) NextI; + for (auto I = Begin; I != End; I = NextI) { + NextI = std::next(I); + if (!MRI->getUniqueVRegDef(I->getReg())) + continue; + + unsigned Opcode = I->getParent()->getOpcode(); + if (Opcode == BPF::SUBREG_TO_REG) { + Register TmpReg = I->getParent()->getOperand(0).getReg(); + processDstReg(MRI, TmpReg, DstReg, GVal, false); + } + } + + BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(BPF::COPY), DstReg) + .addReg(SrcReg, 0, BPF::sub_32); + return; + } + + // All uses of DstReg replaced by SrcReg + processDstReg(MRI, DstReg, SrcReg, GVal, true); +} + +void BPFMISimplifyPatchable::processDstReg(MachineRegisterInfo *MRI, + Register &DstReg, Register &SrcReg, const GlobalValue *GVal, + bool doSrcRegProp) { + auto Begin = MRI->use_begin(DstReg), End = MRI->use_end(); + decltype(End) NextI; + for (auto I = Begin; I != End; I = NextI) { + NextI = std::next(I); + if (doSrcRegProp) + I->setReg(SrcReg); + + // The candidate needs to have a unique definition. + if (MRI->getUniqueVRegDef(I->getReg())) + processInst(MRI, I->getParent(), &*I, GVal); + } +} + +// Check to see whether we could do some optimization +// to attach relocation to downstream dependent instructions. +// Two kinds of patterns are recognized below: +// Pattern 1: +// %1 = LD_imm64 @"llvm.b:0:4$0:1" <== patch_imm = 4 +// %2 = LDD %1, 0 <== this insn will be removed +// %3 = ADD_rr %0, %2 +// %4 = LDW[32] %3, 0 OR STW[32] %4, %3, 0 +// The `%4 = ...` will be transformed to +// CORE_[ALU32_]MEM(%4, mem_opcode, %0, @"llvm.b:0:4$0:1") +// and later on, BTF emit phase will translate to +// %4 = LDW[32] %0, 4 STW[32] %4, %0, 4 +// and attach a relocation to it. +// Pattern 2: +// %15 = LD_imm64 @"llvm.t:5:63$0:2" <== relocation type 5 +// %16 = LDD %15, 0 <== this insn will be removed +// %17 = SRA_rr %14, %16 +// The `%17 = ...` will be transformed to +// %17 = CORE_SHIFT(SRA_ri, %14, @"llvm.t:5:63$0:2") +// and later on, BTF emit phase will translate to +// %r4 = SRA_ri %r4, 63 +void BPFMISimplifyPatchable::processInst(MachineRegisterInfo *MRI, + MachineInstr *Inst, MachineOperand *RelocOp, const GlobalValue *GVal) { + unsigned Opcode = Inst->getOpcode(); + if (Opcode == BPF::ADD_rr) + checkADDrr(MRI, RelocOp, GVal); + else if (Opcode == BPF::SLL_rr) + checkShift(MRI, *Inst->getParent(), RelocOp, GVal, BPF::SLL_ri); + else if (Opcode == BPF::SRA_rr) + checkShift(MRI, *Inst->getParent(), RelocOp, GVal, BPF::SRA_ri); + else if (Opcode == BPF::SRL_rr) + checkShift(MRI, *Inst->getParent(), RelocOp, GVal, BPF::SRL_ri); +} + /// Remove unneeded Load instructions. bool BPFMISimplifyPatchable::removeLD() { MachineRegisterInfo *MRI = &MF->getRegInfo(); @@ -105,10 +258,11 @@ bool BPFMISimplifyPatchable::removeLD() { continue; bool IsCandidate = false; + const GlobalValue *GVal = nullptr; if (DefInst->getOpcode() == BPF::LD_imm64) { const MachineOperand &MO = DefInst->getOperand(1); if (MO.isGlobal()) { - const GlobalValue *GVal = MO.getGlobal(); + GVal = MO.getGlobal(); auto *GVar = dyn_cast<GlobalVariable>(GVal); if (GVar) { // Global variables representing structure offset or @@ -124,12 +278,7 @@ bool BPFMISimplifyPatchable::removeLD() { if (!IsCandidate) continue; - auto Begin = MRI->use_begin(DstReg), End = MRI->use_end(); - decltype(End) NextI; - for (auto I = Begin; I != End; I = NextI) { - NextI = std::next(I); - I->setReg(SrcReg); - } + processCandidate(MRI, MBB, MI, SrcReg, DstReg, GVal); ToErase = &MI; Changed = true; diff --git a/llvm/lib/Target/BPF/BPFSubtarget.cpp b/llvm/lib/Target/BPF/BPFSubtarget.cpp index ab3452501b952..f3cb03b1f1f57 100644 --- a/llvm/lib/Target/BPF/BPFSubtarget.cpp +++ b/llvm/lib/Target/BPF/BPFSubtarget.cpp @@ -52,6 +52,7 @@ void BPFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { if (CPU == "v3") { HasJmpExt = true; HasJmp32 = true; + HasAlu32 = true; return; } } diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp index 0c4f2c74e7a4a..40375bc88bff2 100644 --- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp +++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp @@ -27,7 +27,7 @@ static cl:: opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden, cl::desc("Disable machine peepholes for BPF")); -extern "C" void LLVMInitializeBPFTarget() { +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() { // Register the target. RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget()); RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget()); diff --git a/llvm/lib/Target/BPF/BTF.h b/llvm/lib/Target/BPF/BTF.h index a13c862bf840a..ad3dcc14c38a3 100644 --- a/llvm/lib/Target/BPF/BTF.h +++ b/llvm/lib/Target/BPF/BTF.h @@ -176,12 +176,18 @@ struct BTFParam { uint32_t Type; }; +/// BTF_KIND_FUNC can be global, static or extern. +enum : uint8_t { + FUNC_STATIC = 0, + FUNC_GLOBAL = 1, + FUNC_EXTERN = 2, +}; + /// Variable scoping information. enum : uint8_t { VAR_STATIC = 0, ///< Linkage: InternalLinkage VAR_GLOBAL_ALLOCATED = 1, ///< Linkage: ExternalLinkage - VAR_GLOBAL_TENTATIVE = 2, ///< Linkage: CommonLinkage - VAR_GLOBAL_EXTERNAL = 3, ///< Linkage: ExternalLinkage + VAR_GLOBAL_EXTERNAL = 2, ///< Linkage: ExternalLinkage }; /// BTF_KIND_DATASEC are followed by multiple "struct BTFDataSecVar". diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp index db551e739bd7c..a9fb04f20d1c8 100644 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -308,10 +308,11 @@ void BTFTypeFuncProto::emitType(MCStreamer &OS) { } } -BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId) +BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, + uint32_t Scope) : Name(FuncName) { Kind = BTF::BTF_KIND_FUNC; - BTFType.Info = Kind << 24; + BTFType.Info = (Kind << 24) | Scope; BTFType.Type = ProtoTypeId; } @@ -897,8 +898,9 @@ void BTFDebug::beginFunctionImpl(const MachineFunction *MF) { visitSubroutineType(SP->getType(), true, FuncArgNames, ProtoTypeId); // Construct subprogram func type + uint8_t Scope = SP->isLocalToUnit() ? BTF::FUNC_STATIC : BTF::FUNC_GLOBAL; auto FuncTypeEntry = - std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId); + std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope); uint32_t FuncTypeId = addType(std::move(FuncTypeEntry)); for (const auto &TypeEntry : TypeEntries) @@ -937,9 +939,8 @@ unsigned BTFDebug::populateStructType(const DIType *Ty) { } /// Generate a struct member field relocation. -void BTFDebug::generateFieldReloc(const MachineInstr *MI, - const MCSymbol *ORSym, DIType *RootTy, - StringRef AccessPattern) { +void BTFDebug::generateFieldReloc(const MCSymbol *ORSym, DIType *RootTy, + StringRef AccessPattern) { unsigned RootId = populateStructType(RootTy); size_t FirstDollar = AccessPattern.find_first_of('$'); size_t FirstColon = AccessPattern.find_first_of(':'); @@ -959,33 +960,8 @@ void BTFDebug::generateFieldReloc(const MachineInstr *MI, FieldRelocTable[SecNameOff].push_back(FieldReloc); } -void BTFDebug::processLDimm64(const MachineInstr *MI) { - // If the insn is an LD_imm64, the following two cases - // will generate an .BTF.ext record. - // - // If the insn is "r2 = LD_imm64 @__BTF_...", - // add this insn into the .BTF.ext FieldReloc subsection. - // Relocation looks like: - // . SecName: - // . InstOffset - // . TypeID - // . OffSetNameOff - // Later, the insn is replaced with "r2 = <offset>" - // where "<offset>" equals to the offset based on current - // type definitions. - // - // If the insn is "r2 = LD_imm64 @VAR" and VAR is - // a patchable external global, add this insn into the .BTF.ext - // ExternReloc subsection. - // Relocation looks like: - // . SecName: - // . InstOffset - // . ExternNameOff - // Later, the insn is replaced with "r2 = <value>" or - // "LD_imm64 r2, <value>" where "<value>" = 0. - +void BTFDebug::processReloc(const MachineOperand &MO) { // check whether this is a candidate or not - const MachineOperand &MO = MI->getOperand(1); if (MO.isGlobal()) { const GlobalValue *GVal = MO.getGlobal(); auto *GVar = dyn_cast<GlobalVariable>(GVal); @@ -995,7 +971,7 @@ void BTFDebug::processLDimm64(const MachineInstr *MI) { MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index); DIType *Ty = dyn_cast<DIType>(MDN); - generateFieldReloc(MI, ORSym, Ty, GVar->getName()); + generateFieldReloc(ORSym, Ty, GVar->getName()); } } } @@ -1020,8 +996,31 @@ void BTFDebug::beginInstruction(const MachineInstr *MI) { return; } - if (MI->getOpcode() == BPF::LD_imm64) - processLDimm64(MI); + if (MI->getOpcode() == BPF::LD_imm64) { + // If the insn is "r2 = LD_imm64 @<an AmaAttr global>", + // add this insn into the .BTF.ext FieldReloc subsection. + // Relocation looks like: + // . SecName: + // . InstOffset + // . TypeID + // . OffSetNameOff + // . RelocType + // Later, the insn is replaced with "r2 = <offset>" + // where "<offset>" equals to the offset based on current + // type definitions. + processReloc(MI->getOperand(1)); + } else if (MI->getOpcode() == BPF::CORE_MEM || + MI->getOpcode() == BPF::CORE_ALU32_MEM || + MI->getOpcode() == BPF::CORE_SHIFT) { + // relocation insn is a load, store or shift insn. + processReloc(MI->getOperand(3)); + } else if (MI->getOpcode() == BPF::JAL) { + // check extern function references + const MachineOperand &MO = MI->getOperand(0); + if (MO.isGlobal()) { + processFuncPrototypes(dyn_cast<Function>(MO.getGlobal())); + } + } // Skip this instruction if no DebugLoc or the DebugLoc // is the same as the previous instruction. @@ -1055,20 +1054,20 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { // Collect all types referenced by globals. const Module *M = MMI->getModule(); for (const GlobalVariable &Global : M->globals()) { - // Ignore external globals for now. - if (!Global.hasInitializer() && Global.hasExternalLinkage()) - continue; - // Decide the section name. StringRef SecName; if (Global.hasSection()) { SecName = Global.getSection(); - } else { + } else if (Global.hasInitializer()) { // data, bss, or readonly sections if (Global.isConstant()) SecName = ".rodata"; else SecName = Global.getInitializer()->isZeroValue() ? ".bss" : ".data"; + } else { + // extern variables without explicit section, + // put them into ".extern" section. + SecName = ".extern"; } if (ProcessingMapDef != SecName.startswith(".maps")) @@ -1076,6 +1075,11 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { SmallVector<DIGlobalVariableExpression *, 1> GVs; Global.getDebugInfo(GVs); + + // No type information, mostly internal, skip it. + if (GVs.size() == 0) + continue; + uint32_t GVTypeId = 0; for (auto *GVE : GVs) { if (SecName.startswith(".maps")) @@ -1087,25 +1091,33 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { // Only support the following globals: // . static variables - // . non-static global variables with section attributes - // Essentially means: - // . .bcc/.data/.rodata DataSec entities only contain static data - // . Other DataSec entities contain static or initialized global data. - // Initialized global data are mostly used for finding map key/value type - // id's. Whether DataSec is readonly or not can be found from - // corresponding ELF section flags. + // . non-static weak or non-weak global variables + // . weak or non-weak extern global variables + // Whether DataSec is readonly or not can be found from corresponding ELF + // section flags. Whether a BTF_KIND_VAR is a weak symbol or not + // can be found from the corresponding ELF symbol table. auto Linkage = Global.getLinkage(); if (Linkage != GlobalValue::InternalLinkage && - (Linkage != GlobalValue::ExternalLinkage || !Global.hasSection())) + Linkage != GlobalValue::ExternalLinkage && + Linkage != GlobalValue::WeakAnyLinkage && + Linkage != GlobalValue::ExternalWeakLinkage) continue; - uint32_t GVarInfo = Linkage == GlobalValue::ExternalLinkage - ? BTF::VAR_GLOBAL_ALLOCATED - : BTF::VAR_STATIC; + uint32_t GVarInfo; + if (Linkage == GlobalValue::InternalLinkage) { + GVarInfo = BTF::VAR_STATIC; + } else if (Global.hasInitializer()) { + GVarInfo = BTF::VAR_GLOBAL_ALLOCATED; + } else { + GVarInfo = BTF::VAR_GLOBAL_EXTERNAL; + } + auto VarEntry = std::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo); uint32_t VarId = addType(std::move(VarEntry)); + assert(!SecName.empty()); + // Find or create a DataSec if (DataSecEntries.find(SecName) == DataSecEntries.end()) { DataSecEntries[SecName] = std::make_unique<BTFKindDataSec>(Asm, SecName); @@ -1135,10 +1147,52 @@ bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) { return true; } } + } else if (MI->getOpcode() == BPF::CORE_MEM || + MI->getOpcode() == BPF::CORE_ALU32_MEM || + MI->getOpcode() == BPF::CORE_SHIFT) { + const MachineOperand &MO = MI->getOperand(3); + if (MO.isGlobal()) { + const GlobalValue *GVal = MO.getGlobal(); + auto *GVar = dyn_cast<GlobalVariable>(GVal); + if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) { + uint32_t Imm = PatchImms[GVar->getName().str()]; + OutMI.setOpcode(MI->getOperand(1).getImm()); + if (MI->getOperand(0).isImm()) + OutMI.addOperand(MCOperand::createImm(MI->getOperand(0).getImm())); + else + OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg())); + OutMI.addOperand(MCOperand::createReg(MI->getOperand(2).getReg())); + OutMI.addOperand(MCOperand::createImm(Imm)); + return true; + } + } } return false; } +void BTFDebug::processFuncPrototypes(const Function *F) { + if (!F) + return; + + const DISubprogram *SP = F->getSubprogram(); + if (!SP || SP->isDefinition()) + return; + + // Do not emit again if already emitted. + if (ProtoFunctions.find(F) != ProtoFunctions.end()) + return; + ProtoFunctions.insert(F); + + uint32_t ProtoTypeId; + const std::unordered_map<uint32_t, StringRef> FuncArgNames; + visitSubroutineType(SP->getType(), false, FuncArgNames, ProtoTypeId); + + uint8_t Scope = BTF::FUNC_EXTERN; + auto FuncTypeEntry = + std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope); + addType(std::move(FuncTypeEntry)); +} + void BTFDebug::endModule() { // Collect MapDef globals if not collected yet. if (MapDefNotCollected) { @@ -1148,6 +1202,7 @@ void BTFDebug::endModule() { // Collect global types/variables except MapDef globals. processGlobals(false); + for (auto &DataSec : DataSecEntries) addType(std::move(DataSec.second)); diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h index c01e0d1d16128..0812c4f7915de 100644 --- a/llvm/lib/Target/BPF/BTFDebug.h +++ b/llvm/lib/Target/BPF/BTFDebug.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/CodeGen/DebugHandlerBase.h" +#include <set> #include <unordered_map> #include "BTF.h" @@ -151,7 +152,7 @@ class BTFTypeFunc : public BTFTypeBase { StringRef Name; public: - BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId); + BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope); uint32_t getSize() { return BTFTypeBase::getSize(); } void completeType(BTFDebug &BDebug); void emitType(MCStreamer &OS); @@ -223,7 +224,7 @@ struct BTFLineInfo { uint32_t ColumnNum; ///< the column number }; -/// Represent one offset relocation. +/// Represent one field relocation. struct BTFFieldReloc { const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc uint32_t TypeID; ///< Type ID @@ -251,6 +252,7 @@ class BTFDebug : public DebugHandlerBase { std::map<std::string, uint32_t> PatchImms; std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>> FixupDerivedTypes; + std::set<const Function *>ProtoFunctions; /// Add types to TypeEntries. /// @{ @@ -293,15 +295,18 @@ class BTFDebug : public DebugHandlerBase { /// Generate types and variables for globals. void processGlobals(bool ProcessingMapDef); - /// Generate one offset relocation record. - void generateFieldReloc(const MachineInstr *MI, const MCSymbol *ORSym, - DIType *RootTy, StringRef AccessPattern); + /// Generate types for function prototypes. + void processFuncPrototypes(const Function *); + + /// Generate one field relocation record. + void generateFieldReloc(const MCSymbol *ORSym, DIType *RootTy, + StringRef AccessPattern); /// Populating unprocessed struct type. unsigned populateStructType(const DIType *Ty); - /// Process LD_imm64 instructions. - void processLDimm64(const MachineInstr *MI); + /// Process relocation instructions. + void processReloc(const MachineOperand &MO); /// Emit common header of .BTF and .BTF.ext sections. void emitCommonHeader(); diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index c845524ad657a..75f963b5448ac 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -67,7 +67,6 @@ public: DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, - raw_ostream &VStream, raw_ostream &CStream) const override; uint8_t getInstClass(uint64_t Inst) const { return (Inst >> 56) & 0x7; }; @@ -84,7 +83,7 @@ static MCDisassembler *createBPFDisassembler(const Target &T, } -extern "C" void LLVMInitializeBPFDisassembler() { +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFDisassembler() { // Register the disassembler. TargetRegistry::RegisterMCDisassembler(getTheBPFTarget(), createBPFDisassembler); @@ -162,7 +161,6 @@ static DecodeStatus readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address, DecodeStatus BPFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, - raw_ostream &VStream, raw_ostream &CStream) const { bool IsLittleEndian = getContext().getAsmInfo()->isLittleEndian(); uint64_t Insn, Hi; diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.cpp index 079202994c8d7..e0aeec989879d 100644 --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.cpp +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.cpp @@ -24,9 +24,10 @@ using namespace llvm; // Include the auto-generated portion of the assembly writer. #include "BPFGenAsmWriter.inc" -void BPFInstPrinter::printInst(const MCInst *MI, raw_ostream &O, - StringRef Annot, const MCSubtargetInfo &STI) { - printInstruction(MI, O); +void BPFInstPrinter::printInst(const MCInst *MI, uint64_t Address, + StringRef Annot, const MCSubtargetInfo &STI, + raw_ostream &O) { + printInstruction(MI, Address, O); printAnnotation(O, Annot); } diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h b/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h index 8c9a0bc94cffb..2181bb575cdda 100644 --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h @@ -22,8 +22,8 @@ public: const MCRegisterInfo &MRI) : MCInstPrinter(MAI, MII, MRI) {} - void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, - const MCSubtargetInfo &STI) override; + void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &O) override; void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, const char *Modifier = nullptr); void printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O, @@ -32,7 +32,7 @@ public: void printBrTargetOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); // Autogenerated by tblgen. - void printInstruction(const MCInst *MI, raw_ostream &O); + void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); }; } diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h index 04a6a87cebc9e..97f0cbd586082 100644 --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h @@ -21,7 +21,7 @@ class Target; class BPFMCAsmInfo : public MCAsmInfo { public: - explicit BPFMCAsmInfo(const Triple &TT) { + explicit BPFMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) { if (TT.getArch() == Triple::bpfeb) IsLittleEndian = false; diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp index fa27b335f3a18..58da0830d0022 100644 --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp @@ -97,7 +97,7 @@ static MCInstrAnalysis *createBPFInstrAnalysis(const MCInstrInfo *Info) { return new BPFMCInstrAnalysis(Info); } -extern "C" void LLVMInitializeBPFTargetMC() { +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTargetMC() { for (Target *T : {&getTheBPFleTarget(), &getTheBPFbeTarget(), &getTheBPFTarget()}) { // Register the MC asm info. diff --git a/llvm/lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp b/llvm/lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp index 5dfa915034bad..49eb9ad62c562 100644 --- a/llvm/lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp +++ b/llvm/lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp @@ -24,7 +24,7 @@ Target &llvm::getTheBPFTarget() { return TheBPFTarget; } -extern "C" void LLVMInitializeBPFTargetInfo() { +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTargetInfo() { TargetRegistry::RegisterTarget(getTheBPFTarget(), "bpf", "BPF (host endian)", "BPF", [](Triple::ArchType) { return false; }, true); |