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

Side by Side Diff: lib/Transforms/NaCl/ConstantInsertExtractElementIndex.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: Remove TODOs that were done. 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 unified diff | Download patch
OLDNEW
(Empty)
1 //===- ConstantInsertExtractElementIndex.cpp - Insert/Extract element -----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Transform all InsertElement and ExtractElement with non-constant or
11 // out-of-bounds indices into stack accesses. This moves all undefined
12 // behavior to the stack, making InsertElement and ExtractElement
13 // well-defined.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/IR/Instruction.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/Pass.h"
23 #include "llvm/Transforms/NaCl.h"
24
25 #include <algorithm>
26
27 using namespace llvm;
28
29 namespace {
30 class ConstantInsertExtractElementIndex : public BasicBlockPass {
31 public:
32 static char ID; // Pass identification, replacement for typeid
33 ConstantInsertExtractElementIndex() : BasicBlockPass(ID), M(0), TD(0) {
34 initializeConstantInsertExtractElementIndexPass(
35 *PassRegistry::getPassRegistry());
36 }
37 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
38 AU.addRequired<DataLayout>();
39 BasicBlockPass::getAnalysisUsage(AU);
40 }
41 virtual bool doInitialization(Module &Mod) {
42 M = &Mod;
43 return false; // Unchanged.
44 }
45 virtual bool runOnBasicBlock(BasicBlock &BB);
46
47 private:
48 typedef SmallVector<Instruction *, 8> Instructions;
49 const Module *M;
50 const DataLayout *TD;
jvoung (off chromium) 2014/04/04 23:20:21 I think TargetData was renamed to DataLayout. Some
JF 2014/04/15 01:52:27 Done, in this and other files.
51
52 /// Get the index of an InsertElement or ExtractElement instruction, or null.
53 static Value *getIdx(const Instruction *I);
54
55 void findInvalidInsertExtractElements(const BasicBlock &BB,
jvoung (off chromium) 2014/04/04 23:20:21 nit: It's not actually invalid so "Invalid" should
JF 2014/04/15 01:52:27 Done.
56 Instructions &BadVectorIdx) const;
57 void fixInvalidInsertExtractElements(BasicBlock &BB,
58 const Instructions &BadVectorIdx) const;
59 };
60 }
61
62 char ConstantInsertExtractElementIndex::ID = 0;
63 INITIALIZE_PASS(
64 ConstantInsertExtractElementIndex, "constant-insert-extract-element-index",
65 "Force insert and extract vector elemement to always be in bounds", false,
jvoung (off chromium) 2014/04/04 23:20:21 elemement -> element This doesn't really force th
JF 2014/04/15 01:52:27 Correct. I don't mind doing what you suggest inste
jvoung (off chromium) 2014/04/16 00:10:27 Sure, I'm okay with leaving this as is for now, si
66 false)
67
68 Value *ConstantInsertExtractElementIndex::getIdx(const Instruction *I) {
jvoung (off chromium) 2014/04/04 23:20:21 Could have just been a static function that's not
JF 2014/04/15 01:52:27 Done.
69 switch (I->getOpcode()) {
70 default: return 0;
Jim Stichnoth 2014/04/04 23:08:17 I don't know of a style guide reference, but could
JF 2014/04/15 01:52:27 Done.
71 case Instruction::InsertElement: return I->getOperand(2);
72 case Instruction::ExtractElement: return I->getOperand(1);
73 }
74 }
75
76 void ConstantInsertExtractElementIndex::findInvalidInsertExtractElements(
77 const BasicBlock &BB, Instructions &BadVectorIdx) const {
jvoung (off chromium) 2014/04/04 23:20:21 nit: BadVectorIdx sounds like it's a single index,
JF 2014/04/15 01:52:27 Done.
78 for (BasicBlock::const_iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE;
79 ++BBI) {
80 const Instruction *I = &*BBI;
81 Value *Idx = getIdx(I);
82 if (!Idx)
83 // Not and InsertElement or ExtractElement, ignore the instruction.
Jim Stichnoth 2014/04/04 23:08:17 and --> an
JF 2014/04/15 01:52:27 Done.
84 continue;
85 if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx)) {
86 unsigned NumElements =
87 cast<VectorType>(I->getOperand(0)->getType())->getNumElements();
88 if (CI->getValue().ult(NumElements))
89 // Index is constant in-range for the vector type, keep as-is.
90 continue;
91 }
92 BadVectorIdx.push_back(const_cast<Instruction *>(I));
Jim Stichnoth 2014/04/04 23:08:17 I trust const_cast is actually necessary :(
JF 2014/04/15 01:52:27 Yeah, I wanted to go all const-correctness, but so
93 }
94 }
95
96 void ConstantInsertExtractElementIndex::fixInvalidInsertExtractElements(
97 BasicBlock &BB, const Instructions &BadVectorIdx) const {
98 for (Instructions::const_iterator IB = BadVectorIdx.begin(),
99 IE = BadVectorIdx.end();
100 IB != IE; ++IB) {
101 Instruction *I = *IB;
102 Value *Vec = I->getOperand(0);
103 Value *Idx = getIdx(I);
104 VectorType *VecTy = cast<VectorType>(Vec->getType());
105 Type *ElemTy = VecTy->getElementType();
106 unsigned ElemAlign = TD->getPrefTypeAlignment(ElemTy);
107 unsigned VecAlign = std::max(ElemAlign, TD->getPrefTypeAlignment(VecTy));
108
109 IRBuilder<> IRB(I);
110 AllocaInst *Alloca = IRB.CreateAlloca(
111 ElemTy, ConstantInt::get(Type::getInt32Ty(M->getContext()),
jvoung (off chromium) 2014/04/04 23:20:21 Instead of ElemTy, have the alloca be i8, and mult
jvoung (off chromium) 2014/04/07 15:40:11 n/m about this point -- it'll be handled by the Re
JF 2014/04/15 01:52:27 Yeah I wanted to do the "right" thing for LLVM, an
112 VecTy->getNumElements()));
113 Alloca->setAlignment(VecAlign);
114 Value *AllocaAsVec = IRB.CreateBitCast(Alloca, VecTy->getPointerTo());
115 IRB.CreateAlignedStore(Vec, AllocaAsVec, Alloca->getAlignment());
116 Value *GEP = IRB.CreateGEP(Alloca, Idx);
117
118 Value *Res;
119 switch (I->getOpcode()) {
120 default:
121 llvm_unreachable("expected InsertElement or ExtractElement");
122 case Instruction::InsertElement: {
123 IRB.CreateAlignedStore(I->getOperand(1), GEP, ElemAlign);
124 Res = IRB.CreateAlignedLoad(AllocaAsVec, Alloca->getAlignment());
125 break;
126 }
127 case Instruction::ExtractElement: {
128 Res = IRB.CreateAlignedLoad(GEP, ElemAlign);
129 break;
130 }
131 }
Jim Stichnoth 2014/04/04 23:08:17 Sorry, these two perfectly aligned braces really b
JF 2014/04/15 01:52:27 Done, though if they *had* been required I'd have
132
133 I->replaceAllUsesWith(Res);
jvoung (off chromium) 2014/04/04 23:20:21 CopyDebug?
JF 2014/04/15 01:52:27 I was going to fix IRBuilder instead so it copies
134 I->eraseFromParent();
135 }
136 }
137
138 bool ConstantInsertExtractElementIndex::runOnBasicBlock(BasicBlock &BB) {
139 bool Changed = false;
140 if (!TD)
141 TD = &getAnalysis<DataLayout>();
142 Instructions BadVectorIdx;
143 findInvalidInsertExtractElements(BB, BadVectorIdx);
144 if (!BadVectorIdx.empty()) {
145 Changed = true;
146 fixInvalidInsertExtractElements(BB, BadVectorIdx);
147 }
148 return Changed;
149 }
150
151 BasicBlockPass *llvm::createConstantInsertExtractElementIndexPass() {
152 return new ConstantInsertExtractElementIndex();
153 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698