@@ -162,8 +162,9 @@ class IDEInstInteractionAnalysisT
162162 // Global variables may only be initialized once.
163163 // They may also be initialized within getCallToRetFlowFunction() in case an
164164 // entry point is a function call. (See getCallToRetFlowFunction().)
165- if (InitGlobals && Seeds.countInitialSeeds (curr)) {
166- InitGlobals = false ; // We are initializing globals here now.
165+ if (Seeds.countInitialSeeds (curr) && !InitializedGlobalsAtSeed[curr]) {
166+ InitializedGlobalsAtSeed[curr] =
167+ true ; // We are initializing globals here now.
167168 std::set<d_t > Globals;
168169 for (const auto *Mod : this ->IRDB ->getAllModules ()) {
169170 for (const auto &Global : Mod->globals ()) {
@@ -491,7 +492,8 @@ class IDEInstInteractionAnalysisT
491492 if (this ->ICF ->isHeapAllocatingFunction (destMthd)) {
492493 // Kill add facts and model the effects in getCallToRetFlowFunction().
493494 return KillAll<d_t >::getInstance ();
494- } else if (destMthd->isDeclaration ()) {
495+ }
496+ if (destMthd->isDeclaration ()) {
495497 // We don't have anything that we could analyze, kill all facts.
496498 return KillAll<d_t >::getInstance ();
497499 }
@@ -557,28 +559,6 @@ class IDEInstInteractionAnalysisT
557559 inline FlowFunctionPtrType
558560 getCallToRetFlowFunction (n_t callSite, n_t retSite,
559561 std::set<f_t > callees) override {
560- // Model call to heap allocating functions (new, new[], malloc, etc.) --
561- // only model direct calls, though.
562- if (callees.size () == 1 ) {
563- for (const auto *Callee : callees) {
564- if (this ->ICF ->isHeapAllocatingFunction (Callee)) {
565- // In case a heap allocating function is called, generate the pointer
566- // that is returned.
567- //
568- // Flow function:
569- //
570- // Let H be a heap allocating function.
571- //
572- // 0
573- // |\
574- // x = call H | \
575- // v v
576- // 0 x
577- //
578- return std::make_shared<Gen<d_t >>(callSite, this ->getZeroValue ());
579- }
580- }
581- }
582562 // The entry point of a function may also be a call statement, which is why
583563 // we need to replicate the global generating code that we already saw in
584564 // getNormalFlowFunction(). Generate all global variables and handle the
@@ -596,22 +576,47 @@ class IDEInstInteractionAnalysisT
596576 // v v v
597577 // 0 x G
598578 //
599- // Variable that will hold our generating globals function.
600- FlowFunctionPtrType GlobalFlowFun = nullptr ;
601579 // Global variables may only be initialized once.
602580 // They may also be initialized within getCallToRetFlowFunction() in case an
603581 // entry point is a function call. (See getCallToRetFlowFunction().)
604- if (InitGlobals && Seeds.countInitialSeeds (callSite)) {
605- InitGlobals = false ; // We are initializing globals here now.
582+ if (Seeds.countInitialSeeds (callSite) && !InitializedGlobalsAtSeed[callSite] ) {
583+ InitializedGlobalsAtSeed[callSite] = true ; // We are initializing globals here now.
606584 std::set<d_t > Globals;
607585 for (const auto *Mod : this ->IRDB ->getAllModules ()) {
608586 for (const auto &Global : Mod->globals ()) {
609587 Globals.insert (&Global); // collect all global variables
610588 }
611589 }
612590 // Create the flow function that generates the globals.
613- GlobalFlowFun =
591+ auto GlobalFlowFun =
614592 std::make_shared<GenAll<d_t >>(Globals, this ->getZeroValue ());
593+ // Create the flow function for the instruction we are currently misusing.
594+ auto FlowFun = getCallToRetFlowFunction (callSite, retSite, callees);
595+ return std::make_shared<Union<d_t >>(
596+ std::vector<FlowFunctionPtrType>({FlowFun, GlobalFlowFun}));
597+ }
598+
599+ // Model call to heap allocating functions (new, new[], malloc, etc.) --
600+ // only model direct calls, though.
601+ if (callees.size () == 1 ) {
602+ for (const auto *Callee : callees) {
603+ if (this ->ICF ->isHeapAllocatingFunction (Callee)) {
604+ // In case a heap allocating function is called, generate the pointer
605+ // that is returned.
606+ //
607+ // Flow function:
608+ //
609+ // Let H be a heap allocating function.
610+ //
611+ // 0
612+ // |\
613+ // x = call H | \
614+ // v v
615+ // 0 x
616+ //
617+ return std::make_shared<Gen<d_t >>(callSite, this ->getZeroValue ());
618+ }
619+ }
615620 }
616621 // Just use the auto mapping for values, pointer parameters and global
617622 // variables are killed and handled by getCallFlowfunction() and
@@ -628,35 +633,19 @@ class IDEInstInteractionAnalysisT
628633 }
629634 // Declarations only case
630635 if (OnlyDecls) {
631- auto PassAsId =
632- std::make_shared<MapFactsAlongsideCallSite<container_type>>(
633- llvm::cast<llvm::CallBase>(callSite),
634- true /* propagate globals alongsite the call site */ ,
635- [](const llvm::CallBase *CS, const llvm::Value *V) {
636- return false ; // not involved in the call
637- });
638- if (GlobalFlowFun) {
639- // We potentially need to combine this flow function with the global
640- // generating flow function.
641- return std::make_shared<Union<d_t >>(
642- std::vector<FlowFunctionPtrType>({PassAsId, GlobalFlowFun}));
643- }
644- return PassAsId;
636+ return std::make_shared<MapFactsAlongsideCallSite<container_type>>(
637+ llvm::cast<llvm::CallBase>(callSite),
638+ true /* propagate globals alongsite the call site */ ,
639+ [](const llvm::CallBase *CS, const llvm::Value *V) {
640+ return false ; // not involved in the call
641+ });
645642 }
646643 // Otherwise
647- auto KillGlobals =
648- std::make_shared<MapFactsAlongsideCallSite<container_type>>(
649- llvm::cast<llvm::CallBase>(callSite),
650- false // do not propagate globals (as they are propagated via call-
651- // and ret-functions)
652- );
653- if (GlobalFlowFun) {
654- // We potentially need to combine this flow function with the global
655- // generating flow function.
656- return std::make_shared<Union<d_t >>(
657- std::vector<FlowFunctionPtrType>({KillGlobals, GlobalFlowFun}));
658- }
659- return KillGlobals;
644+ return std::make_shared<MapFactsAlongsideCallSite<container_type>>(
645+ llvm::cast<llvm::CallBase>(callSite),
646+ false // do not propagate globals (as they are propagated via call-
647+ // and ret-functions)
648+ );
660649 }
661650
662651 inline FlowFunctionPtrType getSummaryFlowFunction (n_t callSite,
@@ -1552,7 +1541,8 @@ class IDEInstInteractionAnalysisT
15521541
15531542 // TODO This is only a temporary mechanism to handle global variables.
15541543 InitialSeeds<n_t , d_t , l_t > Seeds;
1555- bool InitGlobals = true ; // Globals must be initialized!
1544+ std::unordered_map<n_t , bool >
1545+ InitializedGlobalsAtSeed; // Globals must be initialized!
15561546
15571547}; // namespace psr
15581548
0 commit comments