Skip to content

Commit 0e9e5c3

Browse files
committed
improve on inst interaction analysis
1 parent ab38087 commit 0e9e5c3

3 files changed

Lines changed: 134 additions & 182 deletions

File tree

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/IDEInstInteractionAnalysis.h

Lines changed: 37 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,6 @@ class IDEInstInteractionAnalysisT
124124
this->ZeroValue =
125125
IDEInstInteractionAnalysisT<EdgeFactType, SyntacticAnalysisOnly,
126126
EnableIndirectTaints>::createZeroValue();
127-
this->Seeds =
128-
IDEInstInteractionAnalysisT<EdgeFactType, SyntacticAnalysisOnly,
129-
EnableIndirectTaints>::initialSeeds();
130127
IIAAAddLabelsEF::initEdgeFunctionCleaner();
131128
IIAAKillOrReplaceEF::initEdgeFunctionCleaner();
132129
}
@@ -144,42 +141,6 @@ class IDEInstInteractionAnalysisT
144141
// start formulating our analysis by specifying the parts required for IFDS
145142

146143
FlowFunctionPtrType getNormalFlowFunction(n_t curr, n_t succ) override {
147-
// Generate all global variables and handle the instruction that we
148-
// currently misuse to generate them.
149-
// TODO The handling of global variables, global constructors and global
150-
// destructors will soon be possible using a dedicated mechanism.
151-
//
152-
// Flow function:
153-
//
154-
// Let G be the set of global variables.
155-
//
156-
// 0
157-
// |\
158-
// some instruction | \--\
159-
// v v v
160-
// 0 x G
161-
//
162-
// Global variables may only be initialized once.
163-
// They may also be initialized within getCallToRetFlowFunction() in case an
164-
// entry point is a function call. (See getCallToRetFlowFunction().)
165-
if (Seeds.countInitialSeeds(curr) && !InitializedGlobalsAtSeed[curr]) {
166-
InitializedGlobalsAtSeed[curr] =
167-
true; // We are initializing globals here now.
168-
std::set<d_t> Globals;
169-
for (const auto *Mod : this->IRDB->getAllModules()) {
170-
for (const auto &Global : Mod->globals()) {
171-
Globals.insert(&Global); // collect all global variables
172-
}
173-
}
174-
// Create the flow function that generates the globals.
175-
auto GlobalFlowFun =
176-
std::make_shared<GenAll<d_t>>(Globals, this->getZeroValue());
177-
// Create the flow function for the instruction we are currently misusing.
178-
auto FlowFun = getNormalFlowFunction(curr, succ);
179-
return std::make_shared<Union<d_t>>(
180-
std::vector<FlowFunctionPtrType>({FlowFun, GlobalFlowFun}));
181-
}
182-
183144
// Generate all local variables
184145
//
185146
// Flow function:
@@ -559,45 +520,6 @@ class IDEInstInteractionAnalysisT
559520
inline FlowFunctionPtrType
560521
getCallToRetFlowFunction(n_t callSite, n_t retSite,
561522
std::set<f_t> callees) override {
562-
// The entry point of a function may also be a call statement, which is why
563-
// we need to replicate the global generating code that we already saw in
564-
// getNormalFlowFunction(). Generate all global variables and handle the
565-
// instruction that we currently misuse to generate them.
566-
// TODO The handling of global variables, global constructors and global
567-
// destructors will soon be possible using a dedicated mechanism.
568-
//
569-
// Flow function:
570-
//
571-
// Let G be the set of global variables.
572-
//
573-
// 0
574-
// |\
575-
// some instruction | \--\
576-
// v v v
577-
// 0 x G
578-
//
579-
// Global variables may only be initialized once.
580-
// They may also be initialized within getCallToRetFlowFunction() in case an
581-
// entry point is a function call. (See getCallToRetFlowFunction().)
582-
if (Seeds.countInitialSeeds(callSite) &&
583-
!InitializedGlobalsAtSeed[callSite]) {
584-
InitializedGlobalsAtSeed[callSite] =
585-
true; // We are initializing globals here now.
586-
std::set<d_t> Globals;
587-
for (const auto *Mod : this->IRDB->getAllModules()) {
588-
for (const auto &Global : Mod->globals()) {
589-
Globals.insert(&Global); // collect all global variables
590-
}
591-
}
592-
// Create the flow function that generates the globals.
593-
auto GlobalFlowFun =
594-
std::make_shared<GenAll<d_t>>(Globals, this->getZeroValue());
595-
// Create the flow function for the instruction we are currently misusing.
596-
auto FlowFun = getCallToRetFlowFunction(callSite, retSite, callees);
597-
return std::make_shared<Union<d_t>>(
598-
std::vector<FlowFunctionPtrType>({FlowFun, GlobalFlowFun}));
599-
}
600-
601523
// Model call to heap allocating functions (new, new[], malloc, etc.) --
602524
// only model direct calls, though.
603525
if (callees.size() == 1) {
@@ -634,20 +556,17 @@ class IDEInstInteractionAnalysisT
634556
}
635557
}
636558
// Declarations only case
637-
if (OnlyDecls) {
638-
return std::make_shared<MapFactsAlongsideCallSite<container_type>>(
639-
llvm::cast<llvm::CallBase>(callSite),
640-
true /* propagate globals alongsite the call site */,
641-
[](const llvm::CallBase *CS, const llvm::Value *V) {
642-
return false; // not involved in the call
643-
});
644-
}
645-
// Otherwise
646559
return std::make_shared<MapFactsAlongsideCallSite<container_type>>(
647560
llvm::cast<llvm::CallBase>(callSite),
648-
false // do not propagate globals (as they are propagated via call-
649-
// and ret-functions)
650-
);
561+
OnlyDecls /* Propagate globals alongsite the call site if no function
562+
definition is available. Otherwise, do not propagate
563+
globals here (as they are propagated via call- and
564+
ret-functions. */
565+
,
566+
[](const llvm::CallBase *CS, const llvm::Value *V) {
567+
return false; // treat as not involved in the call since this also
568+
// caputes usages of the parameter
569+
});
651570
}
652571

653572
inline FlowFunctionPtrType getSummaryFlowFunction(n_t callSite,
@@ -658,10 +577,31 @@ class IDEInstInteractionAnalysisT
658577

659578
inline InitialSeeds<n_t, d_t, l_t> initialSeeds() override {
660579
InitialSeeds<n_t, d_t, l_t> Seeds;
580+
std::set<const llvm::Function *> EntryPointFuns;
661581
for (const auto &EntryPoint : this->EntryPoints) {
662-
for (const auto *StartPoint :
663-
this->ICF->getStartPointsOf(this->ICF->getFunction(EntryPoint))) {
664-
Seeds.addSeed(StartPoint, this->getZeroValue(), this->bottomElement());
582+
EntryPointFuns.insert(this->IRDB->getFunctionDefinition(EntryPoint));
583+
}
584+
// Set initial seeds at the required entry points and generate the global
585+
// variables using generalized initial seeds
586+
for (const auto *EntryPointFun : EntryPointFuns) {
587+
// Generate zero value at the entry points
588+
Seeds.addSeed(&EntryPointFun->front().front(), this->getZeroValue(),
589+
bottomElement());
590+
// Generate all global variables using generalized initial seeds
591+
for (const auto *M : this->IRDB->getAllModules()) {
592+
for (const auto &G : M->globals()) {
593+
if (const auto *GV = llvm::dyn_cast<llvm::GlobalVariable>(&G)) {
594+
l_t InitialValues = BitVectorSet<e_t>();
595+
std::set<e_t> EdgeFacts;
596+
if (edgeFactGen) {
597+
EdgeFacts = edgeFactGen(GV);
598+
// fill BitVectorSet
599+
InitialValues =
600+
BitVectorSet<e_t>(EdgeFacts.begin(), EdgeFacts.end());
601+
}
602+
Seeds.addSeed(&EntryPointFun->front().front(), GV, InitialValues);
603+
}
604+
}
665605
}
666606
}
667607
return Seeds;
@@ -721,39 +661,6 @@ class IDEInstInteractionAnalysisT
721661
return IIAAAddLabelsEF::createEdgeFunction(UserEdgeFacts);
722662
}
723663
}
724-
// TODO use new mechanism to handle globals.
725-
//
726-
// Zero --> Global edges
727-
//
728-
// Edge function:
729-
//
730-
// Let g be a global variable.
731-
//
732-
// 0
733-
// \
734-
// non-call/non-return instruction \ \x.x \cup { commit of('@global') }
735-
// v
736-
// g
737-
//
738-
static auto Globals = [this]() {
739-
std::set<d_t> Globals;
740-
for (const auto *Mod : this->IRDB->getAllModules()) {
741-
for (const auto &G : Mod->globals()) {
742-
Globals.insert(&G);
743-
}
744-
}
745-
return Globals;
746-
}();
747-
if (Seeds.containsInitialSeedsFor(curr) && isZeroValue(currNode) &&
748-
Globals.count(succNode)) {
749-
if (const auto *GlobalVarDef =
750-
llvm::dyn_cast<llvm::GlobalVariable>(succNode)) {
751-
EdgeFacts = edgeFactGen(GlobalVarDef);
752-
// fill BitVectorSet
753-
UserEdgeFacts = BitVectorSet<e_t>(EdgeFacts.begin(), EdgeFacts.end());
754-
return IIAAAddLabelsEF::createEdgeFunction(UserEdgeFacts);
755-
}
756-
}
757664
//
758665
// i --> i edges
759666
//
@@ -1112,41 +1019,9 @@ class IDEInstInteractionAnalysisT
11121019
}
11131020
}
11141021
}
1115-
// TODO use new mechanism to handle globals.
1116-
//
1117-
// Zero --> Global edges
1118-
//
1119-
// Edge function:
1120-
//
1121-
// Let g be a global variable.
1122-
//
1123-
// 0
1124-
// \
1125-
// some callsite \ \x.x \cup { commit of('@global') }
1126-
// v
1127-
// g
1128-
//
1129-
static auto Globals = [this]() {
1130-
std::set<d_t> Globals;
1131-
for (const auto *Mod : this->IRDB->getAllModules()) {
1132-
for (const auto &G : Mod->globals()) {
1133-
Globals.insert(&G);
1134-
}
1135-
}
1136-
return Globals;
1137-
}();
1138-
if (Seeds.countInitialSeeds(callSite) && isZeroValue(callNode) &&
1139-
Globals.count(retSiteNode)) {
1140-
if (const auto *GlobalVarDef =
1141-
llvm::dyn_cast<llvm::GlobalVariable>(retSiteNode)) {
1142-
EdgeFacts = edgeFactGen(GlobalVarDef);
1143-
// fill BitVectorSet
1144-
UserEdgeFacts = BitVectorSet<e_t>(EdgeFacts.begin(), EdgeFacts.end());
1145-
return IIAAAddLabelsEF::createEdgeFunction(UserEdgeFacts);
1146-
}
1147-
}
1148-
// Capture interactions of the call instruction and its operands.
1149-
for (const auto &Op : callSite->operands()) {
1022+
// Capture interactions of the call instruction and its arguments.
1023+
const auto *CS = llvm::dyn_cast<llvm::CallBase>(callSite);
1024+
for (const auto &Arg : CS->args()) {
11501025
//
11511026
// o_i --> o_i
11521027
//
@@ -1158,7 +1033,7 @@ class IDEInstInteractionAnalysisT
11581033
// v
11591034
// o_i
11601035
//
1161-
if (callNode == Op && callNode == retSiteNode) {
1036+
if (callNode == Arg && callNode == retSiteNode) {
11621037
return IIAAAddLabelsEF::createEdgeFunction(UserEdgeFacts);
11631038
}
11641039
}
@@ -1541,11 +1416,6 @@ class IDEInstInteractionAnalysisT
15411416
return {};
15421417
}
15431418

1544-
// TODO This is only a temporary mechanism to handle global variables.
1545-
InitialSeeds<n_t, d_t, l_t> Seeds;
1546-
std::unordered_map<n_t, bool>
1547-
InitializedGlobalsAtSeed; // Globals must be initialized!
1548-
15491419
}; // namespace psr
15501420

15511421
using IDEInstInteractionAnalysis = IDEInstInteractionAnalysisT<>;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
int GlobalFeature = 2;
2+
3+
int doStuff(int i) { return i + 52; }
4+
5+
int main(int argc, char *argv[]) {
6+
int Sum = argc;
7+
8+
switch (GlobalFeature + argc) {
9+
case 0:
10+
return 21;
11+
case 1:
12+
Sum += 2;
13+
case 7:
14+
Sum += 3;
15+
break;
16+
case 2:
17+
Sum += 4;
18+
break;
19+
case 4:
20+
Sum += 4;
21+
break;
22+
}
23+
24+
Sum = doStuff(Sum);
25+
26+
Sum += 42;
27+
28+
return Sum;
29+
}

0 commit comments

Comments
 (0)