Skip to content

Commit f57ff73

Browse files
committed
Merge from 'main' to 'sycl-web' (588 commits)
CONFLICT (content): Merge conflict in llvm/lib/Transforms/IPO/IPO.cpp
2 parents d74f1aa + 773d663 commit f57ff73

File tree

2,004 files changed

+140185
-31011
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,004 files changed

+140185
-31011
lines changed

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,13 @@ class BinaryContext {
366366
BinaryFunction *getBinaryFunctionContainingAddress(uint64_t Address,
367367
bool CheckPastEnd = false,
368368
bool UseMaxSize = false);
369+
const BinaryFunction *
370+
getBinaryFunctionContainingAddress(uint64_t Address,
371+
bool CheckPastEnd = false,
372+
bool UseMaxSize = false) const {
373+
return const_cast<BinaryContext *>(this)
374+
->getBinaryFunctionContainingAddress(Address, CheckPastEnd, UseMaxSize);
375+
}
369376

370377
/// Return a BinaryFunction that starts at a given \p Address.
371378
BinaryFunction *getBinaryFunctionAtAddress(uint64_t Address);
@@ -504,9 +511,11 @@ class BinaryContext {
504511
/// Optionally, populate \p Address from jump table entries. The entries
505512
/// could be partially populated if the jump table detection fails.
506513
bool analyzeJumpTable(const uint64_t Address,
507-
const JumpTable::JumpTableType Type, BinaryFunction &BF,
514+
const JumpTable::JumpTableType Type,
515+
const BinaryFunction &BF,
508516
const uint64_t NextJTAddress = 0,
509-
JumpTable::AddressesType *EntriesAsAddress = nullptr);
517+
JumpTable::AddressesType *EntriesAsAddress = nullptr,
518+
bool *HasEntryInFragment = nullptr) const;
510519

511520
/// After jump table locations are established, this function will populate
512521
/// their EntriesAsAddress based on memory contents.
@@ -1143,7 +1152,7 @@ class BinaryContext {
11431152

11441153
/// Return a relocation registered at a given \p Address, or nullptr if there
11451154
/// is no relocation at such address.
1146-
const Relocation *getRelocationAt(uint64_t Address);
1155+
const Relocation *getRelocationAt(uint64_t Address) const;
11471156

11481157
/// Register a presence of PC-relative relocation at the given \p Address.
11491158
void addPCRelativeDataRelocation(uint64_t Address) {

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ class BinaryFunction {
349349
/// This attribute is only valid when hasCFG() == true.
350350
bool HasCanonicalCFG{true};
351351

352+
/// True if another function body was merged into this one.
353+
bool HasFunctionsFoldedInto{false};
354+
352355
/// Name for the section this function code should reside in.
353356
std::string CodeSectionName;
354357

@@ -1407,6 +1410,9 @@ class BinaryFunction {
14071410
/// Return true if the body of the function was merged into another function.
14081411
bool isFolded() const { return FoldedIntoFunction != nullptr; }
14091412

1413+
/// Return true if other functions were folded into this one.
1414+
bool hasFunctionsFoldedInto() const { return HasFunctionsFoldedInto; }
1415+
14101416
/// If this function was folded, return the function it was folded into.
14111417
BinaryFunction *getFoldedIntoFunction() const { return FoldedIntoFunction; }
14121418

@@ -1460,8 +1466,6 @@ class BinaryFunction {
14601466

14611467
ArrayRef<uint8_t> getLSDATypeIndexTable() const { return LSDATypeIndexTable; }
14621468

1463-
const LabelsMapType &getLabels() const { return Labels; }
1464-
14651469
IslandInfo &getIslandInfo() {
14661470
assert(Islands && "function expected to have constant islands");
14671471
return *Islands;
@@ -1770,6 +1774,9 @@ class BinaryFunction {
17701774

17711775
void setFolded(BinaryFunction *BF) { FoldedIntoFunction = BF; }
17721776

1777+
/// Indicate that another function body was merged with this function.
1778+
void setHasFunctionsFoldedInto() { HasFunctionsFoldedInto = true; }
1779+
17731780
BinaryFunction &setPersonalityFunction(uint64_t Addr) {
17741781
assert(!PersonalityFunction && "can't set personality function twice");
17751782
PersonalityFunction = BC.getOrCreateGlobalSymbol(Addr, "FUNCat");

bolt/include/bolt/Core/JumpTable.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class JumpTable : public BinaryData {
6666
/// The type of this jump table.
6767
JumpTableType Type;
6868

69+
/// Whether this jump table has entries pointing to multiple functions.
70+
bool IsSplit{false};
71+
6972
/// All the entries as labels.
7073
std::vector<MCSymbol *> Entries;
7174

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ class MCPlusBuilder {
110110
return AnnotationInst;
111111
}
112112

113+
void removeAnnotationInst(MCInst &Inst) const {
114+
assert(getAnnotationInst(Inst) && "Expected annotation instruction.");
115+
Inst.erase(std::prev(Inst.end()));
116+
assert(!getAnnotationInst(Inst) &&
117+
"More than one annotation instruction detected.");
118+
}
119+
113120
void setAnnotationOpValue(MCInst &Inst, unsigned Index, int64_t Value,
114121
AllocatorIdTy AllocatorId = 0) {
115122
MCInst *AnnotationInst = getAnnotationInst(Inst);
@@ -163,6 +170,18 @@ class MCPlusBuilder {
163170
/// MCPlusBuilder classes must use convert/lower/create* interfaces instead.
164171
void setTailCall(MCInst &Inst);
165172

173+
/// Transfer annotations from \p SrcInst to \p DstInst.
174+
void moveAnnotations(MCInst &&SrcInst, MCInst &DstInst) const {
175+
assert(!getAnnotationInst(DstInst) &&
176+
"Destination instruction should not have annotations.");
177+
const MCInst *AnnotationInst = getAnnotationInst(SrcInst);
178+
if (!AnnotationInst)
179+
return;
180+
181+
DstInst.addOperand(MCOperand::createInst(AnnotationInst));
182+
removeAnnotationInst(SrcInst);
183+
}
184+
166185
public:
167186
class InstructionIterator {
168187
public:
@@ -854,6 +873,15 @@ class MCPlusBuilder {
854873
return false;
855874
}
856875

876+
struct X86MemOperand {
877+
unsigned BaseRegNum;
878+
int64_t ScaleImm;
879+
unsigned IndexRegNum;
880+
int64_t DispImm;
881+
unsigned SegRegNum;
882+
const MCExpr *DispExpr = nullptr;
883+
};
884+
857885
/// Given an instruction with (compound) memory operand, evaluate and return
858886
/// the corresponding values. Note that the operand could be in any position,
859887
/// but there is an assumption there's only one compound memory operand.
@@ -862,13 +890,10 @@ class MCPlusBuilder {
862890
///
863891
/// Since a Displacement field could be either an immediate or an expression,
864892
/// the function sets either \p DispImm or \p DispExpr value.
865-
virtual bool
866-
evaluateX86MemoryOperand(const MCInst &Inst, unsigned *BaseRegNum,
867-
int64_t *ScaleImm, unsigned *IndexRegNum,
868-
int64_t *DispImm, unsigned *SegmentRegNum,
869-
const MCExpr **DispExpr = nullptr) const {
893+
virtual std::optional<X86MemOperand>
894+
evaluateX86MemoryOperand(const MCInst &Inst) const {
870895
llvm_unreachable("not implemented");
871-
return false;
896+
return std::nullopt;
872897
}
873898

874899
/// Given an instruction with memory addressing attempt to statically compute
@@ -1858,9 +1883,8 @@ class MCPlusBuilder {
18581883
void stripAnnotations(MCInst &Inst, bool KeepTC = false);
18591884

18601885
virtual InstructionListType
1861-
createInstrumentedIndirectCall(const MCInst &CallInst, bool TailCall,
1862-
MCSymbol *HandlerFuncAddr, int CallSiteID,
1863-
MCContext *Ctx) {
1886+
createInstrumentedIndirectCall(MCInst &&CallInst, MCSymbol *HandlerFuncAddr,
1887+
int CallSiteID, MCContext *Ctx) {
18641888
llvm_unreachable("not implemented");
18651889
return InstructionListType();
18661890
}

bolt/include/bolt/Core/Relocation.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ struct Relocation {
106106
/// Return code for a PC-relative 8-byte relocation
107107
static uint64_t getPC64();
108108

109+
/// Return code for a ABS 8-byte relocation
110+
static uint64_t getAbs64();
111+
109112
/// Return true if this relocation is PC-relative. Return false otherwise.
110113
bool isPCRelative() const { return isPCRelative(Type); }
111114

bolt/include/bolt/Passes/RetpolineInsertion.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,7 @@ struct IndirectBranchInfo {
3030
bool isJump() const { return !IsCall; }
3131
bool isTailCall() const { return IsTailCall; }
3232

33-
struct MemOpInfo {
34-
unsigned BaseRegNum;
35-
int64_t ScaleValue;
36-
unsigned IndexRegNum;
37-
int64_t DispValue;
38-
unsigned SegRegNum;
39-
const MCExpr *DispExpr{nullptr};
40-
};
33+
using MemOpInfo = MCPlusBuilder::X86MemOperand;
4134

4235
union {
4336
// Register branch information

bolt/lib/Core/BinaryContext.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,12 @@ MemoryContentsType BinaryContext::analyzeMemoryAt(uint64_t Address,
479479
return MemoryContentsType::UNKNOWN;
480480
}
481481

482-
bool BinaryContext::analyzeJumpTable(
483-
const uint64_t Address, const JumpTable::JumpTableType Type,
484-
BinaryFunction &BF, const uint64_t NextJTAddress,
485-
JumpTable::AddressesType *EntriesAsAddress) {
482+
bool BinaryContext::analyzeJumpTable(const uint64_t Address,
483+
const JumpTable::JumpTableType Type,
484+
const BinaryFunction &BF,
485+
const uint64_t NextJTAddress,
486+
JumpTable::AddressesType *EntriesAsAddress,
487+
bool *HasEntryInFragment) const {
486488
// Is one of the targets __builtin_unreachable?
487489
bool HasUnreachable = false;
488490

@@ -495,7 +497,7 @@ bool BinaryContext::analyzeJumpTable(
495497
};
496498

497499
auto doesBelongToFunction = [&](const uint64_t Addr,
498-
BinaryFunction *TargetBF) -> bool {
500+
const BinaryFunction *TargetBF) -> bool {
499501
if (BF.containsAddress(Addr))
500502
return true;
501503
// Nothing to do if we failed to identify the containing function.
@@ -505,7 +507,7 @@ bool BinaryContext::analyzeJumpTable(
505507
return BF.isChildOf(*TargetBF) || TargetBF->isChildOf(BF);
506508
};
507509

508-
ErrorOr<BinarySection &> Section = getSectionForAddress(Address);
510+
ErrorOr<const BinarySection &> Section = getSectionForAddress(Address);
509511
if (!Section)
510512
return false;
511513

@@ -562,7 +564,7 @@ bool BinaryContext::analyzeJumpTable(
562564
}
563565

564566
// Function or one of its fragments.
565-
BinaryFunction *TargetBF = getBinaryFunctionContainingAddress(Value);
567+
const BinaryFunction *TargetBF = getBinaryFunctionContainingAddress(Value);
566568

567569
// We assume that a jump table cannot have function start as an entry.
568570
if (!doesBelongToFunction(Value, TargetBF) || Value == BF.getAddress()) {
@@ -596,8 +598,8 @@ bool BinaryContext::analyzeJumpTable(
596598
++NumRealEntries;
597599
LLVM_DEBUG(dbgs() << formatv("OK: {0:x} real entry\n", Value));
598600

599-
if (TargetBF != &BF)
600-
BF.setHasIndirectTargetToSplitFragment(true);
601+
if (TargetBF != &BF && HasEntryInFragment)
602+
*HasEntryInFragment = true;
601603
addEntryAddress(Value);
602604
}
603605

@@ -627,7 +629,7 @@ void BinaryContext::populateJumpTables() {
627629

628630
const bool Success =
629631
analyzeJumpTable(JT->getAddress(), JT->Type, *(JT->Parents[0]),
630-
NextJTAddress, &JT->EntriesAsAddress);
632+
NextJTAddress, &JT->EntriesAsAddress, &JT->IsSplit);
631633
if (!Success) {
632634
LLVM_DEBUG({
633635
dbgs() << "failed to analyze ";
@@ -640,6 +642,8 @@ void BinaryContext::populateJumpTables() {
640642
llvm_unreachable("jump table heuristic failure");
641643
}
642644
for (BinaryFunction *Frag : JT->Parents) {
645+
if (JT->IsSplit)
646+
Frag->setHasIndirectTargetToSplitFragment(true);
643647
for (uint64_t EntryAddress : JT->EntriesAsAddress)
644648
// if target is builtin_unreachable
645649
if (EntryAddress == Frag->getAddress() + Frag->getSize()) {
@@ -1345,6 +1349,8 @@ void BinaryContext::foldFunction(BinaryFunction &ChildBF,
13451349

13461350
ChildBF.setFolded(&ParentBF);
13471351
}
1352+
1353+
ParentBF.setHasFunctionsFoldedInto();
13481354
}
13491355

13501356
void BinaryContext::fixBinaryDataHoles() {
@@ -2085,8 +2091,8 @@ bool BinaryContext::removeRelocationAt(uint64_t Address) {
20852091
return Section->removeRelocationAt(Address - Section->getAddress());
20862092
}
20872093

2088-
const Relocation *BinaryContext::getRelocationAt(uint64_t Address) {
2089-
ErrorOr<BinarySection &> Section = getSectionForAddress(Address);
2094+
const Relocation *BinaryContext::getRelocationAt(uint64_t Address) const {
2095+
ErrorOr<const BinarySection &> Section = getSectionForAddress(Address);
20902096
if (!Section)
20912097
return nullptr;
20922098

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,8 @@ bool BinaryFunction::validateExternallyReferencedOffsets() {
17701770
bool BinaryFunction::postProcessIndirectBranches(
17711771
MCPlusBuilder::AllocatorIdTy AllocId) {
17721772
auto addUnknownControlFlow = [&](BinaryBasicBlock &BB) {
1773+
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: adding unknown control flow in " << *this
1774+
<< " for " << BB.getName() << "\n");
17731775
HasUnknownControlFlow = true;
17741776
BB.removeAllSuccessors();
17751777
for (uint64_t PossibleDestination : ExternallyReferencedOffsets)
@@ -1877,7 +1879,10 @@ bool BinaryFunction::postProcessIndirectBranches(
18771879
// references, then we should be able to derive the jump table even if we
18781880
// fail to match the pattern.
18791881
if (HasUnknownControlFlow && NumIndirectJumps == 1 &&
1880-
JumpTables.size() == 1 && LastIndirectJump) {
1882+
JumpTables.size() == 1 && LastIndirectJump &&
1883+
!BC.getJumpTableContainingAddress(LastJT)->IsSplit) {
1884+
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: unsetting unknown control flow in "
1885+
<< *this << '\n');
18811886
BC.MIB->setJumpTable(*LastIndirectJump, LastJT, LastJTIndexReg, AllocId);
18821887
HasUnknownControlFlow = false;
18831888

@@ -2897,16 +2902,12 @@ void BinaryFunction::clearDisasmState() {
28972902
void BinaryFunction::setTrapOnEntry() {
28982903
clearDisasmState();
28992904

2900-
auto addTrapAtOffset = [&](uint64_t Offset) {
2905+
forEachEntryPoint([&](uint64_t Offset, const MCSymbol *Label) -> bool {
29012906
MCInst TrapInstr;
29022907
BC.MIB->createTrap(TrapInstr);
29032908
addInstruction(Offset, std::move(TrapInstr));
2904-
};
2905-
2906-
addTrapAtOffset(0);
2907-
for (const std::pair<const uint32_t, MCSymbol *> &KV : getLabels())
2908-
if (getSecondaryEntryPointSymbol(KV.second))
2909-
addTrapAtOffset(KV.first);
2909+
return true;
2910+
});
29102911

29112912
TrapsOnEntry = true;
29122913
}

bolt/lib/Core/BinarySection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ void BinarySection::reorderContents(const std::vector<BinaryData *> &Order,
252252
// of the reordered segment to force LLVM to recognize and map this
253253
// section.
254254
MCSymbol *ZeroSym = BC.registerNameAtAddress("Zero", 0, 0, 0);
255-
addRelocation(OS.tell(), ZeroSym, ELF::R_X86_64_64, 0xdeadbeef);
255+
addRelocation(OS.tell(), ZeroSym, Relocation::getAbs64(), 0xdeadbeef);
256256

257257
uint64_t Zero = 0;
258258
OS.write(reinterpret_cast<const char *>(&Zero), sizeof(Zero));

bolt/lib/Core/MCPlusBuilder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) {
298298
// Preserve TailCall annotation.
299299
auto IsTC = hasAnnotation(Inst, MCAnnotation::kTailCall);
300300

301-
Inst.erase(std::prev(Inst.end()));
301+
removeAnnotationInst(Inst);
302+
302303
if (KeepTC && IsTC)
303304
setTailCall(Inst);
304305
}

bolt/lib/Core/Relocation.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,12 @@ bool Relocation::isPCRelative(uint64_t Type) {
636636
return isPCRelativeX86(Type);
637637
}
638638

639+
uint64_t Relocation::getAbs64() {
640+
if (Arch == Triple::aarch64)
641+
return ELF::R_AARCH64_ABS64;
642+
return ELF::R_X86_64_64;
643+
}
644+
639645
size_t Relocation::emit(MCStreamer *Streamer) const {
640646
const size_t Size = getSizeForType(Type);
641647
MCContext &Ctx = Streamer->getContext();

bolt/lib/Passes/ADRRelaxationPass.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include "bolt/Passes/ADRRelaxationPass.h"
1414
#include "bolt/Core/ParallelUtilities.h"
15+
#include "bolt/Utils/CommandLineOpts.h"
16+
#include <iterator>
1517

1618
using namespace llvm;
1719

@@ -54,6 +56,20 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
5456
int64_t Addend = BC.MIB->getTargetAddend(Inst);
5557
InstructionListType Addr =
5658
BC.MIB->materializeAddress(Symbol, BC.Ctx.get(), Reg, Addend);
59+
60+
if (It != BB.begin() && BC.MIB->isNoop(*std::prev(It))) {
61+
It = BB.eraseInstruction(std::prev(It));
62+
} else if (opts::StrictMode && !BF.isSimple()) {
63+
// If the function is not simple, it may contain a jump table undetected
64+
// by us. This jump table may use an offset from the branch instruction
65+
// to land in the desired place. If we add new instructions, we
66+
// invalidate this offset, so we have to rely on linker-inserted NOP to
67+
// replace it with ADRP, and abort if it is not present.
68+
errs() << formatv("BOLT-ERROR: Cannot relax adr in non-simple function "
69+
"{0}. Can't proceed in current mode.\n",
70+
BF.getOneName());
71+
exit(1);
72+
}
5773
It = BB.replaceInstruction(It, Addr);
5874
}
5975
}

0 commit comments

Comments
 (0)