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

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

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 10 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
« no previous file with comments | « lib/Transforms/NaCl/ExpandCtors.cpp ('k') | lib/Transforms/NaCl/ExpandIndirectBr.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Transforms/NaCl/ExpandGetElementPtr.cpp
diff --git a/lib/Transforms/NaCl/ExpandGetElementPtr.cpp b/lib/Transforms/NaCl/ExpandGetElementPtr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0718b6e429b997b6097a1e17b616781d1a912b39
--- /dev/null
+++ b/lib/Transforms/NaCl/ExpandGetElementPtr.cpp
@@ -0,0 +1,151 @@
+//===- ExpandGetElementPtr.cpp - Expand GetElementPtr into arithmetic------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass expands out GetElementPtr instructions into ptrtoint,
+// inttoptr and arithmetic instructions.
+//
+// This simplifies the language so that the PNaCl translator does not
+// need to handle GetElementPtr and struct types as part of a stable
+// wire format for PNaCl.
+//
+// Note that we drop the "inbounds" attribute of GetElementPtr.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/NaCl.h"
+
+using namespace llvm;
+
+namespace {
+ class ExpandGetElementPtr : public BasicBlockPass {
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ ExpandGetElementPtr() : BasicBlockPass(ID) {
+ initializeExpandGetElementPtrPass(*PassRegistry::getPassRegistry());
+ }
+
+ virtual bool runOnBasicBlock(BasicBlock &BB);
+ };
+}
+
+char ExpandGetElementPtr::ID = 0;
+INITIALIZE_PASS(ExpandGetElementPtr, "expand-getelementptr",
+ "Expand out GetElementPtr instructions into arithmetic",
+ false, false)
+
+static Value *CastToPtrSize(Value *Val, Instruction *InsertPt,
+ const DebugLoc &Debug, Type *PtrType) {
+ unsigned ValSize = Val->getType()->getIntegerBitWidth();
+ unsigned PtrSize = PtrType->getIntegerBitWidth();
+ if (ValSize == PtrSize)
+ return Val;
+ Instruction *Inst;
+ if (ValSize > PtrSize) {
+ Inst = new TruncInst(Val, PtrType, "gep_trunc", InsertPt);
+ } else {
+ // GEP indexes must be sign-extended.
+ Inst = new SExtInst(Val, PtrType, "gep_sext", InsertPt);
+ }
+ Inst->setDebugLoc(Debug);
+ return Inst;
+}
+
+static void FlushOffset(Instruction **Ptr, uint64_t *CurrentOffset,
+ Instruction *InsertPt, const DebugLoc &Debug,
+ Type *PtrType) {
+ if (*CurrentOffset) {
+ *Ptr = BinaryOperator::Create(Instruction::Add, *Ptr,
+ ConstantInt::get(PtrType, *CurrentOffset),
+ "gep", InsertPt);
+ (*Ptr)->setDebugLoc(Debug);
+ *CurrentOffset = 0;
+ }
+}
+
+static void ExpandGEP(GetElementPtrInst *GEP, DataLayout *DL, Type *PtrType) {
+ const DebugLoc &Debug = GEP->getDebugLoc();
+ Instruction *Ptr = new PtrToIntInst(GEP->getPointerOperand(), PtrType,
+ "gep_int", GEP);
+ Ptr->setDebugLoc(Debug);
+
+ Type *CurrentTy = GEP->getPointerOperand()->getType();
+ // We do some limited constant folding ourselves. An alternative
+ // would be to generate verbose, unfolded output (e.g. multiple
+ // adds; adds of zero constants) and use a later pass such as
+ // "-instcombine" to clean that up. However, "-instcombine" can
+ // reintroduce GetElementPtr instructions.
+ uint64_t CurrentOffset = 0;
+
+ for (GetElementPtrInst::op_iterator Op = GEP->op_begin() + 1;
+ Op != GEP->op_end();
+ ++Op) {
+ Value *Index = *Op;
+ if (StructType *StTy = dyn_cast<StructType>(CurrentTy)) {
+ uint64_t Field = cast<ConstantInt>(Op)->getZExtValue();
+ CurrentTy = StTy->getElementType(Field);
+ CurrentOffset += DL->getStructLayout(StTy)->getElementOffset(Field);
+ } else {
+ CurrentTy = cast<SequentialType>(CurrentTy)->getElementType();
+ uint64_t ElementSize = DL->getTypeAllocSize(CurrentTy);
+ if (ConstantInt *C = dyn_cast<ConstantInt>(Index)) {
+ CurrentOffset += C->getSExtValue() * ElementSize;
+ } else {
+ FlushOffset(&Ptr, &CurrentOffset, GEP, Debug, PtrType);
+ Index = CastToPtrSize(Index, GEP, Debug, PtrType);
+ if (ElementSize != 1) {
+ Index = CopyDebug(
+ BinaryOperator::Create(Instruction::Mul, Index,
+ ConstantInt::get(PtrType, ElementSize),
+ "gep_array", GEP),
+ GEP);
+ }
+ Ptr = BinaryOperator::Create(Instruction::Add, Ptr,
+ Index, "gep", GEP);
+ Ptr->setDebugLoc(Debug);
+ }
+ }
+ }
+ FlushOffset(&Ptr, &CurrentOffset, GEP, Debug, PtrType);
+
+ assert(CurrentTy == GEP->getType()->getElementType());
+ Instruction *Result = new IntToPtrInst(Ptr, GEP->getType(), "", GEP);
+ Result->setDebugLoc(Debug);
+ Result->takeName(GEP);
+ GEP->replaceAllUsesWith(Result);
+ GEP->eraseFromParent();
+}
+
+bool ExpandGetElementPtr::runOnBasicBlock(BasicBlock &BB) {
+ bool Modified = false;
+ DataLayout DL(BB.getParent()->getParent());
+ Type *PtrType = DL.getIntPtrType(BB.getContext());
+
+ for (BasicBlock::InstListType::iterator Iter = BB.begin();
+ Iter != BB.end(); ) {
+ Instruction *Inst = Iter++;
+ if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
+ Modified = true;
+ ExpandGEP(GEP, &DL, PtrType);
+ }
+ }
+ return Modified;
+}
+
+BasicBlockPass *llvm::createExpandGetElementPtrPass() {
+ return new ExpandGetElementPtr();
+}
« no previous file with comments | « lib/Transforms/NaCl/ExpandCtors.cpp ('k') | lib/Transforms/NaCl/ExpandIndirectBr.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698