1- // ===- bolt/Passes/ADRRelaxationPass .cpp ---- ------------------------------===//
1+ // ===- bolt/Passes/AArch64RelaxationPass .cpp ------------------------------===//
22//
33// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44// See https://llvm.org/LICENSE.txt for license information.
55// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66//
77// ===----------------------------------------------------------------------===//
88//
9- // This file implements the ADRRelaxationPass class.
9+ // This file implements the AArch64RelaxationPass class.
1010//
1111// ===----------------------------------------------------------------------===//
1212
13- #include " bolt/Passes/ADRRelaxationPass .h"
13+ #include " bolt/Passes/AArch64RelaxationPass .h"
1414#include " bolt/Core/ParallelUtilities.h"
1515#include " bolt/Utils/CommandLineOpts.h"
1616#include < iterator>
@@ -20,10 +20,10 @@ using namespace llvm;
2020namespace opts {
2121extern cl::OptionCategory BoltCategory;
2222
23- static cl::opt<bool >
24- AdrPassOpt ( " adr -relaxation" ,
25- cl::desc (" Replace ARM non-local ADR instructions with ADRP" ),
26- cl::init(true ), cl::cat(BoltCategory), cl::ReallyHidden);
23+ static cl::opt<bool > AArch64PassOpt (
24+ " aarch64 -relaxation" ,
25+ cl::desc (" Replace ARM non-local ADR/LDR instructions with ADRP" ),
26+ cl::init(true ), cl::cat(BoltCategory), cl::ReallyHidden);
2727} // namespace opts
2828
2929namespace llvm {
@@ -35,18 +35,21 @@ namespace bolt {
3535// jobs and checking the exit flag after it.
3636static bool PassFailed = false ;
3737
38- void ADRRelaxationPass ::runOnFunction (BinaryFunction &BF) {
38+ void AArch64RelaxationPass ::runOnFunction (BinaryFunction &BF) {
3939 if (PassFailed)
4040 return ;
4141
4242 BinaryContext &BC = BF.getBinaryContext ();
4343 for (BinaryBasicBlock &BB : BF) {
4444 for (auto It = BB.begin (); It != BB.end (); ++It) {
4545 MCInst &Inst = *It;
46- if (!BC.MIB ->isADR (Inst))
46+ bool IsADR = BC.MIB ->isADR (Inst);
47+
48+ // TODO: Handle other types of LDR (literal, PC-relative) instructions.
49+ if (!IsADR && !BC.MIB ->isLDRXl (Inst) && !BC.MIB ->isLDRWl (Inst))
4750 continue ;
4851
49- const MCSymbol *Symbol = BC.MIB ->getTargetSymbol (Inst);
52+ const MCSymbol *Symbol = BC.MIB ->getTargetSymbol (Inst, IsADR ? 0 : 1 );
5053 if (!Symbol)
5154 continue ;
5255
@@ -56,25 +59,27 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
5659 continue ;
5760 }
5861
59- // Don't relax ADR if it points to the same function and is in the main
60- // fragment and BF initial size is < 1MB.
62+ // Don't relax ADR/LDR if it points to the same function and is in the
63+ // main fragment and BF initial size is < 1MB.
6164 const unsigned OneMB = 0x100000 ;
6265 if (BF.getSize () < OneMB) {
6366 BinaryFunction *TargetBF = BC.getFunctionForSymbol (Symbol);
6467 if (TargetBF == &BF && !BB.isSplit ())
6568 continue ;
6669
67- // No relaxation needed if ADR references a basic block in the same
70+ // No relaxation needed if ADR/LDR references a basic block in the same
6871 // fragment.
6972 if (BinaryBasicBlock *TargetBB = BF.getBasicBlockForLabel (Symbol))
7073 if (BB.getFragmentNum () == TargetBB->getFragmentNum ())
7174 continue ;
7275 }
7376
74- InstructionListType AdrpAdd ;
77+ InstructionListType AdrpMaterialization ;
7578 {
7679 auto L = BC.scopeLock ();
77- AdrpAdd = BC.MIB ->undoAdrpAddRelaxation (Inst, BC.Ctx .get ());
80+ AdrpMaterialization =
81+ IsADR ? BC.MIB ->undoAdrpAddRelaxation (Inst, BC.Ctx .get ())
82+ : BC.MIB ->createAdrpLdr (Inst, BC.Ctx .get ());
7883 }
7984
8085 if (It != BB.begin () && BC.MIB ->isNoop (*std::prev (It))) {
@@ -88,18 +93,18 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
8893 // invalidate this offset, so we have to rely on linker-inserted NOP to
8994 // replace it with ADRP, and abort if it is not present.
9095 auto L = BC.scopeLock ();
91- BC.errs () << " BOLT-ERROR: cannot relax ADR in non-simple function "
92- << BF << ' \n ' ;
96+ BC.errs () << " BOLT-ERROR: cannot relax " << (IsADR ? " ADR " : " LDR " )
97+ << " in non-simple function " << BF << ' \n ' ;
9398 PassFailed = true ;
9499 return ;
95100 }
96- It = BB.replaceInstruction (It, AdrpAdd );
101+ It = BB.replaceInstruction (It, AdrpMaterialization );
97102 }
98103 }
99104}
100105
101- Error ADRRelaxationPass ::runOnFunctions (BinaryContext &BC) {
102- if (!opts::AdrPassOpt || !BC.HasRelocations )
106+ Error AArch64RelaxationPass ::runOnFunctions (BinaryContext &BC) {
107+ if (!opts::AArch64PassOpt || !BC.HasRelocations )
103108 return Error::success ();
104109
105110 ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
@@ -108,7 +113,7 @@ Error ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
108113
109114 ParallelUtilities::runOnEachFunction (
110115 BC, ParallelUtilities::SchedulingPolicy::SP_TRIVIAL, WorkFun, nullptr ,
111- " ADRRelaxationPass " );
116+ " AArch64RelaxationPass " );
112117
113118 if (PassFailed)
114119 return createFatalBOLTError (" " );
0 commit comments