Last active
April 5, 2022 23:51
-
-
Save kripken/d592f5882eca40f255881cf070204adb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 972d6299672f4508c805af5efd886bb87b0a22fe | |
Author: Alon Zakai <[email protected]> | |
Date: Tue Apr 5 16:50:33 2022 -0700 | |
wip | |
diff --git a/src/passes/ConstantFieldPropagation.cpp b/src/passes/ConstantFieldPropagation.cpp | |
index e4e01dc0e..76f64535c 100644 | |
--- a/src/passes/ConstantFieldPropagation.cpp | |
+++ b/src/passes/ConstantFieldPropagation.cpp | |
@@ -53,9 +53,13 @@ using PCVFunctionStructValuesMap = | |
struct FunctionOptimizer : public WalkerPass<PostWalker<FunctionOptimizer>> { | |
bool isFunctionParallel() override { return true; } | |
- Pass* create() override { return new FunctionOptimizer(infos); } | |
+ Pass* create() override { | |
+ return new FunctionOptimizer(exactInfos, generalInfos); | |
+ } | |
- FunctionOptimizer(PCVStructValuesMap& infos) : infos(infos) {} | |
+ FunctionOptimizer(PCVStructValuesMap& exactInfos, | |
+ PCVStructValuesMap& generalInfos) | |
+ : infos(infos), generalInfos(generalInfos) {} | |
void visitStructGet(StructGet* curr) { | |
auto type = curr->ref->type; | |
@@ -70,6 +74,11 @@ struct FunctionOptimizer : public WalkerPass<PostWalker<FunctionOptimizer>> { | |
// as if nothing was ever noted for that field. | |
PossibleConstantValues info; | |
assert(!info.hasNoted()); | |
+ | |
+ // If the type is exact, use the exact info. | |
+ auto& infos = | |
+ Oracle::isTypeExact(curr->ref->type) ? exactInfos : generalInfos; | |
+ | |
auto iter = infos.find(type.getHeapType()); | |
if (iter != infos.end()) { | |
// There is information on this type, fetch it. | |
@@ -117,7 +126,8 @@ struct FunctionOptimizer : public WalkerPass<PostWalker<FunctionOptimizer>> { | |
} | |
private: | |
- PCVStructValuesMap& infos; | |
+ PCVStructValuesMap& exactInfos; | |
+ PCVStructValuesMap& generalInfos; | |
bool changed = false; | |
}; | |
@@ -227,17 +237,32 @@ struct ConstantFieldPropagation : public Pass { | |
StructUtils::TypeHierarchyPropagator<PossibleConstantValues> propagator( | |
*module); | |
- propagator.propagateToSuperTypes(combinedNewInfos); | |
- propagator.propagateToSuperAndSubTypes(combinedSetInfos); | |
- // Combine both sources of information to the final information that gets | |
- // care about. | |
- PCVStructValuesMap combinedInfos = std::move(combinedNewInfos); | |
- combinedSetInfos.combineInto(combinedInfos); | |
+ // As explained above, in the general case we want to propagate info both | |
+ // ways on sets and one way on news. | |
+ auto generalNewInfos = combinedNewInfos; | |
+ propagator.propagateToSuperTypes(generalNewInfos); | |
+ auto generalSetInfos = combinedSetInfos; | |
+ propagator.propagateToSuperAndSubTypes(generalSetInfos); | |
+ auto generalInfos = generalNewInfos; | |
+ generalSetInfos.mergeInfo(generalInfos); | |
+ | |
+ // The case of exact type info on the get is more optimizable than the | |
+ // above. Considering the get versus a new, we now have precise info on both | |
+ // and so we do not need to propagate at all. And considering the get | |
+ // versus a set, assuming we do not know whether we are exact at the set | |
+ // (to do that we'd need to modify the code that gathers that info, to make | |
+ // it store in the same place it stores for a struct.new), the only sets | |
+ // relevant are sets that have a subtype that includes the exact type on the | |
+ // get. | |
+ auto exactSetInfos = combinedSetInfos; | |
+ propagator.propagateToSubTypes(exactSetInfos); | |
+ auto exactInfos = exactNewInfos; | |
+ exactSetInfos.mergeInfo(exactInfos); | |
// Optimize. | |
// TODO: Skip this if we cannot optimize anything | |
- FunctionOptimizer(combinedInfos).run(runner, module); | |
+ FunctionOptimizer(exactInfos, generalInfos).run(runner, module); | |
// TODO: Actually remove the field from the type, where possible? That might | |
// be best in another pass. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment