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

Side by Side Diff: lib/Transforms/NaCl/PromoteI1Ops.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 unified diff | Download patch
« no previous file with comments | « lib/Transforms/NaCl/PNaClSjLjEH.cpp ('k') | lib/Transforms/NaCl/PromoteIntegers.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- PromoteI1Ops.cpp - Promote various operations on the i1 type--------===//
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 // This pass expands out various operations on the i1 type so that
11 // these i1 operations do not need to be supported by the PNaCl
12 // translator.
13 //
14 // This is similar to the PromoteIntegers pass in that it removes uses
15 // of an unusual-size integer type. The difference is that i1 remains
16 // a valid type in other operations. i1 can still be used in phi
17 // nodes, "select" instructions, in "sext" and "zext", and so on. In
18 // contrast, the integer types that PromoteIntegers removes are not
19 // allowed in any context by PNaCl's ABI verifier.
20 //
21 // This pass expands out the following:
22 //
23 // * i1 loads and stores.
24 // * All i1 comparisons and arithmetic operations, with the exception
25 // of "and", "or" and "xor", because these are used in practice and
26 // don't overflow.
27 //
28 //===----------------------------------------------------------------------===//
29
30 #include "llvm/IR/BasicBlock.h"
31 #include "llvm/IR/Constants.h"
32 #include "llvm/IR/Instructions.h"
33 #include "llvm/Pass.h"
34 #include "llvm/Transforms/NaCl.h"
35
36 using namespace llvm;
37
38 namespace {
39 class PromoteI1Ops : public BasicBlockPass {
40 public:
41 static char ID; // Pass identification, replacement for typeid
42 PromoteI1Ops() : BasicBlockPass(ID) {
43 initializePromoteI1OpsPass(*PassRegistry::getPassRegistry());
44 }
45
46 virtual bool runOnBasicBlock(BasicBlock &BB);
47 };
48 }
49
50 char PromoteI1Ops::ID = 0;
51 INITIALIZE_PASS(PromoteI1Ops, "nacl-promote-i1-ops",
52 "Promote various operations on the i1 type",
53 false, false)
54
55 static Value *promoteValue(Value *Val, bool SignExt, Instruction *InsertPt) {
56 Instruction::CastOps CastType =
57 SignExt ? Instruction::SExt : Instruction::ZExt;
58 return CopyDebug(CastInst::Create(CastType, Val,
59 Type::getInt8Ty(Val->getContext()),
60 Val->getName() + ".expand_i1_val",
61 InsertPt), InsertPt);
62 }
63
64 bool PromoteI1Ops::runOnBasicBlock(BasicBlock &BB) {
65 bool Changed = false;
66
67 Type *I1Ty = Type::getInt1Ty(BB.getContext());
68 Type *I8Ty = Type::getInt8Ty(BB.getContext());
69
70 // Rewrite boolean Switch terminators:
71 if (SwitchInst *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) {
72 Value *Condition = Switch->getCondition();
73 Type *ConditionTy = Condition->getType();
74 if (ConditionTy->isIntegerTy(1)) {
75 ConstantInt *False =
76 cast<ConstantInt>(ConstantInt::getFalse(ConditionTy));
77 ConstantInt *True =
78 cast<ConstantInt>(ConstantInt::getTrue(ConditionTy));
79
80 SwitchInst::CaseIt FalseCase = Switch->findCaseValue(False);
81 SwitchInst::CaseIt TrueCase = Switch->findCaseValue(True);
82
83 BasicBlock *FalseBlock = FalseCase.getCaseSuccessor();
84 BasicBlock *TrueBlock = TrueCase.getCaseSuccessor();
85 BasicBlock *DefaultDest = Switch->getDefaultDest();
86
87 if (TrueBlock && FalseBlock) {
88 // impossible destination
89 DefaultDest->removePredecessor(Switch->getParent());
90 }
91
92 if (!TrueBlock) {
93 TrueBlock = DefaultDest;
94 }
95 if (!FalseBlock) {
96 FalseBlock = DefaultDest;
97 }
98
99 CopyDebug(BranchInst::Create(TrueBlock, FalseBlock, Condition, Switch),
100 Switch);
101 Switch->eraseFromParent();
102 }
103 }
104
105 for (BasicBlock::iterator Iter = BB.begin(), E = BB.end(); Iter != E; ) {
106 Instruction *Inst = Iter++;
107 if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
108 if (Load->getType() == I1Ty) {
109 Changed = true;
110 Value *Ptr = CopyDebug(
111 new BitCastInst(
112 Load->getPointerOperand(), I8Ty->getPointerTo(),
113 Load->getPointerOperand()->getName() + ".i8ptr", Load), Load);
114 LoadInst *NewLoad = new LoadInst(
115 Ptr, Load->getName() + ".pre_trunc", Load);
116 CopyDebug(NewLoad, Load);
117 CopyLoadOrStoreAttrs(NewLoad, Load);
118 Value *Result = CopyDebug(new TruncInst(NewLoad, I1Ty, "", Load), Load);
119 Result->takeName(Load);
120 Load->replaceAllUsesWith(Result);
121 Load->eraseFromParent();
122 }
123 } else if (StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
124 if (Store->getValueOperand()->getType() == I1Ty) {
125 Changed = true;
126 Value *Ptr = CopyDebug(
127 new BitCastInst(
128 Store->getPointerOperand(), I8Ty->getPointerTo(),
129 Store->getPointerOperand()->getName() + ".i8ptr", Store),
130 Store);
131 Value *Val = promoteValue(Store->getValueOperand(), false, Store);
132 StoreInst *NewStore = new StoreInst(Val, Ptr, Store);
133 CopyDebug(NewStore, Store);
134 CopyLoadOrStoreAttrs(NewStore, Store);
135 Store->eraseFromParent();
136 }
137 } else if (BinaryOperator *Op = dyn_cast<BinaryOperator>(Inst)) {
138 if (Op->getType() == I1Ty &&
139 !(Op->getOpcode() == Instruction::And ||
140 Op->getOpcode() == Instruction::Or ||
141 Op->getOpcode() == Instruction::Xor)) {
142 Value *Arg1 = promoteValue(Op->getOperand(0), false, Op);
143 Value *Arg2 = promoteValue(Op->getOperand(1), false, Op);
144 Value *NewOp = CopyDebug(
145 BinaryOperator::Create(
146 Op->getOpcode(), Arg1, Arg2,
147 Op->getName() + ".pre_trunc", Op), Op);
148 Value *Result = CopyDebug(new TruncInst(NewOp, I1Ty, "", Op), Op);
149 Result->takeName(Op);
150 Op->replaceAllUsesWith(Result);
151 Op->eraseFromParent();
152 }
153 } else if (ICmpInst *Op = dyn_cast<ICmpInst>(Inst)) {
154 if (Op->getOperand(0)->getType() == I1Ty) {
155 Value *Arg1 = promoteValue(Op->getOperand(0), Op->isSigned(), Op);
156 Value *Arg2 = promoteValue(Op->getOperand(1), Op->isSigned(), Op);
157 Value *Result = CopyDebug(
158 new ICmpInst(Op, Op->getPredicate(), Arg1, Arg2, ""), Op);
159 Result->takeName(Op);
160 Op->replaceAllUsesWith(Result);
161 Op->eraseFromParent();
162 }
163 }
164 }
165 return Changed;
166 }
167
168 BasicBlockPass *llvm::createPromoteI1OpsPass() {
169 return new PromoteI1Ops();
170 }
OLDNEW
« no previous file with comments | « lib/Transforms/NaCl/PNaClSjLjEH.cpp ('k') | lib/Transforms/NaCl/PromoteIntegers.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698