3030#include " phasar/Utils/Logger.h"
3131
3232#include " llvm/ADT/SmallVector.h"
33+ #include " llvm/ADT/Twine.h"
3334#include " llvm/IR/Argument.h"
3435#include " llvm/IR/Attributes.h"
3536#include " llvm/IR/Constant.h"
@@ -629,26 +630,19 @@ class IDEInstInteractionAnalysisT
629630 // variables using generalized initial seeds
630631
631632 // Generate zero value at the entry points
632- Seeds.addSeed (SP, this ->getZeroValue (), bottomElement () );
633+ Seeds.addSeed (SP, this ->getZeroValue (), Bottom{} );
633634 // Generate formal parameters of entry points, e.g. main(). Formal
634635 // parameters will otherwise cause trouble by overriding alloca
635636 // instructions without being valid data-flow facts themselves.
636637 for (const auto &Arg : SP->getFunction ()->args ()) {
637- Seeds.addSeed (SP, &Arg, Bottom{} );
638+ Seeds.addSeed (SP, &Arg, BitVectorSet< e_t >() );
638639 }
639640 // Generate all global variables using generalized initial seeds
640641
641642 for (const auto &G : this ->IRDB ->getModule ()->globals ()) {
642643 if (const auto *GV = llvm::dyn_cast<llvm::GlobalVariable>(&G)) {
643- l_t InitialValues = BitVectorSet<e_t >();
644- std::set<e_t > EdgeFacts;
645- if (EdgeFactGen) {
646- EdgeFacts = EdgeFactGen (GV);
647- // fill BitVectorSet
648- InitialValues =
649- BitVectorSet<e_t >(EdgeFacts.begin (), EdgeFacts.end ());
650- }
651- Seeds.addSeed (SP, GV, InitialValues);
644+ l_t InitialValues = bvSetFrom (invoke_or_default (EdgeFactGen, GV));
645+ Seeds.addSeed (SP, GV, std::move (InitialValues));
652646 }
653647 }
654648 });
@@ -691,7 +685,12 @@ class IDEInstInteractionAnalysisT
691685 if (SuccNode == Store->getPointerOperand () ||
692686 PT.isInReachableAllocationSites (Store->getPointerOperand (), SuccNode,
693687 true , Store)) {
694- return IIAAAddLabelsEFCache.createEdgeFunction (UserEdgeFacts);
688+ if (isZeroValue (CurrNode)) {
689+ return IIAAKillOrReplaceEFCache.createEdgeFunction (
690+ std::move (UserEdgeFacts));
691+ }
692+ return IIAAAddLabelsEFCache.createEdgeFunction (
693+ std::move (UserEdgeFacts));
695694 }
696695 }
697696
@@ -709,7 +708,7 @@ class IDEInstInteractionAnalysisT
709708 // v
710709 // y
711710 //
712- if (( CurrNode == SuccNode) && CurrNode == Store->getPointerOperand ()) {
711+ if (CurrNode == SuccNode && CurrNode == Store->getPointerOperand ()) {
713712 // y obtains its value(s) from its original allocation and the store
714713 // instruction under analysis.
715714 IF_LOG_ENABLED ({
@@ -722,7 +721,8 @@ class IDEInstInteractionAnalysisT
722721 PHASAR_LOG_LEVEL (DFADEBUG, ' \n ' );
723722 });
724723 // obtain label from the original allocation
725- return IIAAKillOrReplaceEFCache.createEdgeFunction (UserEdgeFacts);
724+ return IIAAKillOrReplaceEFCache.createEdgeFunction (
725+ std::move (UserEdgeFacts));
726726 }
727727
728728 } else {
@@ -800,7 +800,11 @@ class IDEInstInteractionAnalysisT
800800
801801 // We generate Curr in this instruction, so we have to annotate it with
802802 // edge labels
803- return IIAAAddLabelsEFCache.createEdgeFunction (UserEdgeFacts);
803+ if (isZeroValue (CurrNode)) {
804+ return IIAAKillOrReplaceEFCache.createEdgeFunction (
805+ std::move (UserEdgeFacts));
806+ }
807+ return IIAAAddLabelsEFCache.createEdgeFunction (std::move (UserEdgeFacts));
804808 }
805809
806810 // Otherwise stick to identity.
@@ -835,7 +839,7 @@ class IDEInstInteractionAnalysisT
835839 }
836840 }
837841 if (isZeroValue (SrcNode) && SRetParams.count (DestNode)) {
838- return IIAAAddLabelsEFCache .createEdgeFunction ();
842+ return IIAAKillOrReplaceEFCache .createEdgeFunction ();
839843 }
840844 // Everything else can be passed as identity.
841845 return EdgeIdentity<l_t >{};
@@ -863,14 +867,8 @@ class IDEInstInteractionAnalysisT
863867 if (const auto *CD =
864868 llvm::dyn_cast<llvm::ConstantData>(Ret->getReturnValue ())) {
865869 // Check if the user has registered a fact generator function
866- l_t UserEdgeFacts = BitVectorSet<e_t >();
867- std::set<e_t > EdgeFacts;
868- if (EdgeFactGen) {
869- EdgeFacts = EdgeFactGen (ExitInst);
870- // fill BitVectorSet
871- UserEdgeFacts = BitVectorSet<e_t >(EdgeFacts.begin (), EdgeFacts.end ());
872- }
873- return IIAAAddLabelsEFCache.createEdgeFunction (
870+ l_t UserEdgeFacts = bvSetFrom (invoke_or_default (EdgeFactGen, ExitInst));
871+ return IIAAKillOrReplaceEFCache.createEdgeFunction (
874872 std::move (UserEdgeFacts));
875873 }
876874 }
@@ -883,34 +881,29 @@ class IDEInstInteractionAnalysisT
883881 d_t RetSiteNode,
884882 llvm::ArrayRef<f_t > Callees) override {
885883 // Check if the user has registered a fact generator function
886- l_t UserEdgeFacts = BitVectorSet<e_t >();
887- std::set<e_t > EdgeFacts;
888- if (EdgeFactGen) {
889- EdgeFacts = EdgeFactGen (CallSite);
890- // fill BitVectorSet
891- UserEdgeFacts = BitVectorSet<e_t >(EdgeFacts.begin (), EdgeFacts.end ());
892- }
884+ l_t UserEdgeFacts = bvSetFrom (invoke_or_default (EdgeFactGen, CallSite));
885+
893886 // Model call to heap allocating functions (new, new[], malloc, etc.) --
894887 // only model direct calls, though.
895888 if (Callees.size () == 1 ) {
896- for (const auto *Callee : Callees) {
897- if (this ->ICF ->isHeapAllocatingFunction (Callee)) {
898- // Let H be a heap allocating function.
899- //
900- // 0 --> x
901- //
902- // Edge function:
903- //
904- // 0
905- // \
889+ const auto *Callee = Callees.front ();
890+
891+ if (this ->ICF ->isHeapAllocatingFunction (Callee)) {
892+ // Let H be a heap allocating function.
893+ //
894+ // 0 --> x
895+ //
896+ // Edge function:
897+ //
898+ // 0
899+ // \
906900 // %i = call H \ \x.x \cup { commit of('%i = call H') }
907- // v
908- // i
909- //
910- if (isZeroValue (CallNode) && RetSiteNode == CallSite) {
911- return IIAAAddLabelsEFCache.createEdgeFunction (
912- std::move (UserEdgeFacts));
913- }
901+ // v
902+ // i
903+ //
904+ if (isZeroValue (CallNode) && RetSiteNode == CallSite) {
905+ return IIAAKillOrReplaceEFCache.createEdgeFunction (
906+ std::move (UserEdgeFacts));
914907 }
915908 }
916909 }
@@ -944,10 +937,6 @@ class IDEInstInteractionAnalysisT
944937 return nullptr ;
945938 }
946939
947- inline l_t topElement () override { return Top{}; }
948-
949- inline l_t bottomElement () override { return Bottom{}; }
950-
951940 inline l_t join (l_t Lhs, l_t Rhs) override { return joinImpl (Lhs, Rhs); }
952941
953942 // Provide some handy helper edge functions to improve reuse.
@@ -956,7 +945,7 @@ class IDEInstInteractionAnalysisT
956945 // others).
957946 struct IIAAKillOrReplaceEF {
958947 using l_t = typename AnalysisDomainTy::l_t ;
959- l_t Replacement{} ;
948+ l_t Replacement = BitVectorSet< e_t >() ;
960949
961950 l_t computeTarget (ByConstRef<l_t > /* Src */ ) const { return Replacement; }
962951
@@ -972,27 +961,13 @@ class IDEInstInteractionAnalysisT
972961 " IIAAKillOrReplaceEF is too large for SOO" );
973962
974963 if (auto *AD = llvm::dyn_cast<IIAAAddLabelsEF>(SecondFunction)) {
975- auto ADCache =
976- SecondFunction.template getCacheOrNull <IIAAAddLabelsEF>();
977- assert (ADCache != nullptr );
978- if (This->isKillAll ()) {
979- return ADCache->createEdgeFunction (*AD);
980- }
981964 auto Union =
982965 IDEInstInteractionAnalysisT::joinImpl (This->Replacement , AD->Data );
983- return ADCache ->createEdgeFunction (std::move (Union));
966+ return Cache ->createEdgeFunction (std::move (Union));
984967 }
985968
986969 if (auto *KR = llvm::dyn_cast<IIAAKillOrReplaceEF>(SecondFunction)) {
987- if (This->isKillAll ()) {
988- return Cache->createEdgeFunction (*KR);
989- }
990- if (KR->isKillAll ()) {
991- return SecondFunction;
992- }
993- auto Union = IDEInstInteractionAnalysisT::joinImpl (This->Replacement ,
994- KR->Replacement );
995- return Cache->createEdgeFunction (std::move (Union));
970+ return SecondFunction;
996971 }
997972 llvm::report_fatal_error (
998973 " found unexpected edge function in 'IIAAKillOrReplaceEF'" );
@@ -1033,6 +1008,8 @@ class IDEInstInteractionAnalysisT
10331008 return Replacement == Other.Replacement ;
10341009 }
10351010
1011+ [[nodiscard]] bool isConstant () const noexcept { return true ; }
1012+
10361013 friend llvm::raw_ostream &operator <<(llvm::raw_ostream &OS,
10371014 const IIAAKillOrReplaceEF &EF) {
10381015 OS << " EF: (IIAAKillOrReplaceEF)<->" ;
@@ -1061,7 +1038,7 @@ class IDEInstInteractionAnalysisT
10611038 // add all labels provided by Data.
10621039 struct IIAAAddLabelsEF {
10631040 using l_t = typename AnalysisDomainTy::l_t ;
1064- l_t Data{} ;
1041+ l_t Data = BitVectorSet< e_t >() ;
10651042
10661043 l_t computeTarget (ByConstRef<l_t > Src) const {
10671044 return IDEInstInteractionAnalysisT::joinImpl (Src, Data);
@@ -1083,7 +1060,7 @@ class IDEInstInteractionAnalysisT
10831060 return Cache->createEdgeFunction (std::move (Union));
10841061 }
10851062 if (auto *KR = llvm::dyn_cast<IIAAKillOrReplaceEF>(SecondFunction)) {
1086- return Cache-> createEdgeFunction (KR-> Replacement ) ;
1063+ return SecondFunction ;
10871064 }
10881065 llvm::report_fatal_error (
10891066 " found unexpected edge function in 'IIAAAddLabelsEF'" );
@@ -1214,9 +1191,8 @@ class IDEInstInteractionAnalysisT
12141191 }
12151192
12161193protected:
1217- static inline bool isZeroValueImpl (d_t d) {
1218- return LLVMZeroValue::isLLVMZeroValue (d);
1219- }
1194+ // NOLINTNEXTLINE(readability-identifier-naming)
1195+ static constexpr auto isZeroValueImpl = LLVMZeroValue::isLLVMZeroValue;
12201196
12211197 static void printEdgeFactImpl (llvm::raw_ostream &OS,
12221198 ByConstRef<l_t > EdgeFact) {
@@ -1244,10 +1220,10 @@ class IDEInstInteractionAnalysisT
12441220 }
12451221
12461222 static inline l_t joinImpl (ByConstRef<l_t > Lhs, ByConstRef<l_t > Rhs) {
1247- if (Lhs.isTop () || Lhs .isBottom ()) {
1223+ if (Lhs.isTop () || Rhs .isBottom ()) {
12481224 return Rhs;
12491225 }
1250- if (Rhs.isTop () || Rhs .isBottom ()) {
1226+ if (Rhs.isTop () || Lhs .isBottom ()) {
12511227 return Lhs;
12521228 }
12531229 const auto &LhsSet = std::get<BitVectorSet<e_t >>(Lhs);
@@ -1270,7 +1246,7 @@ class IDEInstInteractionAnalysisT
12701246 // at some point. Therefore, we only care for the variables and their
12711247 // associated values and ignore at which point a variable may holds as a
12721248 // data-flow fact.
1273- const auto Variable = Result.getColumnKey ();
1249+ const auto & Variable = Result.getColumnKey ();
12741250 const auto &Value = Result.getValue ();
12751251 // skip result entry if variable is not in the set of all variables
12761252 if (Variables.find (Variable) == Variables.end ()) {
0 commit comments