Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6385528

Browse files
committed
C++/C#: Fix getIRTypeForPRValue join order
This predicate was taking 39s on a snapshot of Facebook Fizz because it had disjuncts like this: 43685 ~0% {1} r34 = JOIN Type::FunctionPointerIshType#f AS L WITH Type::Type::getUnspecifiedType_dispred#ff_10#join_rhs AS R ON FIRST 1 OUTPUT R.<1> 43685 ~1% {2} r35 = JOIN r34 WITH CppType::getTypeSize#ff AS R ON FIRST 1 OUTPUT R.<1>, r34.<0> 170371500 ~2% {2} r36 = JOIN r35 WITH IRType::IRSizedType#ff_10#join_rhs AS R ON FIRST 1 OUTPUT R.<1>, r35.<1> 43685 ~6% {2} r37 = JOIN r36 WITH IRType::IRFunctionAddressType#class#ff AS R ON FIRST 1 OUTPUT r36.<1>, r36.<0> Instead of fixing the joins in `getIRTypeForPRValue` itself, I've changed the `IRType::getByteSize` predicate such that the optimiser knows how to join with it efficiently. The disjunct shown above now looks like this instead: 43685 ~0% {1} r26 = JOIN Type::FunctionPointerIshType#f AS L WITH Type::Type::getUnspecifiedType_dispred#ff_10#join_rhs AS R ON FIRST 1 OUTPUT R.<1> 43685 ~1% {2} r27 = JOIN r26 WITH CppType::getTypeSize#ff AS R ON FIRST 1 OUTPUT R.<1>, r26.<0> 43685 ~6% {2} r28 = JOIN r27 WITH IRType::IRFunctionAddressType::getByteSize#ff_10#join_rhs AS R ON FIRST 1 OUTPUT r27.<1>, R.<1>
1 parent 20ae183 commit 6385528

2 files changed

Lines changed: 50 additions & 4 deletions

File tree

  • cpp/ql/src/semmle/code/cpp/ir/implementation
  • csharp/ql/src/semmle/code/csharp/ir/implementation

cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ class IRType extends TIRType {
4242
*
4343
* This will hold for all `IRType` objects except `IRUnknownType`.
4444
*/
45+
// This predicate is overridden with `pragma[noinline]` in every leaf subclass.
46+
// This allows callers to ask for things like _the_ floating-point type of
47+
// size 4 without getting a join that first finds all types of size 4 and
48+
// _then_ restricts them to floating-point types.
4549
int getByteSize() { none() }
4650

4751
/**
@@ -104,8 +108,6 @@ private class IRSizedType extends IRType {
104108
this = TIRFunctionAddressType(byteSize) or
105109
this = TIROpaqueType(_, byteSize)
106110
}
107-
108-
final override int getByteSize() { result = byteSize }
109111
}
110112

111113
/**
@@ -117,6 +119,9 @@ class IRBooleanType extends IRSizedType, TIRBooleanType {
117119
final override Language::LanguageType getCanonicalLanguageType() {
118120
result = Language::getCanonicalBooleanType(byteSize)
119121
}
122+
123+
pragma[noinline]
124+
final override int getByteSize() { result = byteSize }
120125
}
121126

122127
/**
@@ -141,6 +146,9 @@ class IRSignedIntegerType extends IRNumericType, TIRSignedIntegerType {
141146
final override Language::LanguageType getCanonicalLanguageType() {
142147
result = Language::getCanonicalSignedIntegerType(byteSize)
143148
}
149+
150+
pragma[noinline]
151+
final override int getByteSize() { result = byteSize }
144152
}
145153

146154
/**
@@ -153,6 +161,9 @@ class IRUnsignedIntegerType extends IRNumericType, TIRUnsignedIntegerType {
153161
final override Language::LanguageType getCanonicalLanguageType() {
154162
result = Language::getCanonicalUnsignedIntegerType(byteSize)
155163
}
164+
165+
pragma[noinline]
166+
final override int getByteSize() { result = byteSize }
156167
}
157168

158169
/**
@@ -164,6 +175,9 @@ class IRFloatingPointType extends IRNumericType, TIRFloatingPointType {
164175
final override Language::LanguageType getCanonicalLanguageType() {
165176
result = Language::getCanonicalFloatingPointType(byteSize)
166177
}
178+
179+
pragma[noinline]
180+
final override int getByteSize() { result = byteSize }
167181
}
168182

169183
/**
@@ -178,6 +192,9 @@ class IRAddressType extends IRSizedType, TIRAddressType {
178192
final override Language::LanguageType getCanonicalLanguageType() {
179193
result = Language::getCanonicalAddressType(byteSize)
180194
}
195+
196+
pragma[noinline]
197+
final override int getByteSize() { result = byteSize }
181198
}
182199

183200
/**
@@ -190,6 +207,9 @@ class IRFunctionAddressType extends IRSizedType, TIRFunctionAddressType {
190207
final override Language::LanguageType getCanonicalLanguageType() {
191208
result = Language::getCanonicalFunctionAddressType(byteSize)
192209
}
210+
211+
pragma[noinline]
212+
final override int getByteSize() { result = byteSize }
193213
}
194214

195215
/**
@@ -218,6 +238,9 @@ class IROpaqueType extends IRSizedType, TIROpaqueType {
218238
* same size.
219239
*/
220240
final Language::OpaqueTypeTag getTag() { result = tag }
241+
242+
pragma[noinline]
243+
final override int getByteSize() { result = byteSize }
221244
}
222245

223246
module IRTypeSanity {

csharp/ql/src/semmle/code/csharp/ir/implementation/IRType.qll

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ class IRType extends TIRType {
4242
*
4343
* This will hold for all `IRType` objects except `IRUnknownType`.
4444
*/
45+
// This predicate is overridden with `pragma[noinline]` in every leaf subclass.
46+
// This allows callers to ask for things like _the_ floating-point type of
47+
// size 4 without getting a join that first finds all types of size 4 and
48+
// _then_ restricts them to floating-point types.
4549
int getByteSize() { none() }
4650

4751
/**
@@ -104,8 +108,6 @@ private class IRSizedType extends IRType {
104108
this = TIRFunctionAddressType(byteSize) or
105109
this = TIROpaqueType(_, byteSize)
106110
}
107-
108-
final override int getByteSize() { result = byteSize }
109111
}
110112

111113
/**
@@ -117,6 +119,9 @@ class IRBooleanType extends IRSizedType, TIRBooleanType {
117119
final override Language::LanguageType getCanonicalLanguageType() {
118120
result = Language::getCanonicalBooleanType(byteSize)
119121
}
122+
123+
pragma[noinline]
124+
final override int getByteSize() { result = byteSize }
120125
}
121126

122127
/**
@@ -141,6 +146,9 @@ class IRSignedIntegerType extends IRNumericType, TIRSignedIntegerType {
141146
final override Language::LanguageType getCanonicalLanguageType() {
142147
result = Language::getCanonicalSignedIntegerType(byteSize)
143148
}
149+
150+
pragma[noinline]
151+
final override int getByteSize() { result = byteSize }
144152
}
145153

146154
/**
@@ -153,6 +161,9 @@ class IRUnsignedIntegerType extends IRNumericType, TIRUnsignedIntegerType {
153161
final override Language::LanguageType getCanonicalLanguageType() {
154162
result = Language::getCanonicalUnsignedIntegerType(byteSize)
155163
}
164+
165+
pragma[noinline]
166+
final override int getByteSize() { result = byteSize }
156167
}
157168

158169
/**
@@ -164,6 +175,9 @@ class IRFloatingPointType extends IRNumericType, TIRFloatingPointType {
164175
final override Language::LanguageType getCanonicalLanguageType() {
165176
result = Language::getCanonicalFloatingPointType(byteSize)
166177
}
178+
179+
pragma[noinline]
180+
final override int getByteSize() { result = byteSize }
167181
}
168182

169183
/**
@@ -178,6 +192,9 @@ class IRAddressType extends IRSizedType, TIRAddressType {
178192
final override Language::LanguageType getCanonicalLanguageType() {
179193
result = Language::getCanonicalAddressType(byteSize)
180194
}
195+
196+
pragma[noinline]
197+
final override int getByteSize() { result = byteSize }
181198
}
182199

183200
/**
@@ -190,6 +207,9 @@ class IRFunctionAddressType extends IRSizedType, TIRFunctionAddressType {
190207
final override Language::LanguageType getCanonicalLanguageType() {
191208
result = Language::getCanonicalFunctionAddressType(byteSize)
192209
}
210+
211+
pragma[noinline]
212+
final override int getByteSize() { result = byteSize }
193213
}
194214

195215
/**
@@ -218,6 +238,9 @@ class IROpaqueType extends IRSizedType, TIROpaqueType {
218238
* same size.
219239
*/
220240
final Language::OpaqueTypeTag getTag() { result = tag }
241+
242+
pragma[noinline]
243+
final override int getByteSize() { result = byteSize }
221244
}
222245

223246
module IRTypeSanity {

0 commit comments

Comments
 (0)