@@ -290,14 +290,6 @@ class InitializerBuilder {
290290};
291291
292292class 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
468460Instruction *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 ;
0 commit comments