Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(523)

Unified Diff: lib/Transforms/NaCl/GlobalizeConstantVectors.cpp

Issue 221693002: PNaCl: Add support for GCC/LLVM vector extensions (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Address dschuff's comments. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/Transforms/NaCl/GlobalizeConstantVectors.cpp
diff --git a/lib/Transforms/NaCl/GlobalizeConstantVectors.cpp b/lib/Transforms/NaCl/GlobalizeConstantVectors.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ab9fed1ceb6518efa1cb4542155495169e3f92db
--- /dev/null
+++ b/lib/Transforms/NaCl/GlobalizeConstantVectors.cpp
@@ -0,0 +1,126 @@
+//===- GlobalizeConstantVectors.cpp - Globalize constant vector -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass replaces all constant vector operands by loads of the same
+// vector value from a constant global. After this pass functions don't
+// rely on ConstantVector and ConstantDataVector.
jvoung (off chromium) 2014/04/16 00:10:27 Maybe reference the FlattenGlobals pass too -- It
JF 2014/04/16 20:48:07 Done.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Transforms/NaCl.h"
+
+using namespace llvm;
+
+namespace {
+// Must be a ModulePass since it adds globals.
+class GlobalizeConstantVectors : public ModulePass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ GlobalizeConstantVectors() : ModulePass(ID), DL(0) {
+ initializeGlobalizeConstantVectorsPass(*PassRegistry::getPassRegistry());
+ }
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+ AU.addRequired<DataLayout>();
+ }
+ virtual bool runOnModule(Module &M);
+
+private:
+ typedef SmallVector<Value *, 128> Values;
+ const DataLayout *DL;
+
+ void findConstantVectors(const Function &F, Values &CVs) const;
+ void globalizeConstantVectors(Module &M, Function &F,
+ const Values &CVs) const;
+};
+} // anonymous namespace
+
+char GlobalizeConstantVectors::ID = 0;
+INITIALIZE_PASS(GlobalizeConstantVectors, "globalize-constant-vectors",
+ "Replace constant vector operands with equivalent loads", false,
+ false)
+
+void GlobalizeConstantVectors::findConstantVectors(const Function &F,
+ Values &CVs) const {
+ for (const_inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE;
+ ++II) {
+ for (User::const_op_iterator OI = II->op_begin(), OE = II->op_end();
+ OI != OE; ++OI) {
+ Value *V = OI->get();
+ if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V))
+ CVs.push_back(V);
+ }
+ }
+}
+
+void
+GlobalizeConstantVectors::globalizeConstantVectors(Module &M, Function &F,
+ const Values &CVs) const {
+ // The first instruction in a function dominates all others, it is
+ // therefore a safe insertion point.
+ // TODO(jfb) Sink values closer to their use?
+ Instruction *FirstInst = F.getEntryBlock().getFirstNonPHI();
+ for (Values::const_iterator VI = CVs.begin(), VE = CVs.end(); VI != VE;
+ ++VI) {
+ Value *V = *VI;
+ static const char Name[] = "constant_vector";
+
+ GlobalVariable *GV = new GlobalVariable(
+ M, V->getType(), /* isConstant= */ true, GlobalValue::InternalLinkage,
+ cast<Constant>(V), Name);
+ GV->setAlignment(DL->getPrefTypeAlignment(V->getType()));
+ LoadInst *MaterializedGV = new LoadInst(GV, Name, /* isVolatile= */ false,
+ GV->getAlignment(), FirstInst);
+
+ for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE;
+ ++UI) {
+ User *U = *UI;
+ if (Instruction *I = dyn_cast<Instruction>(U))
+ if (I->getParent()->getParent() != &F)
+ // Skip uses of the constant vector in other functions: we
+ // need to materialize it in every function which has a use.
+ continue;
+ if (isa<GlobalVariable>(U))
+ // Don't replace global uses of the constant vector: we just
+ // created a new one. This avoid recursive references.
+ continue;
+ for (User::op_iterator OI = U->op_begin(), OE = U->op_end(); OI != OE;
+ ++OI)
+ if (dyn_cast<Value>(*OI) == V)
+ // The current operand is a use of the constant vector,
+ // replace it with the materialized one.
+ *OI = MaterializedGV;
+ }
+ }
+}
+
+bool GlobalizeConstantVectors::runOnModule(Module &M) {
+ bool Changed = false;
+ DL = &getAnalysis<DataLayout>();
+ for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
+ Function &F = *FI;
+ Values ConstantVectors;
+ findConstantVectors(F, ConstantVectors);
+ if (!ConstantVectors.empty()) {
+ Changed = true;
+ globalizeConstantVectors(M, F, ConstantVectors);
+ }
+ }
+ return Changed;
+}
+
+ModulePass *llvm::createGlobalizeConstantVectorsPass() {
+ return new GlobalizeConstantVectors();
+}

Powered by Google App Engine
This is Rietveld 408576698