38struct InstrumentationOptions {
44 bool HandleAllReturns;
72 InstrumentationOptions);
84 InstrumentationOptions);
89void XRayInstrumentation::replaceRetWithPatchableRet(
91 InstrumentationOptions
op) {
95 for (
auto &
MBB : MF) {
99 (
op.HandleAllReturns ||
T.getOpcode() ==
TII->getReturnOpcode())) {
102 Opc = TargetOpcode::PATCHABLE_RET;
107 Opc = TargetOpcode::PATCHABLE_TAIL_CALL;
112 for (
auto &MO :
T.operands())
115 if (
T.shouldUpdateCallSiteInfo())
116 MF.eraseCallSiteInfo(&
T);
121 for (
auto &
I : Terminators)
122 I->eraseFromParent();
125void XRayInstrumentation::prependRetWithPatchableExit(
127 InstrumentationOptions
op) {
132 (
op.HandleAllReturns ||
T.getOpcode() ==
TII->getReturnOpcode())) {
133 Opc = TargetOpcode::PATCHABLE_FUNCTION_EXIT;
136 Opc = TargetOpcode::PATCHABLE_TAIL_CALL;
148 auto InstrAttr =
F.getFnAttribute(
"function-instrument");
149 bool AlwaysInstrument = InstrAttr.isStringAttribute() &&
150 InstrAttr.getValueAsString() ==
"xray-always";
151 bool NeverInstrument = InstrAttr.isStringAttribute() &&
152 InstrAttr.getValueAsString() ==
"xray-never";
153 if (NeverInstrument && !AlwaysInstrument)
155 auto IgnoreLoopsAttr =
F.getFnAttribute(
"xray-ignore-loops");
158 if (!AlwaysInstrument) {
159 bool IgnoreLoops = IgnoreLoopsAttr.isValid();
160 XRayThreshold =
F.getFnAttributeAsParsedInteger(
161 "xray-instruction-threshold", std::numeric_limits<uint64_t>::max());
162 if (XRayThreshold == std::numeric_limits<uint64_t>::max())
167 for (
const auto &
MBB : MF)
170 bool TooFewInstrs = MICount < XRayThreshold;
175 getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();
176 auto *MDT = MDTWrapper ? &MDTWrapper->getDomTree() :
nullptr;
184 auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();
185 auto *MLI = MLIWrapper ? &MLIWrapper->getLI() :
nullptr;
195 if (MLI->empty() && TooFewInstrs)
197 }
else if (TooFewInstrs) {
210 auto *
TII = MF.getSubtarget().getInstrInfo();
211 auto &FirstMBB = *MBI;
212 auto &FirstMI = *FirstMBB.begin();
214 if (!MF.getSubtarget().isXRaySupported()) {
218 Fn,
"An attempt to perform XRay instrumentation for an"
219 " unsupported target."));
224 if (!
F.hasFnAttribute(
"xray-skip-entry")) {
227 BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(),
228 TII->get(TargetOpcode::PATCHABLE_FUNCTION_ENTER));
231 if (!
F.hasFnAttribute(
"xray-skip-exit")) {
232 switch (MF.getTarget().getTargetTriple().getArch()) {
233 case Triple::ArchType::arm:
234 case Triple::ArchType::thumb:
235 case Triple::ArchType::aarch64:
236 case Triple::ArchType::hexagon:
237 case Triple::ArchType::loongarch64:
238 case Triple::ArchType::mips:
239 case Triple::ArchType::mipsel:
240 case Triple::ArchType::mips64:
241 case Triple::ArchType::mips64el:
242 case Triple::ArchType::riscv32:
243 case Triple::ArchType::riscv64: {
245 InstrumentationOptions
op;
247 op.HandleTailcall = MF.getTarget().getTargetTriple().isRISCV();
248 op.HandleAllReturns =
true;
249 prependRetWithPatchableExit(MF,
TII,
op);
252 case Triple::ArchType::ppc64le:
253 case Triple::ArchType::systemz: {
255 InstrumentationOptions
op;
256 op.HandleTailcall =
false;
257 op.HandleAllReturns =
true;
258 replaceRetWithPatchableRet(MF,
TII,
op);
264 InstrumentationOptions
op;
265 op.HandleTailcall =
true;
266 op.HandleAllReturns =
false;
267 replaceRetWithPatchableRet(MF,
TII,
op);
275char XRayInstrumentation::ID = 0;
278 "Insert XRay ops",
false,
false)
This file contains the simple types necessary to represent the attributes associated with functions a...
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Diagnostic information for unsupported feature in backend.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Module * getParent()
Get the module that this global value is contained inside of...
bool isTailCall(const MachineInstr &MI) const override
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
void analyze(const DominatorTreeBase< BlockT, false > &DomTree)
Create the loop forest using a stable algorithm.
iterator_range< iterator > terminators()
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void initializeXRayInstrumentationPass(PassRegistry &)
char & XRayInstrumentationID
This pass inserts the XRay instrumentation sleds if they are supported by the target platform.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.