@@ -1977,13 +1977,23 @@ module IteratorFlow { |
1977 | 1977 | } |
1978 | 1978 |
|
1979 | 1979 | /** |
1980 | | - * Gets an ultimate definition of `def`. |
1981 | | - * |
1982 | | - * Note: Unlike `def.getAnUltimateDefinition()` this predicate also |
1983 | | - * traverses back through iterator increment and decrement operations. |
| 1980 | + * Holds if `write` is an instruction that writes to address `address` |
1984 | 1981 | */ |
1985 | | - private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) { |
1986 | | - result = def.getAnUltimateDefinition() |
| 1982 | + private predicate isIteratorWrite(Instruction write, Operand address) { |
| 1983 | + exists(Ssa::DefImpl writeDef, IRBlock bb, int i | |
| 1984 | + writeDef.hasIndexInBlock(_, bb, i) and |
| 1985 | + bb.getInstruction(i) = write and |
| 1986 | + address = writeDef.getAddressOperand() |
| 1987 | + ) |
| 1988 | + } |
| 1989 | + |
| 1990 | + private module GetAnUltimateDefinitionInput implements Ssa::GetAnUltimateDefinitionSig { |
| 1991 | + predicate isRelevantUltimateDefinition(Ssa::Definition def) { fwd(_, def) } |
| 1992 | + } |
| 1993 | + |
| 1994 | + private Ssa::Definition getAnUltimateDefinitionStep(Ssa::Definition def) { |
| 1995 | + result = |
| 1996 | + Ssa::GetAnUltimateDefinition<GetAnUltimateDefinitionInput>::getAnUltimateDefinition(def) |
1987 | 1997 | or |
1988 | 1998 | exists(IRBlock bb, int i, IteratorCrementCall crementCall, Ssa::SourceVariable sv | |
1989 | 1999 | crementCall = def.getValue().asInstruction().(StoreInstruction).getSourceValue() and |
@@ -1993,14 +2003,28 @@ module IteratorFlow { |
1993 | 2003 | ) |
1994 | 2004 | } |
1995 | 2005 |
|
1996 | | - /** |
1997 | | - * Holds if `write` is an instruction that writes to address `address` |
1998 | | - */ |
1999 | | - private predicate isIteratorWrite(Instruction write, Operand address) { |
2000 | | - exists(Ssa::DefImpl writeDef, IRBlock bb, int i | |
2001 | | - writeDef.hasIndexInBlock(_, bb, i) and |
2002 | | - bb.getInstruction(i) = write and |
2003 | | - address = writeDef.getAddressOperand() |
| 2006 | + private predicate isSource(GetsIteratorCall beginCall, Ssa::Definition def) { |
| 2007 | + exists(StoreInstruction beginStore | |
| 2008 | + beginStore = def.getValue().asInstruction() and |
| 2009 | + operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall) |
| 2010 | + ) |
| 2011 | + } |
| 2012 | + |
| 2013 | + private predicate isSink(Instruction writeToDeref, Ssa::Definition def) { |
| 2014 | + exists(IteratorPointerDereferenceCall starCall, Operand address, IRBlock bbStar, int iStar | |
| 2015 | + isIteratorWrite(writeToDeref, address) and |
| 2016 | + operandForFullyConvertedCall(address, starCall) and |
| 2017 | + bbStar.getInstruction(iStar) = starCall and |
| 2018 | + Ssa::ssaDefReachesRead(_, def, bbStar, iStar) |
| 2019 | + ) |
| 2020 | + } |
| 2021 | + |
| 2022 | + private predicate fwd(GetsIteratorCall beginCall, Ssa::Definition def) { |
| 2023 | + isSource(beginCall, def) |
| 2024 | + or |
| 2025 | + exists(Ssa::Definition def0 | |
| 2026 | + fwd(beginCall, def0) and |
| 2027 | + def0 = getAnUltimateDefinitionStep(def) |
2004 | 2028 | ) |
2005 | 2029 | } |
2006 | 2030 |
|
@@ -2016,17 +2040,9 @@ module IteratorFlow { |
2016 | 2040 | private predicate isIteratorStoreInstruction( |
2017 | 2041 | GetsIteratorCall beginCall, Instruction writeToDeref |
2018 | 2042 | ) { |
2019 | | - exists( |
2020 | | - StoreInstruction beginStore, IRBlock bbStar, int iStar, Ssa::Definition def, |
2021 | | - IteratorPointerDereferenceCall starCall, Ssa::Definition ultimate, Operand address |
2022 | | - | |
2023 | | - isIteratorWrite(writeToDeref, address) and |
2024 | | - operandForFullyConvertedCall(address, starCall) and |
2025 | | - bbStar.getInstruction(iStar) = starCall and |
2026 | | - Ssa::ssaDefReachesRead(_, def, bbStar, iStar) and |
2027 | | - ultimate = getAnUltimateDefinition*(def) and |
2028 | | - beginStore = ultimate.getValue().asInstruction() and |
2029 | | - operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall) |
| 2043 | + exists(Ssa::Definition def | |
| 2044 | + fwd(beginCall, def) and |
| 2045 | + isSink(writeToDeref, def) |
2030 | 2046 | ) |
2031 | 2047 | } |
2032 | 2048 |
|
|