Update the pass manager to allow for function creation in function passes.

Add interfaces and update the pass execution logic to allow function
passes to create new functions, or ask for functions to be optimized
prior to continuing.

Doing so results in the pass pipeline halting execution on the current
function, and continuing with newly added functions, returning to the
previous function after the newly added functions are fully optimized.
This commit is contained in:
Mark Lacey
2015-12-17 15:15:58 -08:00
parent b70af8ae08
commit dbde7cc4c1
3 changed files with 41 additions and 3 deletions

View File

@@ -22,6 +22,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "swift/SILOptimizer/Analysis/FunctionOrder.h"
#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/TimeValue.h"
@@ -206,6 +207,10 @@ void SILPassManager::runPassesOnFunction(PassList FuncTransforms,
SFT->run();
Mod->removeDeleteNotificationHandler(SFT);
// Did running the transform result in new functions being added
// to the top of our worklist?
bool newFunctionsAdded = (F != FunctionWorklist.back());
if (SILPrintPassTime) {
auto Delta =
llvm::sys::TimeValue::now().nanoseconds() - StartTime.nanoseconds();
@@ -232,7 +237,11 @@ void SILPassManager::runPassesOnFunction(PassList FuncTransforms,
}
++NumPassesRun;
if (!continueTransforming())
// If running the transform resulted in new functions on the top
// of the worklist, we'll return so that we can begin processing
// those new functions.
if (newFunctionsAdded || !continueTransforming())
return;
}
}
@@ -255,6 +264,11 @@ void SILPassManager::runFunctionPasses(PassList FuncTransforms) {
FunctionWorklist.push_back(*I);
}
// Used to track how many times a given function has been
// (partially) optimized by the function pass pipeline in this
// invocation.
llvm::DenseMap<SILFunction *, unsigned int> CountOptimized;
// Pop functions off the worklist, and run all function transforms
// on each of them.
while (!FunctionWorklist.empty()) {
@@ -262,7 +276,19 @@ void SILPassManager::runFunctionPasses(PassList FuncTransforms) {
runPassesOnFunction(FuncTransforms, F);
FunctionWorklist.pop_back();
++CountOptimized[F];
// We currently have no function passes that generate new
// functions, so confirm that we only optimize a given function
// once.
assert(CountOptimized[F] == 1 && "Expected function to be optimized once!");
// If running the function transforms did not result in new
// functions being added to the top of the worklist, then we're
// done with this function and can pop it off and
// continue. Otherwise, we'll return to this function and
// reoptimize after processing the new function that were added.
if (F == FunctionWorklist.back())
FunctionWorklist.pop_back();
}
}