aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-09-11 16:45:55 +0000
committerChris Lattner <sabre@nondot.org>2003-09-11 16:45:55 +0000
commit38aec325604635380421a27e39ab06d55ed2458d (patch)
tree207cb17b79d4fd46084656a4319a6ee0841d58e8 /lib
parent473205250de3289cda13b18e31c3f2fceb6e2e6a (diff)
downloadexternal_llvm-38aec325604635380421a27e39ab06d55ed2458d.zip
external_llvm-38aec325604635380421a27e39ab06d55ed2458d.tar.gz
external_llvm-38aec325604635380421a27e39ab06d55ed2458d.tar.bz2
Integrate functionality of the mem2reg pass directly into this pass to make
the combination more effective git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8471 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp69
1 files changed, 62 insertions, 7 deletions
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 864f876..d2a098c 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -3,29 +3,43 @@
// This transformation implements the well known scalar replacement of
// aggregates transformation. This xform breaks up alloca instructions of
// aggregate type (structure or array) into individual alloca instructions for
-// each member (if possible).
+// each member (if possible). Then, if possible, it transforms the individual
+// alloca instructions into nice clean scalar SSA form.
+//
+// This combines a simple SRoA algorithm with the Mem2Reg algorithm because
+// often interact, especially for C++ programs. As such, iterating between
+// SRoA, then Mem2Reg until we run out of things to promote works well.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Pass.h"
#include "llvm/iMemory.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Constants.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "Support/Debug.h"
#include "Support/Statistic.h"
#include "Support/StringExtras.h"
namespace {
Statistic<> NumReplaced("scalarrepl", "Number of alloca's broken up");
+ Statistic<> NumPromoted("scalarrepl", "Number of alloca's promoted");
struct SROA : public FunctionPass {
bool runOnFunction(Function &F);
+ bool performScalarRepl(Function &F);
+ bool performPromotion(Function &F);
+
// getAnalysisUsage - This pass does not require any passes, but we know it
// will not alter the CFG, so say so.
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<DominanceFrontier>();
+ AU.addRequired<TargetData>();
AU.setPreservesCFG();
}
@@ -43,11 +57,52 @@ namespace {
Pass *createScalarReplAggregatesPass() { return new SROA(); }
-// runOnFunction - This algorithm is a simple worklist driven algorithm, which
-// runs on all of the malloc/alloca instructions in the function, removing them
-// if they are only used by getelementptr instructions.
-//
bool SROA::runOnFunction(Function &F) {
+ bool Changed = false, LocalChange;
+ do {
+ LocalChange = performScalarRepl(F);
+ LocalChange |= performPromotion(F);
+ Changed |= LocalChange;
+ } while (LocalChange);
+
+ return Changed;
+}
+
+
+bool SROA::performPromotion(Function &F) {
+ std::vector<AllocaInst*> Allocas;
+ const TargetData &TD = getAnalysis<TargetData>();
+
+ BasicBlock &BB = F.getEntryNode(); // Get the entry node for the function
+
+ bool Changed = false;
+
+ while (1) {
+ Allocas.clear();
+
+ // Find allocas that are safe to promote, by looking at all instructions in
+ // the entry node
+ for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?
+ if (isAllocaPromotable(AI, TD))
+ Allocas.push_back(AI);
+
+ if (Allocas.empty()) break;
+
+ PromoteMemToReg(Allocas, getAnalysis<DominanceFrontier>(), TD);
+ NumPromoted += Allocas.size();
+ Changed = true;
+ }
+
+ return Changed;
+}
+
+
+// performScalarRepl - This algorithm is a simple worklist driven algorithm,
+// which runs on all of the malloc/alloca instructions in the function, removing
+// them if they are only used by getelementptr instructions.
+//
+bool SROA::performScalarRepl(Function &F) {
std::vector<AllocationInst*> WorkList;
// Scan the entry basic block, adding any alloca's and mallocs to the worklist