Skip to content

Commit 6759cdd

Browse files
committed
[NFC] [MTE] Use helpers for stack tagging.
Reviewed By: eugenis Differential Revision: https://reviews.llvm.org/D119503
1 parent bf2f72f commit 6759cdd

File tree

3 files changed

+32
-82
lines changed

3 files changed

+32
-82
lines changed

llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/IR/Instruction.h"
2020
#include "llvm/IR/IntrinsicInst.h"
2121
#include "llvm/IR/Module.h"
22+
#include "llvm/IR/ValueHandle.h"
2223

2324
namespace llvm {
2425
namespace memtag {
@@ -74,6 +75,7 @@ Instruction *getUntagLocationIfFunctionExit(Instruction &Inst);
7475

7576
struct AllocaInfo {
7677
AllocaInst *AI;
78+
TrackingVH<Instruction> OldAI; // Track through RAUW to replace debug uses.
7779
SmallVector<IntrinsicInst *, 2> LifetimeStart;
7880
SmallVector<IntrinsicInst *, 2> LifetimeEnd;
7981
SmallVector<DbgVariableIntrinsic *, 2> DbgVariableIntrinsics;

llvm/lib/Target/AArch64/AArch64StackTagging.cpp

Lines changed: 26 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -290,14 +290,6 @@ class InitializerBuilder {
290290
};
291291

292292
class AArch64StackTagging : public FunctionPass {
293-
struct AllocaInfo {
294-
AllocaInst *AI;
295-
TrackingVH<Instruction> OldAI; // Track through RAUW to replace debug uses.
296-
SmallVector<IntrinsicInst *, 2> LifetimeStart;
297-
SmallVector<IntrinsicInst *, 2> LifetimeEnd;
298-
SmallVector<DbgVariableIntrinsic *, 2> DbgVariableIntrinsics;
299-
};
300-
301293
const bool MergeInit;
302294
const bool UseStackSafety;
303295

@@ -313,7 +305,7 @@ class AArch64StackTagging : public FunctionPass {
313305
}
314306

315307
bool isInterestingAlloca(const AllocaInst &AI);
316-
void alignAndPadAlloca(AllocaInfo &Info);
308+
void alignAndPadAlloca(memtag::AllocaInfo &Info);
317309

318310
void tagAlloca(AllocaInst *AI, Instruction *InsertBefore, Value *Ptr,
319311
uint64_t Size);
@@ -322,9 +314,9 @@ class AArch64StackTagging : public FunctionPass {
322314
Instruction *collectInitializers(Instruction *StartInst, Value *StartPtr,
323315
uint64_t Size, InitializerBuilder &IB);
324316

325-
Instruction *
326-
insertBaseTaggedPointer(const MapVector<AllocaInst *, AllocaInfo> &Allocas,
327-
const DominatorTree *DT);
317+
Instruction *insertBaseTaggedPointer(
318+
const MapVector<AllocaInst *, memtag::AllocaInfo> &Allocas,
319+
const DominatorTree *DT);
328320
bool runOnFunction(Function &F) override;
329321

330322
StringRef getPassName() const override { return "AArch64 Stack Tagging"; }
@@ -466,12 +458,12 @@ void AArch64StackTagging::untagAlloca(AllocaInst *AI, Instruction *InsertBefore,
466458
}
467459

468460
Instruction *AArch64StackTagging::insertBaseTaggedPointer(
469-
const MapVector<AllocaInst *, AllocaInfo> &InterestingAllocas,
461+
const MapVector<AllocaInst *, memtag::AllocaInfo> &AllocasToInstrument,
470462
const DominatorTree *DT) {
471463
BasicBlock *PrologueBB = nullptr;
472464
// Try sinking IRG as deep as possible to avoid hurting shrink wrap.
473-
for (auto &I : InterestingAllocas) {
474-
const AllocaInfo &Info = I.second;
465+
for (auto &I : AllocasToInstrument) {
466+
const memtag::AllocaInfo &Info = I.second;
475467
AllocaInst *AI = Info.AI;
476468
if (!PrologueBB) {
477469
PrologueBB = AI->getParent();
@@ -490,7 +482,7 @@ Instruction *AArch64StackTagging::insertBaseTaggedPointer(
490482
return Base;
491483
}
492484

493-
void AArch64StackTagging::alignAndPadAlloca(AllocaInfo &Info) {
485+
void AArch64StackTagging::alignAndPadAlloca(memtag::AllocaInfo &Info) {
494486
const Align NewAlignment =
495487
max(MaybeAlign(Info.AI->getAlign()), kTagGranuleSize);
496488
Info.AI->setAlignment(NewAlignment);
@@ -536,63 +528,17 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
536528
if (MergeInit)
537529
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
538530

539-
MapVector<AllocaInst *, AllocaInfo>
540-
InterestingAllocas; // need stable iteration order
541-
SmallVector<Instruction *, 8> RetVec;
542-
SmallVector<Instruction *, 4> UnrecognizedLifetimes;
543-
544-
bool CallsReturnTwice = false;
545-
for (Instruction &I : instructions(F)) {
546-
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
547-
if (CI->canReturnTwice()) {
548-
CallsReturnTwice = true;
549-
}
550-
}
551-
if (auto *AI = dyn_cast<AllocaInst>(&I)) {
552-
if (isInterestingAlloca(*AI)) {
553-
InterestingAllocas[AI].AI = AI;
554-
InterestingAllocas[AI].OldAI = AI;
555-
}
556-
continue;
557-
}
558-
559-
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) {
560-
for (Value *V : DVI->location_ops())
561-
if (auto *AI = dyn_cast_or_null<AllocaInst>(V))
562-
if (isInterestingAlloca(*AI) &&
563-
(InterestingAllocas[AI].DbgVariableIntrinsics.empty() ||
564-
InterestingAllocas[AI].DbgVariableIntrinsics.back() != DVI))
565-
InterestingAllocas[AI].DbgVariableIntrinsics.push_back(DVI);
566-
continue;
567-
}
568-
569-
auto *II = dyn_cast<IntrinsicInst>(&I);
570-
if (II && (II->getIntrinsicID() == Intrinsic::lifetime_start ||
571-
II->getIntrinsicID() == Intrinsic::lifetime_end)) {
572-
AllocaInst *AI = findAllocaForValue(II->getArgOperand(1));
573-
if (!AI) {
574-
UnrecognizedLifetimes.push_back(&I);
575-
continue;
576-
}
577-
if (!isInterestingAlloca(*AI))
578-
continue;
579-
if (II->getIntrinsicID() == Intrinsic::lifetime_start)
580-
InterestingAllocas[AI].LifetimeStart.push_back(II);
581-
else
582-
InterestingAllocas[AI].LifetimeEnd.push_back(II);
583-
continue;
584-
}
585-
586-
Instruction *ExitUntag = memtag::getUntagLocationIfFunctionExit(I);
587-
if (ExitUntag)
588-
RetVec.push_back(ExitUntag);
589-
}
531+
memtag::StackInfoBuilder SIB(
532+
[this](const AllocaInst &AI) { return isInterestingAlloca(AI); });
533+
for (Instruction &I : instructions(F))
534+
SIB.visit(I);
535+
memtag::StackInfo &SInfo = SIB.get();
590536

591-
if (InterestingAllocas.empty())
537+
if (SInfo.AllocasToInstrument.empty())
592538
return false;
593539

594-
for (auto &I : InterestingAllocas) {
595-
AllocaInfo &Info = I.second;
540+
for (auto &I : SInfo.AllocasToInstrument) {
541+
memtag::AllocaInfo &Info = I.second;
596542
assert(Info.AI && isInterestingAlloca(*Info.AI));
597543
alignAndPadAlloca(Info);
598544
}
@@ -602,7 +548,7 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
602548
if (auto *P = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
603549
DT = &P->getDomTree();
604550

605-
if (DT == nullptr && (InterestingAllocas.size() > 1 ||
551+
if (DT == nullptr && (SInfo.AllocasToInstrument.size() > 1 ||
606552
!F->hasFnAttribute(Attribute::OptimizeNone))) {
607553
DeleteDT = std::make_unique<DominatorTree>(*F);
608554
DT = DeleteDT.get();
@@ -621,11 +567,11 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
621567
SetTagFunc =
622568
Intrinsic::getDeclaration(F->getParent(), Intrinsic::aarch64_settag);
623569

624-
Instruction *Base = insertBaseTaggedPointer(InterestingAllocas, DT);
570+
Instruction *Base = insertBaseTaggedPointer(SInfo.AllocasToInstrument, DT);
625571

626572
int NextTag = 0;
627-
for (auto &I : InterestingAllocas) {
628-
const AllocaInfo &Info = I.second;
573+
for (auto &I : SInfo.AllocasToInstrument) {
574+
const memtag::AllocaInfo &Info = I.second;
629575
AllocaInst *AI = Info.AI;
630576
int Tag = NextTag;
631577
NextTag = (NextTag + 1) % 16;
@@ -642,15 +588,15 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
642588
TagPCall->setOperand(0, Info.AI);
643589

644590
bool StandardLifetime =
645-
UnrecognizedLifetimes.empty() &&
591+
SInfo.UnrecognizedLifetimes.empty() &&
646592
memtag::isStandardLifetime(Info.LifetimeStart, Info.LifetimeEnd, DT,
647593
ClMaxLifetimes);
648594
// Calls to functions that may return twice (e.g. setjmp) confuse the
649595
// postdominator analysis, and will leave us to keep memory tagged after
650596
// function return. Work around this by always untagging at every return
651597
// statement if return_twice functions are called.
652-
if (UnrecognizedLifetimes.empty() && StandardLifetime &&
653-
!CallsReturnTwice) {
598+
if (SInfo.UnrecognizedLifetimes.empty() && StandardLifetime &&
599+
!SInfo.CallsReturnTwice) {
654600
IntrinsicInst *Start = Info.LifetimeStart[0];
655601
uint64_t Size =
656602
cast<ConstantInt>(Start->getArgOperand(0))->getZExtValue();
@@ -660,15 +606,15 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
660606
auto TagEnd = [&](Instruction *Node) { untagAlloca(AI, Node, Size); };
661607
if (!DT || !PDT ||
662608
!memtag::forAllReachableExits(*DT, *PDT, Start, Info.LifetimeEnd,
663-
RetVec, TagEnd)) {
609+
SInfo.RetVec, TagEnd)) {
664610
for (auto *End : Info.LifetimeEnd)
665611
End->eraseFromParent();
666612
}
667613
} else {
668614
uint64_t Size = Info.AI->getAllocationSizeInBits(*DL).getValue() / 8;
669615
Value *Ptr = IRB.CreatePointerCast(TagPCall, IRB.getInt8PtrTy());
670616
tagAlloca(AI, &*IRB.GetInsertPoint(), Ptr, Size);
671-
for (auto &RI : RetVec) {
617+
for (auto &RI : SInfo.RetVec) {
672618
untagAlloca(AI, RI, Size);
673619
}
674620
// We may have inserted tag/untag outside of any lifetime interval.
@@ -686,7 +632,7 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
686632

687633
// If we have instrumented at least one alloca, all unrecognized lifetime
688634
// instrinsics have to go.
689-
for (auto &I : UnrecognizedLifetimes)
635+
for (auto &I : SInfo.UnrecognizedLifetimes)
690636
I->eraseFromParent();
691637

692638
return true;

llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ void StackInfoBuilder::visit(Instruction &Inst) {
6565
}
6666
}
6767
if (AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
68-
if (IsInterestingAlloca(*AI))
69-
Info.AllocasToInstrument.insert({AI, {}});
68+
if (IsInterestingAlloca(*AI)) {
69+
Info.AllocasToInstrument[AI].AI = AI;
70+
Info.AllocasToInstrument[AI].OldAI = AI;
71+
}
7072
return;
7173
}
7274
auto *II = dyn_cast<IntrinsicInst>(&Inst);

0 commit comments

Comments
 (0)