@@ -242,7 +242,7 @@ static void printInstsShort(raw_ostream &OS,
242242 }
243243}
244244
245- raw_ostream &operator <<(raw_ostream &OS, const SrcState &S) {
245+ static raw_ostream &operator <<(raw_ostream &OS, const SrcState &S) {
246246 OS << " src-state<" ;
247247 if (S.empty ()) {
248248 OS << " empty" ;
@@ -432,8 +432,7 @@ class SrcSafetyAnalysis {
432432 SrcStatePrinter P (BC);
433433 LLVM_DEBUG ({
434434 dbgs () << " SrcSafetyAnalysis::ComputeNext(" ;
435- BC.InstPrinter ->printInst (&const_cast <MCInst &>(Point), 0 , " " , *BC.STI ,
436- dbgs ());
435+ BC.InstPrinter ->printInst (&Point, 0 , " " , *BC.STI , dbgs ());
437436 dbgs () << " , " ;
438437 P.print (dbgs (), Cur);
439438 dbgs () << " )\n " ;
@@ -611,6 +610,42 @@ class DataflowSrcSafetyAnalysis
611610 StringRef getAnnotationName () const { return " DataflowSrcSafetyAnalysis" ; }
612611};
613612
613+ // / A helper base class for implementing a simplified counterpart of a dataflow
614+ // / analysis for functions without CFG information.
615+ template <typename StateTy> class CFGUnawareAnalysis {
616+ BinaryContext &BC;
617+ BinaryFunction &BF;
618+ MCPlusBuilder::AllocatorIdTy AllocId;
619+ unsigned StateAnnotationIndex;
620+
621+ void cleanStateAnnotations () {
622+ for (auto &I : BF.instrs ())
623+ BC.MIB ->removeAnnotation (I.second , StateAnnotationIndex);
624+ }
625+
626+ protected:
627+ CFGUnawareAnalysis (BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId,
628+ StringRef AnnotationName)
629+ : BC(BF.getBinaryContext()), BF(BF), AllocId(AllocId) {
630+ StateAnnotationIndex = BC.MIB ->getOrCreateAnnotationIndex (AnnotationName);
631+ }
632+
633+ void setState (MCInst &Inst, const StateTy &S) {
634+ // Check if we need to remove an old annotation (this is the case if
635+ // this is the second, detailed run of the analysis).
636+ if (BC.MIB ->hasAnnotation (Inst, StateAnnotationIndex))
637+ BC.MIB ->removeAnnotation (Inst, StateAnnotationIndex);
638+ // Attach the state.
639+ BC.MIB ->addAnnotation (Inst, StateAnnotationIndex, S, AllocId);
640+ }
641+
642+ const StateTy &getState (const MCInst &Inst) const {
643+ return BC.MIB ->getAnnotationAs <StateTy>(Inst, StateAnnotationIndex);
644+ }
645+
646+ ~CFGUnawareAnalysis () { cleanStateAnnotations (); }
647+ };
648+
614649// A simplified implementation of DataflowSrcSafetyAnalysis for functions
615650// lacking CFG information.
616651//
@@ -645,15 +680,10 @@ class DataflowSrcSafetyAnalysis
645680// of instructions without labels in between. These sequences can be processed
646681// the same way basic blocks are processed by data-flow analysis, assuming
647682// pessimistically that all registers are unsafe at the start of each sequence.
648- class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis {
683+ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis ,
684+ public CFGUnawareAnalysis<SrcState> {
685+ using SrcSafetyAnalysis::BC;
649686 BinaryFunction &BF;
650- MCPlusBuilder::AllocatorIdTy AllocId;
651- unsigned StateAnnotationIndex;
652-
653- void cleanStateAnnotations () {
654- for (auto &I : BF.instrs ())
655- BC.MIB ->removeAnnotation (I.second , StateAnnotationIndex);
656- }
657687
658688 // / Creates a state with all registers marked unsafe (not to be confused
659689 // / with empty state).
@@ -665,9 +695,8 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis {
665695 CFGUnawareSrcSafetyAnalysis (BinaryFunction &BF,
666696 MCPlusBuilder::AllocatorIdTy AllocId,
667697 ArrayRef<MCPhysReg> RegsToTrackInstsFor)
668- : SrcSafetyAnalysis(BF, RegsToTrackInstsFor), BF(BF), AllocId(AllocId) {
669- StateAnnotationIndex =
670- BC.MIB ->getOrCreateAnnotationIndex (" CFGUnawareSrcSafetyAnalysis" );
698+ : SrcSafetyAnalysis(BF, RegsToTrackInstsFor),
699+ CFGUnawareAnalysis (BF, AllocId, " CFGUnawareSrcSafetyAnalysis" ), BF(BF) {
671700 }
672701
673702 void run () override {
@@ -686,23 +715,17 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis {
686715 S = createUnsafeState ();
687716 }
688717
689- // Check if we need to remove an old annotation (this is the case if
690- // this is the second, detailed, run of the analysis).
691- if (BC.MIB ->hasAnnotation (Inst, StateAnnotationIndex))
692- BC.MIB ->removeAnnotation (Inst, StateAnnotationIndex);
693718 // Attach the state *before* this instruction executes.
694- BC. MIB -> addAnnotation (Inst, StateAnnotationIndex, S, AllocId );
719+ setState (Inst, S );
695720
696721 // Compute the state after this instruction executes.
697722 S = computeNext (Inst, S);
698723 }
699724 }
700725
701726 const SrcState &getStateBefore (const MCInst &Inst) const override {
702- return BC. MIB -> getAnnotationAs <SrcState> (Inst, StateAnnotationIndex );
727+ return getState (Inst);
703728 }
704-
705- ~CFGUnawareSrcSafetyAnalysis () { cleanStateAnnotations (); }
706729};
707730
708731std::shared_ptr<SrcSafetyAnalysis>
@@ -786,7 +809,7 @@ struct DstState {
786809 bool operator !=(const DstState &RHS) const { return !((*this ) == RHS); }
787810};
788811
789- raw_ostream &operator <<(raw_ostream &OS, const DstState &S) {
812+ static raw_ostream &operator <<(raw_ostream &OS, const DstState &S) {
790813 OS << " dst-state<" ;
791814 if (S.empty ()) {
792815 OS << " empty" ;
@@ -962,8 +985,7 @@ class DstSafetyAnalysis {
962985 DstStatePrinter P (BC);
963986 LLVM_DEBUG ({
964987 dbgs () << " DstSafetyAnalysis::ComputeNext(" ;
965- BC.InstPrinter ->printInst (&const_cast <MCInst &>(Point), 0 , " " , *BC.STI ,
966- dbgs ());
988+ BC.InstPrinter ->printInst (&Point, 0 , " " , *BC.STI , dbgs ());
967989 dbgs () << " , " ;
968990 P.print (dbgs (), Cur);
969991 dbgs () << " )\n " ;
@@ -1108,15 +1130,10 @@ class DataflowDstSafetyAnalysis
11081130 StringRef getAnnotationName () const { return " DataflowDstSafetyAnalysis" ; }
11091131};
11101132
1111- class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis {
1133+ class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis ,
1134+ public CFGUnawareAnalysis<DstState> {
1135+ using DstSafetyAnalysis::BC;
11121136 BinaryFunction &BF;
1113- MCPlusBuilder::AllocatorIdTy AllocId;
1114- unsigned StateAnnotationIndex;
1115-
1116- void cleanStateAnnotations () {
1117- for (auto &I : BF.instrs ())
1118- BC.MIB ->removeAnnotation (I.second , StateAnnotationIndex);
1119- }
11201137
11211138 DstState createUnsafeState () const {
11221139 return DstState (NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters ());
@@ -1126,9 +1143,8 @@ class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis {
11261143 CFGUnawareDstSafetyAnalysis (BinaryFunction &BF,
11271144 MCPlusBuilder::AllocatorIdTy AllocId,
11281145 ArrayRef<MCPhysReg> RegsToTrackInstsFor)
1129- : DstSafetyAnalysis(BF, RegsToTrackInstsFor), BF(BF), AllocId(AllocId) {
1130- StateAnnotationIndex =
1131- BC.MIB ->getOrCreateAnnotationIndex (" CFGUnawareDstSafetyAnalysis" );
1146+ : DstSafetyAnalysis(BF, RegsToTrackInstsFor),
1147+ CFGUnawareAnalysis (BF, AllocId, " CFGUnawareDstSafetyAnalysis" ), BF(BF) {
11321148 }
11331149
11341150 void run () override {
@@ -1146,23 +1162,17 @@ class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis {
11461162 S = createUnsafeState ();
11471163 }
11481164
1149- // Check if we need to remove an old annotation (this is the case if
1150- // this is the second, detailed, run of the analysis).
1151- if (BC.MIB ->hasAnnotation (Inst, StateAnnotationIndex))
1152- BC.MIB ->removeAnnotation (Inst, StateAnnotationIndex);
11531165 // Attach the state *after* this instruction executes.
1154- BC. MIB -> addAnnotation (Inst, StateAnnotationIndex, S, AllocId );
1166+ setState (Inst, S );
11551167
11561168 // Compute the next state.
11571169 S = computeNext (Inst, S);
11581170 }
11591171 }
11601172
11611173 const DstState &getStateAfter (const MCInst &Inst) const override {
1162- return BC. MIB -> getAnnotationAs <DstState> (Inst, StateAnnotationIndex );
1174+ return getState (Inst);
11631175 }
1164-
1165- ~CFGUnawareDstSafetyAnalysis () { cleanStateAnnotations (); }
11661176};
11671177
11681178std::shared_ptr<DstSafetyAnalysis>
0 commit comments