99#include < utility>
1010#include < llvm/Analysis/CallGraph.h>
1111#include " tsar/Analysis/Memory/RestrictionArgumentsPass.h"
12+ #include " ../../../../../../sapfor-build/llvm-project/llvm/lib/IR/ConstantsContext.h"
1213#include < llvm/Analysis/CallGraph.h>
1314#include < llvm/Analysis/CallGraphSCCPass.h>
1415#include < llvm/ADT/SCCIterator.h>
@@ -32,7 +33,7 @@ INITIALIZE_PASS_END(RestrictionArgumentsPass, "restriction-arguments",
3233DenseSet<Value*> collectGlobalMemorySources(Module* M) {
3334 DenseSet<Value *> GlobalMemorySources;
3435 for (auto &GV : M->getGlobalList ()) {
35- if (GV.getType ()->isPointerTy ()) {
36+ if (GV.getValueType ()->isPointerTy () || GV. getValueType ()-> isArrayTy ()) {
3637 GlobalMemorySources.insert (&GV);
3738 }
3839 }
@@ -93,25 +94,49 @@ DenseSet<int> findPointerArgumentsIndexes(Function* F) {
9394}
9495
9596DenseSet<CallInst*> collectCallsOfFunctionsWithPointerArguments (Function* F) {
96- DenseSet<CallInst*> CallsOfFunctionsWithPointerArguments;
97- for (auto & I : instructions (F)) {
98- if (auto * CallI = dyn_cast<CallInst>(&I)) {
99- auto * CalledF = CallI->getCalledFunction ();
100- // LLVM_DEBUG(
101- // dbgs() << "\tCallInst";
102- // CallI->dump();
103- // dbgs() << "\tCalling Function: ";
104- // CalledF->dump();
105- // );
106- if (!CalledF->isIntrinsic ()) {
107- int PointerArgsAmount = countPointerArguments (CalledF);
108- if (PointerArgsAmount > 0 ) {
109- CallsOfFunctionsWithPointerArguments.insert (CallI);
97+ DenseSet<CallInst*> CallsOfFunctionsWithPointerArguments;
98+ for (auto & I : instructions (F)) {
99+ if (auto * CallI = dyn_cast<CallInst>(&I)) {
100+ auto * CalledF = CallI->getCalledFunction ();
101+ if (CalledF) {
102+ LLVM_DEBUG (
103+ dbgs () << " \t CallInst" ;
104+ CallI->dump ();
105+ dbgs () << " \t Calling Function: " << CalledF->getName () << " \n " ;
106+ );
107+ if (!CalledF->isIntrinsic ()) {
108+ int PointerArgsAmount = countPointerArguments (CalledF);
109+ if (PointerArgsAmount > 0 ) {
110+ CallsOfFunctionsWithPointerArguments.insert (CallI);
111+ }
112+ }
113+ // dealing with call void bitcast (void (...)* @foo to void ()*)()
114+ } else if (auto *CstExpr = dyn_cast<ConstantExpr>(&I)) {
115+ if (CstExpr->isCast ()) {
116+ auto *Arg = CstExpr->getOperand (0 );
117+ if (Arg) {
118+ if (auto * CallArgI = dyn_cast<CallInst>(Arg)) {
119+ auto * CalledArgF = CallArgI->getCalledFunction ();
120+ if (CalledArgF) {
121+ LLVM_DEBUG (
122+ dbgs () << " \t Internal CallInst" ;
123+ CallArgI->dump ();
124+ dbgs () << " \t Internal Calling Function: " << CalledArgF->getName () << " \n " ;
125+ );
126+ if (!CalledArgF->isIntrinsic ()) {
127+ int PointerArgsAmount = countPointerArguments (CalledArgF);
128+ if (PointerArgsAmount > 0 ) {
129+ CallsOfFunctionsWithPointerArguments.insert (CallArgI);
130+ }
110131 }
132+ }
111133 }
134+ }
112135 }
136+ }
113137 }
114- return CallsOfFunctionsWithPointerArguments;
138+ }
139+ return CallsOfFunctionsWithPointerArguments;
115140}
116141
117142DenseMap<CallInst*, FunctionCallWithMemorySources> initCallsToPtrArgumentsMemorySources (DenseSet<CallInst*>& FunctionsCalls) {
@@ -123,73 +148,77 @@ DenseMap<CallInst*, FunctionCallWithMemorySources> initCallsToPtrArgumentsMemory
123148}
124149
125150DenseMap<CallInst*, FunctionCallWithMemorySources> fillCallsToPtrArgumentsMemorySources (
126- DenseSet<CallInst*>& TargetFunctionsCalls,
127- DenseSet<Value*>& MemorySources,
128- DenseMap<Function*, FunctionResultArgumentsMemoryDependencies>& FunctionsReturnValuesDependencies) {
129- auto CallsToPtrArgumentsMemorySources = initCallsToPtrArgumentsMemorySources (TargetFunctionsCalls);
130- // First inst in pair is a workpiece, second - its memory source
131- SmallVector<ValueWithMemorySources, 16 > workList;
132- for (auto * I : MemorySources) {
133- workList.push_back (ValueWithMemorySources (I, I));
134- }
135- while (!workList.empty ()) {
136- auto WorkPair = workList.back ();
137- auto * I = WorkPair.mV ;
138- auto & memorySources = WorkPair.mMemorySources ;
139- workList.pop_back ();
140- for (auto * U : I->users ()) {
141- if (auto * GepU = dyn_cast<GEPOperator>(U)) {
142- workList.push_back (ValueWithMemorySources (GepU, memorySources));
143- } else if (auto * CastI = dyn_cast<CastInst>(U)) {
144- workList.push_back (ValueWithMemorySources (CastI, memorySources));
145- } else if (auto * SelectI = dyn_cast<SelectInst>(U)) {
146- workList.push_back (ValueWithMemorySources (SelectI, memorySources));
147- } else if (auto * LoadI = dyn_cast<LoadInst>(U)) {
148- workList.push_back (ValueWithMemorySources (LoadI, memorySources));
149- } else if (auto * CallI = dyn_cast<CallInst>(U)) {
150- if (TargetFunctionsCalls.count (CallI)) {
151- LLVM_DEBUG (
152- dbgs () << " \t Found CallInst in TargetCalls: " ;
153- CallI->dump ();
154- dbgs () << " \t Memory Sources: \n " ;
155- for (auto * S : memorySources) {
156- dbgs () << " \t\t " ;
157- S->dump ();
158- }
159- );
160- for (int i = 0 ; i < CallI->getNumArgOperands (); i++) {
161- auto * Arg = CallI->getArgOperand (i);
162- if (Arg == I) {
163- if (CallsToPtrArgumentsMemorySources[CallI].mArgumentMemorySources .count (i)) {
164- CallsToPtrArgumentsMemorySources[CallI].mArgumentMemorySources [i].insert (memorySources.begin (), memorySources.end ());
165- }
166- else {
167- CallsToPtrArgumentsMemorySources[CallI].mArgumentMemorySources .insert (
168- std::make_pair (i, memorySources)
169- );
170- }
171- }
172- }
173- }
174- auto * TargetFunction = CallI->getCalledFunction ();
175- if (FunctionsReturnValuesDependencies.count (TargetFunction) &&
176- !FunctionsReturnValuesDependencies[TargetFunction].mInfluencingArgumentsIndexes .empty ()) {
177- auto & InfluencingArgumentsIndexes = FunctionsReturnValuesDependencies[TargetFunction].mInfluencingArgumentsIndexes ;
178- bool shouldProcess = false ;
179- for (int i = 0 ; i < CallI->getNumArgOperands (); i++) {
180- auto * Arg = CallI->getArgOperand (i);
181- if (Arg == I && InfluencingArgumentsIndexes.count (i)) {
182- shouldProcess = true ;
183- }
184- }
185- if (shouldProcess) {
186- workList.push_back (ValueWithMemorySources (CallI, memorySources));
187- }
188- }
151+ DenseSet<CallInst*>& TargetFunctionsCalls,
152+ DenseSet<Value*>& MemorySources,
153+ DenseMap<Function*, FunctionResultArgumentsMemoryDependencies>& FunctionsReturnValuesDependencies) {
154+ auto CallsToPtrArgumentsMemorySources = initCallsToPtrArgumentsMemorySources (TargetFunctionsCalls);
155+ // First inst in pair is a workpiece, second - its memory source
156+ SmallVector<ValueWithMemorySources, 16 > workList;
157+ for (auto * I : MemorySources) {
158+ workList.push_back (ValueWithMemorySources (I, I));
159+ }
160+ while (!workList.empty ()) {
161+ auto WorkPair = workList.back ();
162+ auto * I = WorkPair.mV ;
163+ auto & memorySources = WorkPair.mMemorySources ;
164+ workList.pop_back ();
165+ for (auto * U : I->users ()) {
166+ if (auto * GepOp = dyn_cast<GEPOperator>(U)) {
167+ workList.push_back (ValueWithMemorySources (GepOp, memorySources));
168+ } else if (auto * BitCastOp = dyn_cast<BitCastOperator>(U)) {
169+ workList.push_back (ValueWithMemorySources (BitCastOp, memorySources));
170+ } else if (auto * CastI = dyn_cast<CastInst>(U)) {
171+ workList.push_back (ValueWithMemorySources (CastI, memorySources));
172+ } else if (auto * SelectI = dyn_cast<SelectInst>(U)) {
173+ workList.push_back (ValueWithMemorySources (SelectI, memorySources));
174+ } else if (auto * LoadI = dyn_cast<LoadInst>(U)) {
175+ workList.push_back (ValueWithMemorySources (LoadI, memorySources));
176+ } else if (auto * CallI = dyn_cast<CallInst>(U)) {
177+ if (TargetFunctionsCalls.count (CallI)) {
178+ LLVM_DEBUG (
179+ dbgs () << " \t Found CallInst in TargetCalls: " ;
180+ CallI->dump ();
181+ dbgs () << " \t Memory Sources: \n " ;
182+ for (auto * S : memorySources) {
183+ dbgs () << " \t\t " ;
184+ S->dump ();
185+ }
186+ );
187+ for (int i = 0 ; i < CallI->getNumArgOperands (); i++) {
188+ auto * Arg = CallI->getArgOperand (i);
189+ if (Arg == I) {
190+ if (CallsToPtrArgumentsMemorySources[CallI].mArgumentMemorySources .count (i)) {
191+ CallsToPtrArgumentsMemorySources[CallI].mArgumentMemorySources [i].insert (memorySources.begin (), memorySources.end ());
192+ }
193+ else {
194+ CallsToPtrArgumentsMemorySources[CallI].mArgumentMemorySources .insert (
195+ std::make_pair (i, memorySources)
196+ );
197+ }
198+ }
199+ }
200+ }
201+ auto * TargetFunction = CallI->getCalledFunction ();
202+ if (FunctionsReturnValuesDependencies.count (TargetFunction) &&
203+ !FunctionsReturnValuesDependencies[TargetFunction].mInfluencingArgumentsIndexes .empty ()) {
204+ auto & InfluencingArgumentsIndexes = FunctionsReturnValuesDependencies[TargetFunction].mInfluencingArgumentsIndexes ;
205+ bool shouldProcess = false ;
206+ for (int i = 0 ; i < CallI->getNumArgOperands (); i++) {
207+ auto * Arg = CallI->getArgOperand (i);
208+ if (Arg == I && InfluencingArgumentsIndexes.count (i)) {
209+ shouldProcess = true ;
189210 }
211+ }
212+ if (shouldProcess) {
213+ workList.push_back (ValueWithMemorySources (CallI, memorySources));
214+ }
190215 }
216+ // } else if (auto* ConstExpr = dyn_cast<UnaryConstantExpr>(U)) {
217+ // workList.push_back(ValueWithMemorySources(ConstExpr, memorySources));
218+ }
191219 }
192- return CallsToPtrArgumentsMemorySources;
220+ }
221+ return CallsToPtrArgumentsMemorySources;
193222}
194223
195224// Maps Function to calls info for each pointer argument index
@@ -659,73 +688,74 @@ DenseMap<Function*, FunctionResultArgumentsMemoryDependencies> findFunctionsRetu
659688}
660689
661690bool RestrictionArgumentsPass::runOnModule (Module& M) {
662- LLVM_DEBUG (
663- dbgs () << " [RESTRICTION ARGS]" << " \n " ;
664- M.dump ();
665- );
666-
667- DenseMap<Function*, DenseSet<int >> RestrictFunctionsInfo;
668- DenseMap<Function*, DenseSet<int >> NonRestrictFunctionsInfo;
669-
670- auto & CG = getAnalysis<CallGraphWrapperPass>().getCallGraph ();
691+ LLVM_DEBUG (
692+ dbgs () << " [RESTRICTION ARGS]" << " \n " ;
693+ M.dump ();
694+ );
671695
672- auto FunctionsReturnValuesDependencies = findFunctionsReturnValueDependencies (CG);
673- std::vector<Function*> UpwardCalledFunctions;
674- for (scc_iterator<CallGraph*> CallGraphIterator = scc_begin (&CG); !CallGraphIterator.isAtEnd (); ++CallGraphIterator) {
675- const std::vector<CallGraphNode*>& NodeVec = *CallGraphIterator;
676- if (NodeVec.size () > 1 ) {
677- LLVM_DEBUG (
678- dbgs () << " [RESTRICTION ARGS] Can't process recursion in the Call Graph. First func: \n " ;
679- NodeVec[0 ]->dump ();
680- );
681- }
682- else {
683- for (CallGraphNode* CGNode : *CallGraphIterator) {
684- if (Function* F = CGNode->getFunction ()) {
685- if (F->isIntrinsic ())
686- continue ;
687- UpwardCalledFunctions.push_back (F);
688- }
689- }
696+ DenseMap<Function*, DenseSet<int >> RestrictFunctionsInfo;
697+ DenseMap<Function*, DenseSet<int >> NonRestrictFunctionsInfo;
698+
699+ auto & CG = getAnalysis<CallGraphWrapperPass>().getCallGraph ();
700+
701+ auto FunctionsReturnValuesDependencies = findFunctionsReturnValueDependencies (CG);
702+ std::vector<Function*> UpwardCalledFunctions;
703+ for (scc_iterator<CallGraph*> CallGraphIterator = scc_begin (&CG); !CallGraphIterator.isAtEnd (); ++CallGraphIterator) {
704+ const std::vector<CallGraphNode*>& NodeVec = *CallGraphIterator;
705+ if (NodeVec.size () > 1 ) {
706+ LLVM_DEBUG (
707+ dbgs () << " [RESTRICTION ARGS] Can't process recursion in the Call Graph. First func: \n " ;
708+ NodeVec[0 ]->dump ();
709+ );
710+ }
711+ else {
712+ for (CallGraphNode* CGNode : *CallGraphIterator) {
713+ if (Function* F = CGNode->getFunction ()) {
714+ if (F->isIntrinsic ())
715+ continue ;
716+ UpwardCalledFunctions.push_back (F);
690717 }
718+ }
691719 }
720+ }
692721
693- DenseSet<Value *> GlobalMemorySources = collectGlobalMemorySources (&M);
694-
695- for (auto * F : llvm::reverse (UpwardCalledFunctions)) {
696- runOnFunction (F, RestrictFunctionsInfo, NonRestrictFunctionsInfo, FunctionsReturnValuesDependencies, GlobalMemorySources);
697- }
698-
699- LLVM_DEBUG (
700- dbgs () << " [RESTRICTION ARGS] Restrict Functions: \n " ;
701- for (auto & FInfo : RestrictFunctionsInfo) {
702- auto F = FInfo.first ;
703- auto & Args = FInfo.second ;
704- dbgs () << " \t " << F->getName () << " \n " ;
705- std::set<int > orderedArgs (Args.begin (), Args.end ());
706- for (auto ArgIdx : orderedArgs) {
707- dbgs () << " \t\t " << ArgIdx << " \n " ;
708- }
722+ DenseSet<Value *> GlobalMemorySources = collectGlobalMemorySources (&M);
723+ LLVM_DEBUG (
724+ dbgs () << " [RESTRICTION ARGS] Global memory sources: \n " ;
725+ for (auto & GMS : GlobalMemorySources) {
726+ dbgs () << " \t " ;
727+ GMS->dump ();
709728 }
729+ );
710730
711- dbgs () << " [RESTRICTION ARGS] Functions with Non Restrict calls:\n " ;
712- for (auto & FInfo : NonRestrictFunctionsInfo) {
713- auto F = FInfo.first ;
714- auto & Args = FInfo.second ;
715- dbgs () << " \t " << F->getName () << " \n " ;
716- std::set<int > orderedArgs (Args.begin (), Args.end ());
717- for (auto ArgIdx : orderedArgs) {
718- dbgs () << " \t\t " << ArgIdx << " \n " ;
719- }
720- }
731+ for (auto * F : llvm::reverse (UpwardCalledFunctions)) {
732+ runOnFunction (F, RestrictFunctionsInfo, NonRestrictFunctionsInfo, FunctionsReturnValuesDependencies, GlobalMemorySources);
733+ }
734+
735+ LLVM_DEBUG (
736+ dbgs () << " [RESTRICTION ARGS] Restrict Functions: \n " ;
737+ for (auto & FInfo : RestrictFunctionsInfo) {
738+ auto F = FInfo.first ;
739+ auto & Args = FInfo.second ;
740+ dbgs () << " \t " << F->getName () << " \n " ;
741+ std::set<int > orderedArgs (Args.begin (), Args.end ());
742+ for (auto ArgIdx : orderedArgs) {
743+ dbgs () << " \t\t " << ArgIdx << " \n " ;
744+ }
745+ }
721746
722- dbgs () << " [RESTRICTION ARGS] Global vars:\n " ;
723- for (auto & GV : GlobalMemorySources) {
724- dbgs () << " \t " << GV->getName () << " \n " ;
725- GV->dump ();
747+ dbgs () << " [RESTRICTION ARGS] Functions with Non Restrict calls:\n " ;
748+ for (auto & FInfo : NonRestrictFunctionsInfo) {
749+ auto F = FInfo.first ;
750+ auto & Args = FInfo.second ;
751+ dbgs () << " \t " << F->getName () << " \n " ;
752+ std::set<int > orderedArgs (Args.begin (), Args.end ());
753+ for (auto ArgIdx : orderedArgs) {
754+ dbgs () << " \t\t " << ArgIdx << " \n " ;
726755 }
727- );
728- return false ;
756+ }
757+ );
758+ return false ;
729759}
730760
731761void RestrictionArgumentsPass::getAnalysisUsage (llvm::AnalysisUsage& AU) const {
0 commit comments