summaryrefslogtreecommitdiff
path: root/src/mir/optimise.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2017-01-28 15:36:58 +1100
committerJohn Hodge <tpg@mutabah.net>2017-01-28 15:36:58 +1100
commitc1ee5a0967fd3d79cd30765ff5a03592e544b537 (patch)
tree5207dcbee7c74bce63e22c4b67f63ecbf3b53309 /src/mir/optimise.cpp
parentf6265741bc8f97c7b2a54de0ed366cd19c655481 (diff)
downloadmrust-c1ee5a0967fd3d79cd30765ff5a03592e544b537.tar.gz
MIR Optimise - Run cleanup after inlining (as it triggers monomorph)
Diffstat (limited to 'src/mir/optimise.cpp')
-rw-r--r--src/mir/optimise.cpp72
1 files changed, 46 insertions, 26 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index a4b1d553..645b1bfb 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -328,6 +328,7 @@ namespace {
}
}
+bool MIR_Optimise_BlockSimplify(::MIR::TypeResolve& state, ::MIR::Function& fcn);
bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn);
bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::Function& fcn);
bool MIR_Optimise_UnifyTemporaries(::MIR::TypeResolve& state, ::MIR::Function& fcn);
@@ -340,6 +341,49 @@ void MIR_Optimise(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
TRACE_FUNCTION_F(path);
::MIR::TypeResolve state { sp, resolve, FMT_CB(ss, ss << path;), ret_type, args, fcn };
+
+ bool change_happened;
+ do
+ {
+ change_happened = false;
+
+ // >> Simplify call graph
+ MIR_Optimise_BlockSimplify(state, fcn);
+
+ // >> Inline short functions
+ bool inline_happened = MIR_Optimise_Inlining(state, fcn);
+ if( inline_happened )
+ {
+ // Apply cleanup again (as monomorpisation in inlining may have exposed a vtable call)
+ MIR_Cleanup(resolve, path, fcn, args, ret_type);
+ change_happened = true;
+ }
+
+ // >> Propagate dead assignments
+ while( MIR_Optimise_PropagateSingleAssignments(state, fcn) )
+ ;
+
+ // >> Unify duplicate temporaries
+ // If two temporaries don't overlap in lifetime (blocks in which they're valid), unify the two
+ change_happened |= MIR_Optimise_UnifyTemporaries(state, fcn) || change_happened;
+
+ // >> Combine Duplicate Blocks
+ change_happened |= MIR_Optimise_UnifyBlocks(state, fcn) || change_happened;
+ } while( change_happened );
+
+
+ // DEFENCE: Run validation _before_ GC (so validation errors refer to the pre-gc numbers)
+ MIR_Validate(resolve, path, fcn, args, ret_type);
+ // GC pass on blocks and variables
+ // - Find unused blocks, then delete and rewrite all references.
+ MIR_Optimise_GarbageCollect(state, fcn);
+}
+
+// --------------------------------------------------------------------
+// Performs basic simplications on the call graph (merging/removing blocks)
+// --------------------------------------------------------------------
+bool MIR_Optimise_BlockSimplify(::MIR::TypeResolve& state, ::MIR::Function& fcn)
+{
// >> Replace targets that point to a block that is just a goto
for(auto& block : fcn.blocks)
{
@@ -424,32 +468,8 @@ void MIR_Optimise(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
}
}
- bool change_happened;
- do
- {
- change_happened = false;
-
- // >> Inline short functions
- change_happened |= MIR_Optimise_Inlining(state, fcn);
-
- // >> Propagate dead assignments
- while( MIR_Optimise_PropagateSingleAssignments(state, fcn) )
- ;
-
- // >> Unify duplicate temporaries
- // If two temporaries don't overlap in lifetime (blocks in which they're valid), unify the two
- change_happened = MIR_Optimise_UnifyTemporaries(state, fcn) || change_happened;
-
- // >> Combine Duplicate Blocks
- change_happened = MIR_Optimise_UnifyBlocks(state, fcn) || change_happened;
- } while( change_happened );
-
-
- // DEFENCE: Run validation _before_ GC (so validation errors refer to the pre-gc numbers)
- MIR_Validate(resolve, path, fcn, args, ret_type);
- // GC pass on blocks and variables
- // - Find unused blocks, then delete and rewrite all references.
- MIR_Optimise_GarbageCollect(state, fcn);
+ // NOTE: Not strictly true, but these can't trigger other optimisations
+ return false;
}