Skip to content

Commit 77f1902

Browse files
authored
merge main into amd-staging (llvm#935)
2 parents f25a4d5 + bc33d8f commit 77f1902

File tree

30 files changed

+218
-1551
lines changed

30 files changed

+218
-1551
lines changed

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,17 @@ class BinaryContext {
537537
BinaryFunction *createInjectedBinaryFunction(const std::string &Name,
538538
bool IsSimple = true);
539539

540+
/// Patch the original binary contents at address \p Address with a sequence
541+
/// of instructions from the \p Instructions list. The callee is responsible
542+
/// for checking that the sequence doesn't cross any function or section
543+
/// boundaries.
544+
///
545+
/// Optional \p Name can be assigned to the patch. The name will be emitted to
546+
/// the symbol table at \p Address.
547+
BinaryFunction *createInstructionPatch(uint64_t Address,
548+
InstructionListType &Instructions,
549+
const Twine &Name = "");
550+
540551
std::vector<BinaryFunction *> &getInjectedBinaryFunctions() {
541552
return InjectedBinaryFunctions;
542553
}

bolt/include/bolt/Passes/PatchEntries.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ class PatchEntries : public BinaryFunctionPass {
2626
struct Patch {
2727
const MCSymbol *Symbol;
2828
uint64_t Address;
29-
uint64_t FileOffset;
30-
BinarySection *Section;
3129
};
3230

3331
public:

bolt/lib/Core/BinaryContext.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,6 +2400,32 @@ BinaryContext::createInjectedBinaryFunction(const std::string &Name,
24002400
return BF;
24012401
}
24022402

2403+
BinaryFunction *BinaryContext::createInstructionPatch(
2404+
uint64_t Address, InstructionListType &Instructions, const Twine &Name) {
2405+
ErrorOr<BinarySection &> Section = getSectionForAddress(Address);
2406+
assert(Section && "cannot get section for patching");
2407+
assert(Section->hasSectionRef() && Section->isText() &&
2408+
"can only patch input file code sections");
2409+
2410+
const uint64_t FileOffset =
2411+
Section->getInputFileOffset() + Address - Section->getAddress();
2412+
2413+
std::string PatchName = Name.str();
2414+
if (PatchName.empty()) {
2415+
// Assign unique name to the patch.
2416+
static uint64_t N = 0;
2417+
PatchName = "__BP_" + std::to_string(N++);
2418+
}
2419+
2420+
BinaryFunction *PBF = createInjectedBinaryFunction(PatchName);
2421+
PBF->setOutputAddress(Address);
2422+
PBF->setFileOffset(FileOffset);
2423+
PBF->setOriginSection(&Section.get());
2424+
PBF->addBasicBlock()->addInstructions(Instructions);
2425+
2426+
return PBF;
2427+
}
2428+
24032429
std::pair<size_t, size_t>
24042430
BinaryContext::calculateEmittedSize(BinaryFunction &BF, bool FixBranches) {
24052431
// Adjust branch instruction to match the current layout.

bolt/lib/Passes/PatchEntries.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,8 @@ Error PatchEntries::runOnFunctions(BinaryContext &BC) {
8383
return false;
8484
}
8585

86-
PendingPatches.emplace_back(Patch{Symbol, Function.getAddress() + Offset,
87-
Function.getFileOffset() + Offset,
88-
Function.getOriginSection()});
86+
PendingPatches.emplace_back(
87+
Patch{Symbol, Function.getAddress() + Offset});
8988
NextValidByte = Offset + PatchSize;
9089
if (NextValidByte > Function.getMaxSize()) {
9190
if (opts::Verbosity >= 1)
@@ -118,16 +117,12 @@ Error PatchEntries::runOnFunctions(BinaryContext &BC) {
118117
}
119118

120119
for (Patch &Patch : PendingPatches) {
121-
BinaryFunction *PatchFunction = BC.createInjectedBinaryFunction(
120+
// Add instruction patch to the binary.
121+
InstructionListType Instructions;
122+
BC.MIB->createLongTailCall(Instructions, Patch.Symbol, BC.Ctx.get());
123+
BinaryFunction *PatchFunction = BC.createInstructionPatch(
124+
Patch.Address, Instructions,
122125
NameResolver::append(Patch.Symbol->getName(), ".org.0"));
123-
// Force the function to be emitted at the given address.
124-
PatchFunction->setOutputAddress(Patch.Address);
125-
PatchFunction->setFileOffset(Patch.FileOffset);
126-
PatchFunction->setOriginSection(Patch.Section);
127-
128-
InstructionListType Seq;
129-
BC.MIB->createLongTailCall(Seq, Patch.Symbol, BC.Ctx.get());
130-
PatchFunction->addBasicBlock()->addInstructions(Seq);
131126

132127
// Verify the size requirements.
133128
uint64_t HotSize, ColdSize;

bolt/test/X86/Inputs/define_bar.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Mocks a vtable object weak def in the C++ stdlib.
2-
.data.rel.ro
2+
.section .data.rel.ro,"aw"
33
.weak bar
44
.type bar, %object
55
bar:

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,12 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD,
367367
}
368368

369369
/// Arrays of composite elements.
370-
Descriptor::Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD,
370+
Descriptor::Descriptor(const DeclTy &D, const Type *SourceTy,
371+
const Descriptor *Elem, MetadataSize MD,
371372
unsigned NumElems, bool IsConst, bool IsTemporary,
372373
bool IsMutable)
373-
: Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
374+
: Source(D), SourceType(SourceTy),
375+
ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
374376
Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
375377
AllocSize(std::max<size_t>(alignof(void *), Size) + MDSize),
376378
ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
@@ -410,6 +412,8 @@ Descriptor::Descriptor(const DeclTy &D)
410412
}
411413

412414
QualType Descriptor::getType() const {
415+
if (SourceType)
416+
return QualType(SourceType, 0);
413417
if (const auto *D = asValueDecl())
414418
return D->getType();
415419
if (const auto *T = dyn_cast_if_present<TypeDecl>(asDecl()))

clang/lib/AST/ByteCode/Descriptor.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ struct Descriptor final {
124124
private:
125125
/// Original declaration, used to emit the error message.
126126
const DeclTy Source;
127+
const Type *SourceType = nullptr;
127128
/// Size of an element, in host bytes.
128129
const unsigned ElemSize;
129130
/// Size of the storage, in host bytes.
@@ -186,8 +187,9 @@ struct Descriptor final {
186187
bool IsTemporary, UnknownSize);
187188

188189
/// Allocates a descriptor for an array of composites.
189-
Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD,
190-
unsigned NumElems, bool IsConst, bool IsTemporary, bool IsMutable);
190+
Descriptor(const DeclTy &D, const Type *SourceTy, const Descriptor *Elem,
191+
MetadataSize MD, unsigned NumElems, bool IsConst, bool IsTemporary,
192+
bool IsMutable);
191193

192194
/// Allocates a descriptor for an array of composites of unknown size.
193195
Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD,

clang/lib/AST/ByteCode/DynamicAllocator.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,
5757
assert(ElementDesc->getMetadataSize() == 0);
5858
// Create a new descriptor for an array of the specified size and
5959
// element type.
60+
// FIXME: Pass proper element type.
6061
const Descriptor *D = allocateDescriptor(
61-
ElementDesc->asExpr(), ElementDesc, Descriptor::InlineDescMD, NumElements,
62+
ElementDesc->asExpr(), nullptr, ElementDesc, Descriptor::InlineDescMD,
63+
NumElements,
6264
/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);
6365
return allocate(D, EvalID, AllocForm);
6466
}

clang/lib/AST/ByteCode/Program.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
419419
unsigned ElemSize = ElemDesc->getAllocSize() + sizeof(InlineDescriptor);
420420
if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems)
421421
return {};
422-
return allocateDescriptor(D, ElemDesc, MDSize, NumElems, IsConst,
422+
return allocateDescriptor(D, Ty, ElemDesc, MDSize, NumElems, IsConst,
423423
IsTemporary, IsMutable);
424424
}
425425
}

clang/unittests/AST/ByteCode/toAPValue.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,69 @@ TEST(ToAPValue, MemberPointers) {
254254
ASSERT_EQ(A.getKind(), APValue::MemberPointer);
255255
}
256256
}
257+
258+
/// Compare outputs between the two interpreters.
259+
TEST(ToAPValue, Comparison) {
260+
constexpr char Code[] =
261+
"constexpr int GI = 12;\n"
262+
"constexpr const int *PI = &GI;\n"
263+
"struct S{int a; };\n"
264+
"constexpr S GS[] = {{}, {}};\n"
265+
"constexpr const S* OS = GS + 1;\n"
266+
"constexpr S DS = *OS;\n"
267+
"constexpr int IA[2][2][2] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};\n"
268+
"constexpr const int *PIA = IA[1][1];\n";
269+
270+
for (const char *Arg : {"", "-fexperimental-new-constant-interpreter"}) {
271+
auto AST = tooling::buildASTFromCodeWithArgs(Code, {Arg});
272+
273+
auto getDecl = [&](const char *Name) -> const VarDecl * {
274+
auto Nodes =
275+
match(valueDecl(hasName(Name)).bind("var"), AST->getASTContext());
276+
assert(Nodes.size() == 1);
277+
const auto *D = Nodes[0].getNodeAs<ValueDecl>("var");
278+
assert(D);
279+
return cast<VarDecl>(D);
280+
};
281+
282+
{
283+
const VarDecl *GIDecl = getDecl("GI");
284+
const APValue *V = GIDecl->evaluateValue();
285+
ASSERT_TRUE(V->isInt());
286+
}
287+
288+
{
289+
const VarDecl *GIDecl = getDecl("GI");
290+
const VarDecl *PIDecl = getDecl("PI");
291+
const APValue *V = PIDecl->evaluateValue();
292+
ASSERT_TRUE(V->isLValue());
293+
ASSERT_TRUE(V->hasLValuePath());
294+
ASSERT_EQ(V->getLValueBase().get<const ValueDecl *>(), GIDecl);
295+
ASSERT_EQ(V->getLValuePath().size(), 0u);
296+
}
297+
298+
{
299+
const APValue *V = getDecl("OS")->evaluateValue();
300+
ASSERT_TRUE(V->isLValue());
301+
ASSERT_EQ(V->getLValueOffset().getQuantity(), (unsigned)sizeof(int));
302+
ASSERT_TRUE(V->hasLValuePath());
303+
ASSERT_EQ(V->getLValuePath().size(), 1u);
304+
ASSERT_EQ(V->getLValuePath()[0].getAsArrayIndex(), 1u);
305+
}
306+
307+
{
308+
const APValue *V = getDecl("DS")->evaluateValue();
309+
ASSERT_TRUE(V->isStruct());
310+
}
311+
{
312+
const APValue *V = getDecl("PIA")->evaluateValue();
313+
ASSERT_TRUE(V->isLValue());
314+
ASSERT_TRUE(V->hasLValuePath());
315+
ASSERT_EQ(V->getLValuePath().size(), 3u);
316+
ASSERT_EQ(V->getLValuePath()[0].getAsArrayIndex(), 1u);
317+
ASSERT_EQ(V->getLValuePath()[1].getAsArrayIndex(), 1u);
318+
ASSERT_EQ(V->getLValuePath()[2].getAsArrayIndex(), 0u);
319+
ASSERT_EQ(V->getLValueOffset().getQuantity(), (unsigned)sizeof(int) * 6);
320+
}
321+
}
322+
}

0 commit comments

Comments
 (0)