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

Side by Side Diff: lib/Transforms/NaCl/PromoteIntegers.cpp

Issue 14569012: PNaCl ABI: Promote illegal integer types (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: use upper-clear invariant rather than sign-extend Created 7 years, 7 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 //===- PromoteIntegers.cpp - ---------------------------------------------===//
Mark Seaborn 2013/05/06 17:04:06 Add a short description here?
eliben 2013/05/06 21:58:40 IMHO the name "PromoteIntegers" is a bit too gener
Derek Schuff 2013/05/08 22:33:28 Done.
Derek Schuff 2013/05/08 22:33:28 I LegalizeIntegersForPNaCl is even more generic; t
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 // A limited set of transformations to promote illegal-sized int types.
eliben 2013/05/06 21:58:40 Beef up this comment with a more detailed descript
Derek Schuff 2013/05/08 22:33:28 Done.
9 // It always maintains the invariant that the upper bits (above the size of the
10 // original type) are zero.
11 //
12 //===----------------------------------------------------------------------===//
13 //
Mark Seaborn 2013/05/06 17:04:06 Add a longer description here
Derek Schuff 2013/05/08 22:33:28 Done.
14
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/IR/DerivedTypes.h"
18 #include "llvm/IR/Function.h"
19 #include "llvm/IR/Instructions.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/Pass.h"
22 #include "llvm/Support/raw_ostream.h"
23
24 using namespace llvm;
25 namespace {
26 class PromoteIntegers : public FunctionPass {
27 public:
28 static char ID;
29 PromoteIntegers() : FunctionPass(ID) {
30 initializePromoteIntegersPass(*PassRegistry::getPassRegistry());
31 }
32 virtual bool runOnFunction(Function &F);
33 };
34 }
35
36 char PromoteIntegers::ID = 0;
37 INITIALIZE_PASS(PromoteIntegers, "nacl-promote-ints",
38 "Promote integer types which are illegal in PNaCl",
39 false, false);
40
41
42 // Legal sizes are currently 1, 8, 16, 32, 64
43 // We can't yet expand types above 64 bit, so don't try to touch them for now.
44 static bool isLegalSize(unsigned Size) {
Mark Seaborn 2013/05/06 17:04:06 Nit: as a static function (not a method), should t
Derek Schuff 2013/05/08 22:33:28 I don't think LLVM style distinguishes between sta
Mark Seaborn 2013/05/09 01:00:22 http://llvm.org/docs/CodingStandards.html matches
45 // TODO(dschuff): expand >64bit types or disallow >64bit packed bitfields
46 if (Size > 64) return true;
47 assert(Size <= 64 && "Don't know how to expand > 64bit types yet");
Mark Seaborn 2013/05/06 17:04:06 This assert is redundant given the check above
Derek Schuff 2013/05/08 22:33:28 Done.
48 return isPowerOf2_32(Size) && !(Size & 0x6);
Mark Seaborn 2013/05/06 17:04:06 It might be simpler just to list 1, 8, 16, 32, 64
eliben 2013/05/06 21:58:40 I agree
Derek Schuff 2013/05/08 22:33:28 Done.
49 }
50
51 // Return a legal integer or pointer-to-integer type, promoting to a larger
52 // size if necessary.
53 static Type *convertType(Type *Ty) {
eliben 2013/05/06 21:58:40 PromoteIntegerType? In general, pick one verb cons
Derek Schuff 2013/05/08 22:33:28 They are basically the same in this context. I ren
54 assert((isa<IntegerType>(Ty) || isa<PointerType>(Ty)) &&
55 "Trying to convert a non-integer type");
56 IntegerType *ITy;
57 if (isa<PointerType>(Ty))
eliben 2013/05/06 21:58:40 Why are you handling pointers at all? I thought we
Derek Schuff 2013/05/08 22:33:28 The general strategy with these passes has been to
58 ITy = dyn_cast<IntegerType>(Ty->getContainedType(0));
59 else
60 ITy = dyn_cast<IntegerType>(Ty);
61
62 unsigned Width = ITy->getBitWidth();
63 assert(Width <= 64 && "Don't know how to legalize >64 bit types yet");
64 if (isLegalSize(Width))
65 return Ty;
66 ITy = IntegerType::get(Ty->getContext(), NextPowerOf2(Width));
67
68 if (isa<PointerType>(Ty))
69 return ITy->getPointerTo();
70 return ITy;
71 }
72
73 // Return true if Val is an int or pointer-to-int which should be converted.
74 static bool shouldConvert(Value *Val) {
75 Type *Ty = Val->getType();
76 if (PointerType *Pty = dyn_cast<PointerType>(Ty))
77 Ty = Pty->getContainedType(0);
78 if (IntegerType *ITy = dyn_cast<IntegerType>(Ty)) {
79 if (!isLegalSize(ITy->getBitWidth())) {
80 return true;
81 }
82 }
83 return false;
84 }
85
86 // Return a constant which has been promoted to a legal size.
87 static Value *convertConstant(Constant *C, bool SignExt=false) {
88 assert(shouldConvert(C));
89 ConstantInt *CInt = cast<ConstantInt>(C);
90 return ConstantInt::get(
91 convertType(cast<IntegerType>(CInt->getType())),
92 SignExt ? CInt->getSExtValue() : CInt->getZExtValue(),
93 /*isSigned=*/SignExt);
94 }
95
96 class ConversionState {
eliben 2013/05/06 21:58:40 Document what this class does and what each of its
Derek Schuff 2013/05/08 22:48:32 Done.
97 public:
98 // Return the promoted value for Val. If val has not yet been converted,
eliben 2013/05/06 21:58:40 s/val/Val/ Also, you may want to follow the LLVM
Derek Schuff 2013/05/08 22:33:28 do you mean just use doxygen? (i did add doxy comm
eliben 2013/05/09 16:42:19 Yeah, like \p Val for arguments, etc.
99 // return a placeholder, which will be converted later.
100 Value *getConverted(Value *Val) {
101 if (!shouldConvert(Val))
102 return Val;
103 assert(!isa<GlobalVariable>(Val) && "Can't convert GlobalVariables");
104 if (RewrittenMap.count(Val))
105 return RewrittenMap[Val];
106 Value *P;
107 // Directly convert constants.
108 if (Constant *C = dyn_cast<Constant>(Val))
109 P = convertConstant(C, /*SignExt=*/false);
Mark Seaborn 2013/05/06 17:04:06 This shouldn't be inserted into Placeholders, sure
Derek Schuff 2013/05/08 22:33:28 Done.
110 else
Mark Seaborn 2013/05/06 17:04:06 Maybe use {}s since using 'else' (not sure if styl
Derek Schuff 2013/05/08 22:33:28 It doesn't, and I've seen it this way in LLVM, but
111 // No converted value available yet, so create a placeholder.
112 P = new Argument(convertType(Val->getType()));
eliben 2013/05/06 21:58:40 Why doesn't it have a parent?
Derek Schuff 2013/05/08 22:33:28 you mean, the Argument used as a placeholder? It d
eliben 2013/05/09 16:42:19 I mean in terms of memory management. It's not imm
113 RewrittenMap[Val] = P;
114 Placeholders[Val] = P;
115 return P;
116 }
117
118 // Replace the uses of From with To, replace the uses of any
119 // placeholders for From, and optionally give From's name to To.
120 // Also mark To for deletion.
121 void recordConverted(Value *From, Value *To, bool TakeName=true) {
Mark Seaborn 2013/05/06 17:04:06 Use "Instruction *From" since that's what the func
Derek Schuff 2013/05/08 22:33:28 Done.
122 ToErase.push_back(cast<Instruction>(From));
123 if (!shouldConvert(From)) {
124 From->replaceAllUsesWith(To);
125 } else {
126 if (Placeholders.count(From)) {
127 // Resolve placeholders.
128 Placeholders[From]->replaceAllUsesWith(To);
129 Placeholders.erase(From);
130 }
131 RewrittenMap[From] = To;
132 }
133 if (TakeName) {
134 To->takeName(From);
135 }
136 }
137 ~ConversionState() {
138 for (SmallVectorImpl<Instruction*>::iterator I = ToErase.begin(),
139 E = ToErase.end(); I != E; ++I)
140 (*I)->dropAllReferences();
141 for (SmallVectorImpl<Instruction*>::iterator I = ToErase.begin(),
142 E = ToErase.end(); I != E; ++I)
143 (*I)->eraseFromParent();
144 }
145 private:
146 DenseMap<Value *, Value *> RewrittenMap;
147 DenseMap<Value *, Value *> Placeholders;
148 SmallVector<Instruction*, 8> ToErase;
149 };
150
151 // Split an illegal load into multiple legal loads and return the resulting
152 // promoted value. The size of the load is assumed to be a multiple of 8.
153 static Value *splitLoad(LoadInst *Inst, ConversionState &State) {
154 assert(!Inst->isVolatile() && !Inst->isAtomic() &&
eliben 2013/05/06 21:58:40 Do we disallow/hide volatile loads for PNaCl?
Derek Schuff 2013/05/08 22:33:28 I'm not sure we've converged on that yet. but cert
155 "Can't split volatile/atomic loads");
156 assert(cast<IntegerType>(Inst->getType())->getBitWidth() % 8 == 0);
157
158 Value *OrigPtr = State.getConverted(Inst->getPointerOperand());
159 // OrigPtr is a placeholder in recursive calls, and so has no name
160 if (OrigPtr->getName().empty())
161 OrigPtr->setName(Inst->getPointerOperand()->getName());
162 unsigned Width = cast<IntegerType>(Inst->getType())->getBitWidth();
163 Type *NewType = convertType(Inst->getType());
164 unsigned LoWidth = Width;
165
166 while (!isLegalSize(LoWidth)) LoWidth -= 8;
167 IntegerType *LoType = IntegerType::get(Inst->getContext(), LoWidth);
168 IntegerType *HiType = IntegerType::get(Inst->getContext(), Width - LoWidth);
169 IRBuilder<> IRB(Inst->getParent(), Inst);
170
171 Value *BCLo = IRB.CreateBitCast(
172 OrigPtr,
173 LoType->getPointerTo(),
174 OrigPtr->getName() + ".loty");
175 Value *LoadLo = IRB.CreateAlignedLoad(
176 BCLo, Inst->getAlignment(), Inst->getName() + ".lo");
177 Value *LoExt = IRB.CreateZExt(LoadLo, NewType, LoadLo->getName() + ".ext");
178 Value *GEPHi = IRB.CreateConstGEP1_32(BCLo, 1, OrigPtr->getName() + ".hi");
179 Value *BCHi = IRB.CreateBitCast(
180 GEPHi,
181 HiType->getPointerTo(),
182 OrigPtr->getName() + ".hity");
183
184 Value *LoadHi = IRB.CreateLoad(BCHi, Inst->getName() + ".hi");
185 if (!isLegalSize(Width - LoWidth)) {
186 LoadHi = splitLoad(cast<LoadInst>(LoadHi), State);
187 // BCHi was still illegal, and has been replaced with a placeholder in the
188 // recursive call. Since it is redundant with BCLo in the recursive call,
189 // just splice it out entirely.
190 State.recordConverted(BCHi, GEPHi, /*TakeName=*/false);
191 }
192
193 Value *HiExt = IRB.CreateZExt(LoadHi, NewType, LoadHi->getName() + ".ext");
194 Value *HiShift = IRB.CreateShl(HiExt, LoWidth, HiExt->getName() + ".sh");
195 Value *Result = IRB.CreateOr(LoExt, HiShift);
196
197 State.recordConverted(Inst, Result);
198
199 return Result;
200 }
201
202 static Value *splitStore(StoreInst *Inst, ConversionState &State) {
203 assert(!Inst->isVolatile() && !Inst->isAtomic() &&
204 "Can't split volatile/atomic stores");
205 assert(cast<IntegerType>(Inst->getValueOperand()->getType())->getBitWidth() % 8 == 0);
Mark Seaborn 2013/05/06 17:04:06 Line >80 chars
Derek Schuff 2013/05/08 22:33:28 Done.
206
207 Value *OrigPtr = State.getConverted(Inst->getPointerOperand());
208 // OrigPtr is now a placeholder in recursive calls, and so has no name
209 if (OrigPtr->getName().empty())
210 OrigPtr->setName(Inst->getPointerOperand()->getName());
211 Value *OrigVal = State.getConverted(Inst->getValueOperand());
212 unsigned Width = cast<IntegerType>(
213 Inst->getValueOperand()->getType())->getBitWidth();
214 unsigned LoWidth = Width;
215
216 while (!isLegalSize(LoWidth)) LoWidth -= 8;
217 IntegerType *LoType = IntegerType::get(Inst->getContext(), LoWidth);
218 IntegerType *HiType = IntegerType::get(Inst->getContext(), Width - LoWidth);
219 IRBuilder<> IRB(Inst->getParent(), Inst);
220
221 Value *BCLo = IRB.CreateBitCast(
222 OrigPtr,
223 LoType->getPointerTo(),
224 OrigPtr->getName() + ".loty");
225 Value *LoTrunc = IRB.CreateTrunc(
226 OrigVal, LoType, OrigVal->getName() + ".lo");
227 IRB.CreateAlignedStore(LoTrunc, BCLo, Inst->getAlignment());
228
229 Value *HiLShr = IRB.CreateLShr(
230 OrigVal, LoWidth, OrigVal->getName() + ".hi.sh");
231 Value *GEPHi = IRB.CreateConstGEP1_32(BCLo, 1, OrigPtr->getName() + ".hi");
232 Value *HiTrunc = IRB.CreateTrunc(
233 HiLShr, HiType, OrigVal->getName() + ".hi");
234 Value *BCHi = IRB.CreateBitCast(
235 GEPHi,
236 HiType->getPointerTo(),
237 OrigPtr->getName() + ".hity");
238
239 Value *StoreHi = IRB.CreateStore(HiTrunc, BCHi);
240
241 if (!isLegalSize(Width - LoWidth)) {
242 // HiTrunc is still illegal, and is redundant with the truncate in the
243 // recursive call, so just get rid of it.
244 State.recordConverted(HiTrunc, HiLShr, /*TakeName=*/false);
245 StoreHi = splitStore(cast<StoreInst>(StoreHi), State);
246 // BCHi was still illegal, and has been replaced with a placeholder in the
247 // recursive call. Since it is redundant with BCLo in the recursive call,
248 // just splice it out entirely.
249 State.recordConverted(BCHi, GEPHi, /*TakeName=*/false);
250 }
251 State.recordConverted(Inst, StoreHi, /*TakeName=*/false);
252 return StoreHi;
253 }
254
255 // Return a value with the bits of the operand above the size of the original
256 // type cleared. The operand is assumed to have been legalized already.
257 static Value *getClearUpper(Value *Operand, Type *OrigType,
258 Instruction *InsertPt) {
259 // If the operand is a constant, it will have been created by
260 // ConversionState.getConverted, which zero-extends by default.
261 if (isa<Constant>(Operand))
262 return Operand;
263 return BinaryOperator::Create(
264 Instruction::And,
265 Operand,
266 ConstantInt::get(
267 convertType(OrigType),
268 APInt::getLowBitsSet(convertType(OrigType)->getIntegerBitWidth(),
269 OrigType->getIntegerBitWidth())),
270 Operand->getName() + ".clear",
271 InsertPt);
272 }
273
274 // Return a value with the bits of the operand above the size of the original
275 // type equal to the sign bit of the original operand. The new operand is
276 // assumed to have been legalized already.
277 // This is done by shifting the sign bit of the smaller value up to the MSB
278 // position in the larger size, and then arithmetic-shifting it back down
279 static Value *getSignExtend(Value *Operand, Value *OrigOperand,
280 Instruction *InsertPt) {
281 // If OrigOperand was a constant, NewOperand will have been created by
282 // ConversionState.getConverted, which zero-extends by default. But that is
283 // wrong here, so replace it with a sign-extended constant.
284 if (Constant *C = dyn_cast<Constant>(OrigOperand))
285 return convertConstant(C, /*SignExt=*/true);
286 Type *OrigType = OrigOperand->getType();
287 ConstantInt *ShiftAmt = ConstantInt::getSigned(
288 cast<IntegerType>(convertType(OrigType)),
289 convertType(OrigType)->getIntegerBitWidth() -
290 OrigType->getIntegerBitWidth());
291 BinaryOperator *Shl = BinaryOperator::Create(
292 Instruction::Shl,
293 Operand,
294 ShiftAmt,
295 Operand->getName() + ".getsign",
296 InsertPt);
297 return BinaryOperator::Create(
298 Instruction::AShr,
299 Shl,
300 ShiftAmt,
301 Operand->getName() + ".signed",
302 InsertPt);
303 }
304
305 bool PromoteIntegers::runOnFunction(Function &F) {
306 ConversionState State;
307 // Don't support changing the function arguments. This should not be
308 // generated by clang.
309 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
310 Value *Arg = I;
311 if (shouldConvert(Arg)) {
312 errs() << "Function " << F.getName() << ": " << *Arg << "\n";
313 llvm_unreachable("Cannot convert function with illegal argument");
eliben 2013/05/06 21:58:40 "Convert" is too generic. "Function argument has
Derek Schuff 2013/05/08 22:33:28 Done.
314 }
315 }
316
317 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
318 for (BasicBlock::iterator BBI = FI->begin(), BBE = FI->end(); BBI != BBE;) {
319 Instruction *Inst = BBI++;
320 bool ShouldConvert = shouldConvert(Inst);
eliben 2013/05/06 21:58:40 Comment to clarify the |=...
Derek Schuff 2013/05/08 22:33:28 Done.
321 for (User::op_iterator OI = Inst->op_begin(), OE = Inst->op_end();
322 OI != OE; ++OI)
323 ShouldConvert |= shouldConvert(cast<Value>(OI));
324 if (!ShouldConvert)
325 continue;
326
327 if (SExtInst *Sext = dyn_cast<SExtInst>(Inst)) {
Mark Seaborn 2013/05/06 17:04:06 Maybe move this if/else chain to a top-level funct
Derek Schuff 2013/05/08 22:48:32 Done.
328 Value *Op = Sext->getOperand(0);
329 Value *NewInst = NULL;
330 if (shouldConvert(Op)) {
331 NewInst = getSignExtend(State.getConverted(Op), Op, Sext);
332 }
333 if (convertType(Op->getType()) != convertType(Sext->getType())) {
eliben 2013/05/06 21:58:40 Comment to explain the logic here
Derek Schuff 2013/05/08 22:33:28 Done.
334 NewInst = CastInst::CreateSExtOrBitCast(
335 NewInst ? NewInst : State.getConverted(Op),
336 convertType(cast<IntegerType>(Sext->getType())),
337 Sext->getName() + ".sext", Sext);
338 }
339 if (shouldConvert(Sext)) {
340 NewInst = getClearUpper(NewInst, Sext->getType(), Sext);
341 }
342 assert(NewInst && "Failed to convert sign extension");
343 State.recordConverted(Sext, NewInst);
344 } else if (ZExtInst *Zext = dyn_cast<ZExtInst>(Inst)) {
345 Value *Op = Zext->getOperand(0);
346 Value *NewInst = NULL;
347 // TODO(dschuff): Some of these zexts could be no-ops.
348 if (shouldConvert(Op)) {
349 NewInst = getClearUpper(State.getConverted(Op),
350 Op->getType(),
351 Zext);
352 }
353 if (convertType(Op->getType()) != convertType(Zext->getType())) {
354 NewInst = CastInst::CreateZExtOrBitCast(
355 NewInst ? NewInst : State.getConverted(Op),
356 convertType(cast<IntegerType>(Zext->getType())),
357 "", Zext);
358 }
359 assert(NewInst);
360 State.recordConverted(Zext, NewInst);
361 } else if (TruncInst *Trunc = dyn_cast<TruncInst>(Inst)) {
362 Value *Op = Trunc->getOperand(0);
363 Value *NewInst = NULL;
364 if (convertType(Op->getType()) != convertType(Trunc->getType())) {
365 NewInst = new TruncInst(
366 State.getConverted(Op),
367 convertType(cast<IntegerType>(Trunc->getType())),
368 State.getConverted(Op)->getName() + ".trunc",
369 Trunc);
370 }
371 if (shouldConvert(Trunc)) {
eliben 2013/05/06 21:58:40 Here and below, didn't you already establish Shoul
Derek Schuff 2013/05/08 22:33:28 Either the result or the operand needs to be conve
372 NewInst = getClearUpper(NewInst ? NewInst : Op,
373 Trunc->getType(),
374 Trunc);
375 }
376 assert(NewInst);
377 State.recordConverted(Trunc, NewInst);
378 } else if (AllocaInst *Alloc = dyn_cast<AllocaInst>(Inst)) {
379 // Don't handle arrays of illegal types, but we could handle an array
380 // with size specified as an illegal type, as unlikely as that seems.
381 assert(!(shouldConvert(Alloc) && Alloc->isArrayAllocation()));
382 AllocaInst *NewInst = new AllocaInst(
383 convertType(Alloc->getAllocatedType()),
384 State.getConverted(Alloc->getArraySize()),
385 "", Alloc);
386 NewInst->setAlignment(Alloc->getAlignment());
387 State.recordConverted(Alloc, NewInst);
388 } else if (BitCastInst *BCInst = dyn_cast<BitCastInst>(Inst)) {
389 // Only handle pointers. Ints can't be casted to/from other ints
Mark Seaborn 2013/05/06 17:04:06 It looks like you're trying to expand out pointers
Derek Schuff 2013/05/08 22:33:28 It's really not that much more complex to also cha
Mark Seaborn 2013/05/09 01:00:22 This seems to touch: * getPromotedType() * shoul
390 if (shouldConvert(BCInst) || shouldConvert(BCInst->getOperand(0))) {
391 BitCastInst *NewInst = new BitCastInst(
392 State.getConverted(BCInst->getOperand(0)),
393 convertType(BCInst->getDestTy()),
394 "", BCInst);
395 State.recordConverted(BCInst, NewInst);
396 }
397 } else if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
398 if (shouldConvert(Load)) {
399 splitLoad(Load, State);
400 }
401 } else if (StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
402 if (shouldConvert(Store->getValueOperand())) {
403 splitStore(Store, State);
404 }
405 } else if (CallInst *Call = dyn_cast<CallInst>(Inst)) {
406 llvm_unreachable("can't convert calls");
eliben 2013/05/06 21:58:40 Is this temporary? If not, why the code after it?
407 for (unsigned I = 0; I < Call->getNumArgOperands(); ++I) {
408 Value *Arg = Call->getArgOperand(I);
409 Call->setArgOperand(I, State.getConverted(Arg));
410 }
411 } else if (BinaryOperator *Binop = dyn_cast<BinaryOperator>(Inst)) {
412 Value *NewInst = NULL;
413 if (Binop->getOpcode() == Instruction::AShr) {
eliben 2013/05/06 21:58:40 Can't this be done in the same switch below?
Derek Schuff 2013/05/08 22:33:28 No; AShr needs to sign-extend its operand before d
414 // Combine the sign-extension with the actual AShr operation.
415 Value *Op = Binop->getOperand(0);
416 Value *ShiftAmount = NULL;
417 APInt SignShiftAmt = APInt(
418 convertType(Op->getType())->getIntegerBitWidth(),
419 convertType(Op->getType())->getIntegerBitWidth() -
420 Op->getType()->getIntegerBitWidth());
421 NewInst = BinaryOperator::Create(
422 Instruction::Shl,
423 State.getConverted(Op),
424 ConstantInt::get(convertType(Op->getType()), SignShiftAmt),
425 State.getConverted(Op)->getName() + ".getsign",
426 Binop);
427 if (ConstantInt *C = dyn_cast<ConstantInt>(
428 State.getConverted(Binop->getOperand(1)))) {
429 ShiftAmount = ConstantInt::get(convertType(Op->getType()),
430 SignShiftAmt + C->getValue());
431 } else {
432 ShiftAmount = BinaryOperator::Create(
433 Instruction::Add,
434 State.getConverted(Binop->getOperand(1)),
435 ConstantInt::get(convertType(Binop->getOperand(1)->getType()),
436 SignShiftAmt),
437 State.getConverted(Op)->getName() + ".shamt", Binop);
438 }
439 NewInst = BinaryOperator::Create(
440 Instruction::AShr,
441 NewInst,
442 ShiftAmount,
443 Binop->getName() + ".result", Binop);
444 } else {
445 NewInst = BinaryOperator::Create(
446 Binop->getOpcode(),
447 NewInst ? NewInst : State.getConverted(Binop->getOperand(0)),
448 State.getConverted(Binop->getOperand(1)),
449 Binop->getName() + ".result", Binop);
450 }
451
452 switch (Binop->getOpcode()) {
453 case Instruction::And:
454 case Instruction::Or:
455 case Instruction::Xor:
456 case Instruction::LShr:
457 // These won't change the upper bits.
458 break;
459 case Instruction::Add:
460 case Instruction::Sub:
461 case Instruction::Shl:
462 case Instruction::AShr:
463 // These can change the upper bits, so clear them now.
464 NewInst = getClearUpper(NewInst, Binop->getType(), Binop);
465 break;
466
467 // We should not see FP operators here.
468 // We don't handle mul/div.
469 case Instruction::FAdd:
470 case Instruction::FSub:
471 case Instruction::Mul:
472 case Instruction::FMul:
473 case Instruction::UDiv:
474 case Instruction::SDiv:
475 case Instruction::FDiv:
476 case Instruction::URem:
477 case Instruction::SRem:
478 case Instruction::FRem:
479 case Instruction::BinaryOpsEnd:
480 errs() << *Inst << "\n";
481 llvm_unreachable("Cannot handle binary operator");
482 break;
483 }
484
485 State.recordConverted(Binop, NewInst);
486 } else if (ICmpInst *Cmp = dyn_cast<ICmpInst>(Inst)) {
487 Value *Op0, *Op1;
eliben 2013/05/06 21:58:40 Comment
Derek Schuff 2013/05/08 22:33:28 Done.
488 if (Cmp->isSigned()) {
489 Op0 = getSignExtend(State.getConverted(Cmp->getOperand(0)),
490 Cmp->getOperand(0),
491 Cmp);
492 Op1 = getSignExtend(State.getConverted(Cmp->getOperand(1)),
493 Cmp->getOperand(1),
494 Cmp);
495 } else {
496 Op0 = State.getConverted(Cmp->getOperand(0));
497 Op1 = State.getConverted(Cmp->getOperand(1));
498 }
499 ICmpInst *NewInst = new ICmpInst(
500 Cmp, Cmp->getPredicate(), Op0, Op1, "");
501 State.recordConverted(Cmp, NewInst);
502 } else if (SelectInst *Select = dyn_cast<SelectInst>(Inst)) {
503 SelectInst *NewInst = SelectInst::Create(
504 Select->getCondition(),
505 State.getConverted(Select->getTrueValue()),
506 State.getConverted(Select->getFalseValue()),
507 "", Select);
508 State.recordConverted(Select, NewInst);
509 } else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) {
510 PHINode *NewPhi = PHINode::Create(
511 convertType(Phi->getType()),
512 Phi->getNumIncomingValues(),
513 "", Phi);
514 for (unsigned I = 0, E = Phi->getNumIncomingValues(); I < E; ++I) {
515 NewPhi->addIncoming(State.getConverted(Phi->getIncomingValue(I)),
516 Phi->getIncomingBlock(I));
517 }
518 State.recordConverted(Phi, NewPhi);
519 } else {
520 errs() << *Inst<<"\n";
521 llvm_unreachable("unhandled instruction");
522 }
523 }
524 }
525
526 return true;
527 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698