Skip to content

Commit 667b26b

Browse files
authored
Merge pull request github#5540 from hvitved/csharp/ssa-impl-tweaks
C#: Performance tweaks in `SsaImplCommon.qll`
2 parents a23d8de + e345064 commit 667b26b

File tree

4 files changed

+80
-76
lines changed

4 files changed

+80
-76
lines changed

csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,9 @@ private module SsaDefReaches {
321321
}
322322

323323
pragma[noinline]
324-
private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) {
325-
result = getABasicBlockSuccessor(bb) and
326-
not defOccursInBlock(_, bb, def.getSourceVariable()) and
327-
ssaDefReachesEndOfBlock(bb, def, _)
324+
private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) {
325+
ssaDefReachesEndOfBlock(bb, def, _) and
326+
not defOccursInBlock(_, bb, def.getSourceVariable())
328327
}
329328

330329
/**
@@ -337,7 +336,11 @@ private module SsaDefReaches {
337336
defOccursInBlock(def, bb1, _) and
338337
bb2 = getABasicBlockSuccessor(bb1)
339338
or
340-
exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid))
339+
exists(BasicBlock mid |
340+
varBlockReaches(def, bb1, mid) and
341+
ssaDefReachesThroughBlock(def, mid) and
342+
bb2 = getABasicBlockSuccessor(mid)
343+
)
341344
}
342345

343346
/**
@@ -355,17 +358,10 @@ private module SsaDefReaches {
355358

356359
private import SsaDefReaches
357360

358-
pragma[noinline]
359-
private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) {
360-
exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) |
361-
// The construction of SSA form ensures that each read of a variable is
362-
// dominated by its definition. An SSA definition therefore reaches a
363-
// control flow node if it is the _closest_ SSA definition that dominates
364-
// the node. If two definitions dominate a node then one must dominate the
365-
// other, so therefore the definition of _closest_ is given by the dominator
366-
// tree. Thus, reaching definitions can be calculated in terms of dominance.
367-
idom = getImmediateBasicBlockDominator(bb)
368-
)
361+
pragma[nomagic]
362+
predicate liveThrough(BasicBlock bb, SourceVariable v) {
363+
liveAtExit(bb, v) and
364+
not ssaRef(bb, _, v, SsaDef())
369365
}
370366

371367
/**
@@ -382,9 +378,14 @@ predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable
382378
liveAtExit(bb, v)
383379
)
384380
or
385-
ssaDefReachesEndOfBlockRec(bb, def, v) and
386-
liveAtExit(bb, v) and
387-
not ssaRef(bb, _, v, SsaDef())
381+
// The construction of SSA form ensures that each read of a variable is
382+
// dominated by its definition. An SSA definition therefore reaches a
383+
// control flow node if it is the _closest_ SSA definition that dominates
384+
// the node. If two definitions dominate a node then one must dominate the
385+
// other, so therefore the definition of _closest_ is given by the dominator
386+
// tree. Thus, reaching definitions can be calculated in terms of dominance.
387+
ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and
388+
liveThrough(bb, pragma[only_bind_into](v))
388389
}
389390

390391
/**

csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,9 @@ private module SsaDefReaches {
321321
}
322322

323323
pragma[noinline]
324-
private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) {
325-
result = getABasicBlockSuccessor(bb) and
326-
not defOccursInBlock(_, bb, def.getSourceVariable()) and
327-
ssaDefReachesEndOfBlock(bb, def, _)
324+
private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) {
325+
ssaDefReachesEndOfBlock(bb, def, _) and
326+
not defOccursInBlock(_, bb, def.getSourceVariable())
328327
}
329328

330329
/**
@@ -337,7 +336,11 @@ private module SsaDefReaches {
337336
defOccursInBlock(def, bb1, _) and
338337
bb2 = getABasicBlockSuccessor(bb1)
339338
or
340-
exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid))
339+
exists(BasicBlock mid |
340+
varBlockReaches(def, bb1, mid) and
341+
ssaDefReachesThroughBlock(def, mid) and
342+
bb2 = getABasicBlockSuccessor(mid)
343+
)
341344
}
342345

343346
/**
@@ -355,17 +358,10 @@ private module SsaDefReaches {
355358

356359
private import SsaDefReaches
357360

358-
pragma[noinline]
359-
private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) {
360-
exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) |
361-
// The construction of SSA form ensures that each read of a variable is
362-
// dominated by its definition. An SSA definition therefore reaches a
363-
// control flow node if it is the _closest_ SSA definition that dominates
364-
// the node. If two definitions dominate a node then one must dominate the
365-
// other, so therefore the definition of _closest_ is given by the dominator
366-
// tree. Thus, reaching definitions can be calculated in terms of dominance.
367-
idom = getImmediateBasicBlockDominator(bb)
368-
)
361+
pragma[nomagic]
362+
predicate liveThrough(BasicBlock bb, SourceVariable v) {
363+
liveAtExit(bb, v) and
364+
not ssaRef(bb, _, v, SsaDef())
369365
}
370366

371367
/**
@@ -382,9 +378,14 @@ predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable
382378
liveAtExit(bb, v)
383379
)
384380
or
385-
ssaDefReachesEndOfBlockRec(bb, def, v) and
386-
liveAtExit(bb, v) and
387-
not ssaRef(bb, _, v, SsaDef())
381+
// The construction of SSA form ensures that each read of a variable is
382+
// dominated by its definition. An SSA definition therefore reaches a
383+
// control flow node if it is the _closest_ SSA definition that dominates
384+
// the node. If two definitions dominate a node then one must dominate the
385+
// other, so therefore the definition of _closest_ is given by the dominator
386+
// tree. Thus, reaching definitions can be calculated in terms of dominance.
387+
ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and
388+
liveThrough(bb, pragma[only_bind_into](v))
388389
}
389390

390391
/**

csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,9 @@ private module SsaDefReaches {
321321
}
322322

323323
pragma[noinline]
324-
private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) {
325-
result = getABasicBlockSuccessor(bb) and
326-
not defOccursInBlock(_, bb, def.getSourceVariable()) and
327-
ssaDefReachesEndOfBlock(bb, def, _)
324+
private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) {
325+
ssaDefReachesEndOfBlock(bb, def, _) and
326+
not defOccursInBlock(_, bb, def.getSourceVariable())
328327
}
329328

330329
/**
@@ -337,7 +336,11 @@ private module SsaDefReaches {
337336
defOccursInBlock(def, bb1, _) and
338337
bb2 = getABasicBlockSuccessor(bb1)
339338
or
340-
exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid))
339+
exists(BasicBlock mid |
340+
varBlockReaches(def, bb1, mid) and
341+
ssaDefReachesThroughBlock(def, mid) and
342+
bb2 = getABasicBlockSuccessor(mid)
343+
)
341344
}
342345

343346
/**
@@ -355,17 +358,10 @@ private module SsaDefReaches {
355358

356359
private import SsaDefReaches
357360

358-
pragma[noinline]
359-
private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) {
360-
exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) |
361-
// The construction of SSA form ensures that each read of a variable is
362-
// dominated by its definition. An SSA definition therefore reaches a
363-
// control flow node if it is the _closest_ SSA definition that dominates
364-
// the node. If two definitions dominate a node then one must dominate the
365-
// other, so therefore the definition of _closest_ is given by the dominator
366-
// tree. Thus, reaching definitions can be calculated in terms of dominance.
367-
idom = getImmediateBasicBlockDominator(bb)
368-
)
361+
pragma[nomagic]
362+
predicate liveThrough(BasicBlock bb, SourceVariable v) {
363+
liveAtExit(bb, v) and
364+
not ssaRef(bb, _, v, SsaDef())
369365
}
370366

371367
/**
@@ -382,9 +378,14 @@ predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable
382378
liveAtExit(bb, v)
383379
)
384380
or
385-
ssaDefReachesEndOfBlockRec(bb, def, v) and
386-
liveAtExit(bb, v) and
387-
not ssaRef(bb, _, v, SsaDef())
381+
// The construction of SSA form ensures that each read of a variable is
382+
// dominated by its definition. An SSA definition therefore reaches a
383+
// control flow node if it is the _closest_ SSA definition that dominates
384+
// the node. If two definitions dominate a node then one must dominate the
385+
// other, so therefore the definition of _closest_ is given by the dominator
386+
// tree. Thus, reaching definitions can be calculated in terms of dominance.
387+
ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and
388+
liveThrough(bb, pragma[only_bind_into](v))
388389
}
389390

390391
/**

csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,9 @@ private module SsaDefReaches {
321321
}
322322

323323
pragma[noinline]
324-
private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) {
325-
result = getABasicBlockSuccessor(bb) and
326-
not defOccursInBlock(_, bb, def.getSourceVariable()) and
327-
ssaDefReachesEndOfBlock(bb, def, _)
324+
private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) {
325+
ssaDefReachesEndOfBlock(bb, def, _) and
326+
not defOccursInBlock(_, bb, def.getSourceVariable())
328327
}
329328

330329
/**
@@ -337,7 +336,11 @@ private module SsaDefReaches {
337336
defOccursInBlock(def, bb1, _) and
338337
bb2 = getABasicBlockSuccessor(bb1)
339338
or
340-
exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid))
339+
exists(BasicBlock mid |
340+
varBlockReaches(def, bb1, mid) and
341+
ssaDefReachesThroughBlock(def, mid) and
342+
bb2 = getABasicBlockSuccessor(mid)
343+
)
341344
}
342345

343346
/**
@@ -355,17 +358,10 @@ private module SsaDefReaches {
355358

356359
private import SsaDefReaches
357360

358-
pragma[noinline]
359-
private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) {
360-
exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) |
361-
// The construction of SSA form ensures that each read of a variable is
362-
// dominated by its definition. An SSA definition therefore reaches a
363-
// control flow node if it is the _closest_ SSA definition that dominates
364-
// the node. If two definitions dominate a node then one must dominate the
365-
// other, so therefore the definition of _closest_ is given by the dominator
366-
// tree. Thus, reaching definitions can be calculated in terms of dominance.
367-
idom = getImmediateBasicBlockDominator(bb)
368-
)
361+
pragma[nomagic]
362+
predicate liveThrough(BasicBlock bb, SourceVariable v) {
363+
liveAtExit(bb, v) and
364+
not ssaRef(bb, _, v, SsaDef())
369365
}
370366

371367
/**
@@ -382,9 +378,14 @@ predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable
382378
liveAtExit(bb, v)
383379
)
384380
or
385-
ssaDefReachesEndOfBlockRec(bb, def, v) and
386-
liveAtExit(bb, v) and
387-
not ssaRef(bb, _, v, SsaDef())
381+
// The construction of SSA form ensures that each read of a variable is
382+
// dominated by its definition. An SSA definition therefore reaches a
383+
// control flow node if it is the _closest_ SSA definition that dominates
384+
// the node. If two definitions dominate a node then one must dominate the
385+
// other, so therefore the definition of _closest_ is given by the dominator
386+
// tree. Thus, reaching definitions can be calculated in terms of dominance.
387+
ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and
388+
liveThrough(bb, pragma[only_bind_into](v))
388389
}
389390

390391
/**

0 commit comments

Comments
 (0)