OLD | NEW |
(Empty) | |
| 1 //===- ReplacePtrsWithInts.cpp - Convert pointer values to integer values--===// |
| 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 strips out aggregate pointer types and replaces them with |
| 11 // the integer type iPTR, which is i32 for PNaCl (though this pass |
| 12 // will allow iPTR to be i64 if the DataLayout specifies 64-bit |
| 13 // pointers). |
| 14 // |
| 15 // The pass converts IR to the following normal form: |
| 16 // |
| 17 // All inttoptr and ptrtoint instructions use the same integer size |
| 18 // (iPTR), so they do not implicitly truncate or zero-extend. |
| 19 // |
| 20 // alloca always allocates an i8 array type. |
| 21 // |
| 22 // Pointer types only appear in the following instructions: |
| 23 // * loads and stores: the pointer operand is a NormalizedPtr. |
| 24 // * function calls: the function operand is a NormalizedPtr. |
| 25 // * intrinsic calls: any pointer arguments are NormalizedPtrs. |
| 26 // * alloca |
| 27 // * bitcast and inttoptr: only used as part of a NormalizedPtr. |
| 28 // * ptrtoint: the operand is an InherentPtr. |
| 29 // |
| 30 // Where an InherentPtr is defined as a pointer value that is: |
| 31 // * an alloca; |
| 32 // * a GlobalValue (a function or global variable); or |
| 33 // * an intrinsic call. |
| 34 // |
| 35 // And a NormalizedPtr is defined as a pointer value that is: |
| 36 // * an inttoptr instruction; |
| 37 // * an InherentPtr; or |
| 38 // * a bitcast of an InherentPtr. |
| 39 // |
| 40 // This pass currently strips out lifetime markers (that is, calls to |
| 41 // the llvm.lifetime.start/end intrinsics). |
| 42 // |
| 43 //===----------------------------------------------------------------------===// |
| 44 |
| 45 #include "llvm/ADT/DenseMap.h" |
| 46 #include "llvm/IR/DataLayout.h" |
| 47 #include "llvm/IR/DerivedTypes.h" |
| 48 #include "llvm/IR/Function.h" |
| 49 #include "llvm/IR/IRBuilder.h" |
| 50 #include "llvm/IR/Instructions.h" |
| 51 #include "llvm/IR/IntrinsicInst.h" |
| 52 #include "llvm/IR/Module.h" |
| 53 #include "llvm/IR/Type.h" |
| 54 #include "llvm/Pass.h" |
| 55 #include "llvm/Support/raw_ostream.h" |
| 56 #include "llvm/Transforms/NaCl.h" |
| 57 |
| 58 using namespace llvm; |
| 59 |
| 60 namespace { |
| 61 // This is a ModulePass because the pass must recreate functions in |
| 62 // order to change their argument and return types. |
| 63 struct ReplacePtrsWithInts : public ModulePass { |
| 64 static char ID; // Pass identification, replacement for typeid |
| 65 ReplacePtrsWithInts() : ModulePass(ID) { |
| 66 initializeReplacePtrsWithIntsPass(*PassRegistry::getPassRegistry()); |
| 67 } |
| 68 |
| 69 virtual bool runOnModule(Module &M); |
| 70 }; |
| 71 |
| 72 // FunctionConverter stores the state for mapping old instructions |
| 73 // (of pointer type) to converted instructions (of integer type) |
| 74 // within a function, and provides methods for doing the conversion. |
| 75 class FunctionConverter { |
| 76 // Int type that pointer types are to be replaced with, typically i32. |
| 77 Type *IntPtrType; |
| 78 |
| 79 struct RewrittenVal { |
| 80 RewrittenVal(): IsPlaceholder(true), NewIntVal(NULL) {} |
| 81 bool IsPlaceholder; |
| 82 Value *NewIntVal; |
| 83 }; |
| 84 // Maps from old values (of pointer type) to converted values (of |
| 85 // IntPtrType type). |
| 86 DenseMap<Value *, RewrittenVal> RewriteMap; |
| 87 // Number of placeholders; used for detecting unhandled cases. |
| 88 int PlaceholderCount; |
| 89 // List of instructions whose deletion has been deferred. |
| 90 SmallVector<Instruction *, 20> ToErase; |
| 91 |
| 92 public: |
| 93 FunctionConverter(Type *IntPtrType) |
| 94 : IntPtrType(IntPtrType), PlaceholderCount(0) {} |
| 95 |
| 96 // Returns the normalized version of the given type, converting |
| 97 // pointer types to IntPtrType. |
| 98 Type *convertType(Type *Ty); |
| 99 // Returns the normalized version of the given function type by |
| 100 // normalizing the function's argument types. |
| 101 FunctionType *convertFuncType(FunctionType *FTy); |
| 102 |
| 103 // Records that 'To' is the normalized version of 'From'. If 'To' |
| 104 // is not of pointer type, no type conversion is required, so this |
| 105 // can take the short cut of replacing 'To' with 'From'. |
| 106 void recordConverted(Value *From, Value *To); |
| 107 void recordConvertedAndErase(Instruction *From, Value *To); |
| 108 |
| 109 // Returns the normalized version of the given value. |
| 110 Value *convert(Value *Val); |
| 111 // Returns the NormalizedPtr form of the given pointer value. |
| 112 // Inserts conversion instructions at InsertPt. |
| 113 Value *convertBackToPtr(Value *Val, Instruction *InsertPt); |
| 114 // Returns the NormalizedPtr form of the given function pointer. |
| 115 // Inserts conversion instructions at InsertPt. |
| 116 Value *convertFunctionPtr(Value *Callee, Instruction *InsertPt); |
| 117 // Converts an instruction without recreating it, by wrapping its |
| 118 // operands and result. |
| 119 void convertInPlace(Instruction *Inst); |
| 120 |
| 121 void eraseReplacedInstructions(); |
| 122 }; |
| 123 } |
| 124 |
| 125 Type *FunctionConverter::convertType(Type *Ty) { |
| 126 if (Ty->isPointerTy()) |
| 127 return IntPtrType; |
| 128 return Ty; |
| 129 } |
| 130 |
| 131 FunctionType *FunctionConverter::convertFuncType(FunctionType *FTy) { |
| 132 SmallVector<Type *, 8> ArgTypes; |
| 133 for (FunctionType::param_iterator ArgTy = FTy->param_begin(), |
| 134 E = FTy->param_end(); ArgTy != E; ++ArgTy) { |
| 135 ArgTypes.push_back(convertType(*ArgTy)); |
| 136 } |
| 137 return FunctionType::get(convertType(FTy->getReturnType()), ArgTypes, |
| 138 FTy->isVarArg()); |
| 139 } |
| 140 |
| 141 void FunctionConverter::recordConverted(Value *From, Value *To) { |
| 142 if (!From->getType()->isPointerTy()) { |
| 143 From->replaceAllUsesWith(To); |
| 144 return; |
| 145 } |
| 146 RewrittenVal *RV = &RewriteMap[From]; |
| 147 if (RV->NewIntVal) { |
| 148 assert(RV->IsPlaceholder); |
| 149 // Resolve placeholder. |
| 150 RV->NewIntVal->replaceAllUsesWith(To); |
| 151 delete RV->NewIntVal; |
| 152 RV->IsPlaceholder = false; |
| 153 --PlaceholderCount; |
| 154 } |
| 155 RV->NewIntVal = To; |
| 156 } |
| 157 |
| 158 void FunctionConverter::recordConvertedAndErase(Instruction *From, Value *To) { |
| 159 recordConverted(From, To); |
| 160 // There may still be references to this value, so defer deleting it. |
| 161 ToErase.push_back(From); |
| 162 } |
| 163 |
| 164 Value *FunctionConverter::convert(Value *Val) { |
| 165 if (!Val->getType()->isPointerTy()) |
| 166 return Val; |
| 167 if (Constant *C = dyn_cast<Constant>(Val)) |
| 168 return ConstantExpr::getPtrToInt(C, IntPtrType); |
| 169 RewrittenVal *RV = &RewriteMap[Val]; |
| 170 if (!RV->NewIntVal) { |
| 171 // No converted value available yet, so create a placeholder. |
| 172 Argument *Placeholder = new Argument(convertType(Val->getType())); |
| 173 RV->NewIntVal = Placeholder; |
| 174 ++PlaceholderCount; |
| 175 } |
| 176 return RV->NewIntVal; |
| 177 } |
| 178 |
| 179 Value *FunctionConverter::convertBackToPtr(Value *Val, Instruction *InsertPt) { |
| 180 Type *NewTy = |
| 181 convertType(Val->getType()->getPointerElementType())->getPointerTo(); |
| 182 Value *Conv = convert(Val); |
| 183 return new IntToPtrInst(Conv, NewTy, Conv->getName() + ".asptr", InsertPt); |
| 184 } |
| 185 |
| 186 Value *FunctionConverter::convertFunctionPtr(Value *Callee, |
| 187 Instruction *InsertPt) { |
| 188 FunctionType *FuncType = cast<FunctionType>( |
| 189 Callee->getType()->getPointerElementType()); |
| 190 Value *Conv = convert(Callee); |
| 191 return new IntToPtrInst(Conv, convertFuncType(FuncType)->getPointerTo(), |
| 192 Conv->getName() + ".asfuncptr", InsertPt); |
| 193 } |
| 194 |
| 195 static bool ShouldLeaveAlone(Value *V) { |
| 196 if (Function *F = dyn_cast<Function>(V)) |
| 197 return F->isIntrinsic(); |
| 198 if (isa<InlineAsm>(V)) |
| 199 return true; |
| 200 return false; |
| 201 } |
| 202 |
| 203 void FunctionConverter::convertInPlace(Instruction *Inst) { |
| 204 // Convert operands. |
| 205 for (unsigned I = 0; I < Inst->getNumOperands(); ++I) { |
| 206 Value *Arg = Inst->getOperand(I); |
| 207 if (Arg->getType()->isPointerTy() && !ShouldLeaveAlone(Arg)) { |
| 208 Value *Conv = convert(Arg); |
| 209 Inst->setOperand(I, new IntToPtrInst(convert(Arg), Arg->getType(), |
| 210 Conv->getName() + ".asptr", Inst)); |
| 211 } |
| 212 } |
| 213 // Convert result. |
| 214 if (Inst->getType()->isPointerTy()) { |
| 215 Instruction *Cast = new PtrToIntInst( |
| 216 Inst, convertType(Inst->getType()), Inst->getName() + ".asint"); |
| 217 Cast->insertAfter(Inst); |
| 218 recordConverted(Inst, Cast); |
| 219 } |
| 220 } |
| 221 |
| 222 void FunctionConverter::eraseReplacedInstructions() { |
| 223 if (PlaceholderCount) { |
| 224 for (DenseMap<Value *, RewrittenVal>::iterator I = RewriteMap.begin(), |
| 225 E = RewriteMap.end(); I != E; ++I) { |
| 226 if (I->second.IsPlaceholder) |
| 227 errs() << "Not converted: " << *I->first << "\n"; |
| 228 } |
| 229 report_fatal_error("Case not handled in ReplacePtrsWithInts"); |
| 230 } |
| 231 // We must do dropAllReferences() before doing eraseFromParent(), |
| 232 // otherwise we will try to erase instructions that are still |
| 233 // referenced. |
| 234 for (SmallVectorImpl<Instruction *>::iterator I = ToErase.begin(), |
| 235 E = ToErase.end(); |
| 236 I != E; ++I) { |
| 237 (*I)->dropAllReferences(); |
| 238 } |
| 239 for (SmallVectorImpl<Instruction *>::iterator I = ToErase.begin(), |
| 240 E = ToErase.end(); |
| 241 I != E; ++I) { |
| 242 (*I)->eraseFromParent(); |
| 243 } |
| 244 } |
| 245 |
| 246 static void ConvertMetadataOperand(FunctionConverter *FC, |
| 247 IntrinsicInst *Call, int Index) { |
| 248 MDNode *MD = cast<MDNode>(Call->getArgOperand(Index)); |
| 249 if (MD->getNumOperands() != 1) |
| 250 return; |
| 251 Value *MDArg = MD->getOperand(0); |
| 252 if (MDArg && (isa<Argument>(MDArg) || isa<Instruction>(MDArg))) { |
| 253 MDArg = FC->convert(MDArg); |
| 254 if (PtrToIntInst *Cast = dyn_cast<PtrToIntInst>(MDArg)) { |
| 255 // Unwrapping this is necessary for llvm.dbg.declare to work. |
| 256 MDArg = Cast->getPointerOperand(); |
| 257 } |
| 258 SmallVector<Value *, 1> Args; |
| 259 Args.push_back(MDArg); |
| 260 Call->setArgOperand(Index, MDNode::get(Call->getContext(), Args)); |
| 261 } |
| 262 } |
| 263 |
| 264 // Remove attributes that only apply to pointer arguments. Returns |
| 265 // the updated AttributeSet. |
| 266 static AttributeSet RemovePointerAttrs(LLVMContext &Context, |
| 267 AttributeSet Attrs) { |
| 268 SmallVector<AttributeSet, 8> AttrList; |
| 269 for (unsigned Slot = 0; Slot < Attrs.getNumSlots(); ++Slot) { |
| 270 unsigned Index = Attrs.getSlotIndex(Slot); |
| 271 AttrBuilder AB; |
| 272 for (AttributeSet::iterator Attr = Attrs.begin(Slot), E = Attrs.end(Slot); |
| 273 Attr != E; ++Attr) { |
| 274 switch (Attr->getKindAsEnum()) { |
| 275 // ByVal and StructRet should already have been removed by the |
| 276 // ExpandByVal pass. |
| 277 case Attribute::ByVal: |
| 278 case Attribute::StructRet: |
| 279 case Attribute::Nest: |
| 280 Attrs.dump(); |
| 281 report_fatal_error("ReplacePtrsWithInts cannot handle " |
| 282 "byval, sret or nest attrs"); |
| 283 break; |
| 284 // Strip NoCapture and NoAlias because they are only allowed |
| 285 // on arguments of pointer type, and we are removing the |
| 286 // pointer types. |
| 287 case Attribute::NoCapture: |
| 288 case Attribute::NoAlias: |
| 289 break; |
| 290 default: |
| 291 AB.addAttribute(*Attr); |
| 292 } |
| 293 } |
| 294 AttrList.push_back(AttributeSet::get(Context, Index, AB)); |
| 295 } |
| 296 return AttributeSet::get(Context, AttrList); |
| 297 } |
| 298 |
| 299 template <class InstType> |
| 300 static void CopyLoadOrStoreAttrs(InstType *Dest, InstType *Src) { |
| 301 Dest->setVolatile(Src->isVolatile()); |
| 302 Dest->setAlignment(Src->getAlignment()); |
| 303 Dest->setOrdering(Src->getOrdering()); |
| 304 Dest->setSynchScope(Src->getSynchScope()); |
| 305 } |
| 306 |
| 307 static void ConvertInstruction(DataLayout *DL, Type *IntPtrType, |
| 308 FunctionConverter *FC, Instruction *Inst) { |
| 309 if (ReturnInst *Ret = dyn_cast<ReturnInst>(Inst)) { |
| 310 Value *Result = Ret->getReturnValue(); |
| 311 if (Result) |
| 312 Result = FC->convert(Result); |
| 313 CopyDebug(ReturnInst::Create(Ret->getContext(), Result, Ret), Inst); |
| 314 Ret->eraseFromParent(); |
| 315 } else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) { |
| 316 PHINode *Phi2 = PHINode::Create(FC->convertType(Phi->getType()), |
| 317 Phi->getNumIncomingValues(), |
| 318 "", Phi); |
| 319 CopyDebug(Phi2, Phi); |
| 320 for (unsigned I = 0; I < Phi->getNumIncomingValues(); ++I) { |
| 321 Phi2->addIncoming(FC->convert(Phi->getIncomingValue(I)), |
| 322 Phi->getIncomingBlock(I)); |
| 323 } |
| 324 Phi2->takeName(Phi); |
| 325 FC->recordConvertedAndErase(Phi, Phi2); |
| 326 } else if (SelectInst *Op = dyn_cast<SelectInst>(Inst)) { |
| 327 Instruction *Op2 = SelectInst::Create(Op->getCondition(), |
| 328 FC->convert(Op->getTrueValue()), |
| 329 FC->convert(Op->getFalseValue()), |
| 330 "", Op); |
| 331 CopyDebug(Op2, Op); |
| 332 Op2->takeName(Op); |
| 333 FC->recordConvertedAndErase(Op, Op2); |
| 334 } else if (isa<PtrToIntInst>(Inst) || isa<IntToPtrInst>(Inst)) { |
| 335 Value *Arg = FC->convert(Inst->getOperand(0)); |
| 336 Type *ResultTy = FC->convertType(Inst->getType()); |
| 337 IRBuilder<> Builder(Inst); |
| 338 Builder.SetCurrentDebugLocation(Inst->getDebugLoc()); |
| 339 Value *Result = Builder.CreateZExtOrTrunc(Arg, ResultTy, ""); |
| 340 if (Result != Arg) |
| 341 Result->takeName(Inst); |
| 342 FC->recordConvertedAndErase(Inst, Result); |
| 343 } else if (isa<BitCastInst>(Inst)) { |
| 344 if (Inst->getType()->isPointerTy()) { |
| 345 FC->recordConvertedAndErase(Inst, FC->convert(Inst->getOperand(0))); |
| 346 } |
| 347 } else if (ICmpInst *Cmp = dyn_cast<ICmpInst>(Inst)) { |
| 348 Value *Cmp2 = CopyDebug(new ICmpInst(Inst, Cmp->getPredicate(), |
| 349 FC->convert(Cmp->getOperand(0)), |
| 350 FC->convert(Cmp->getOperand(1)), ""), |
| 351 Inst); |
| 352 Cmp2->takeName(Cmp); |
| 353 Cmp->replaceAllUsesWith(Cmp2); |
| 354 Cmp->eraseFromParent(); |
| 355 } else if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) { |
| 356 Value *Ptr = FC->convertBackToPtr(Load->getPointerOperand(), Inst); |
| 357 LoadInst *Result = new LoadInst(Ptr, "", Inst); |
| 358 Result->takeName(Inst); |
| 359 CopyDebug(Result, Inst); |
| 360 CopyLoadOrStoreAttrs(Result, Load); |
| 361 FC->recordConvertedAndErase(Inst, Result); |
| 362 } else if (StoreInst *Store = dyn_cast<StoreInst>(Inst)) { |
| 363 Value *Ptr = FC->convertBackToPtr(Store->getPointerOperand(), Inst); |
| 364 StoreInst *Result = new StoreInst(FC->convert(Store->getValueOperand()), |
| 365 Ptr, Inst); |
| 366 CopyDebug(Result, Inst); |
| 367 CopyLoadOrStoreAttrs(Result, Store); |
| 368 Inst->eraseFromParent(); |
| 369 } else if (CallInst *Call = dyn_cast<CallInst>(Inst)) { |
| 370 if (IntrinsicInst *ICall = dyn_cast<IntrinsicInst>(Inst)) { |
| 371 if (ICall->getIntrinsicID() == Intrinsic::lifetime_start || |
| 372 ICall->getIntrinsicID() == Intrinsic::lifetime_end) { |
| 373 // Remove alloca lifetime markers for now. This is because |
| 374 // the GVN pass can introduce lifetime markers taking PHI |
| 375 // nodes as arguments. If ReplacePtrsWithInts converts the |
| 376 // PHI node to int type, we will render those lifetime markers |
| 377 // ineffective. But dropping a subset of lifetime markers is |
| 378 // not safe in general. So, until LLVM better defines the |
| 379 // semantics of lifetime markers, we drop them all. See: |
| 380 // https://code.google.com/p/nativeclient/issues/detail?id=3443 |
| 381 Inst->eraseFromParent(); |
| 382 } else { |
| 383 if (ICall->getIntrinsicID() == Intrinsic::dbg_declare) { |
| 384 ConvertMetadataOperand(FC, ICall, 0); |
| 385 } |
| 386 FC->convertInPlace(Inst); |
| 387 } |
| 388 } else if (isa<InlineAsm>(Call->getCalledValue())) { |
| 389 FC->convertInPlace(Inst); |
| 390 } else { |
| 391 SmallVector<Value *, 10> Args; |
| 392 for (unsigned I = 0; I < Call->getNumArgOperands(); ++I) |
| 393 Args.push_back(FC->convert(Call->getArgOperand(I))); |
| 394 CallInst *NewCall = CallInst::Create( |
| 395 FC->convertFunctionPtr(Call->getCalledValue(), Call), |
| 396 Args, "", Inst); |
| 397 CopyDebug(NewCall, Call); |
| 398 NewCall->setAttributes(RemovePointerAttrs(Call->getContext(), |
| 399 Call->getAttributes())); |
| 400 NewCall->setCallingConv(Call->getCallingConv()); |
| 401 NewCall->takeName(Call); |
| 402 FC->recordConvertedAndErase(Call, NewCall); |
| 403 } |
| 404 } else if (InvokeInst *Call = dyn_cast<InvokeInst>(Inst)) { |
| 405 SmallVector<Value *, 10> Args; |
| 406 for (unsigned I = 0; I < Call->getNumArgOperands(); ++I) |
| 407 Args.push_back(FC->convert(Call->getArgOperand(I))); |
| 408 InvokeInst *NewCall = InvokeInst::Create( |
| 409 FC->convertFunctionPtr(Call->getCalledValue(), Call), |
| 410 Call->getNormalDest(), |
| 411 Call->getUnwindDest(), |
| 412 Args, "", Inst); |
| 413 CopyDebug(NewCall, Call); |
| 414 NewCall->setAttributes(RemovePointerAttrs(Call->getContext(), |
| 415 Call->getAttributes())); |
| 416 NewCall->setCallingConv(Call->getCallingConv()); |
| 417 NewCall->takeName(Call); |
| 418 FC->recordConvertedAndErase(Call, NewCall); |
| 419 } else if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Inst)) { |
| 420 Type *ElementTy = Inst->getType()->getPointerElementType(); |
| 421 Type *ElementTy2 = ArrayType::get(Type::getInt8Ty(Inst->getContext()), |
| 422 DL->getTypeAllocSize(ElementTy)); |
| 423 unsigned Alignment = Alloca->getAlignment(); |
| 424 if (Alignment == 0) |
| 425 Alignment = DL->getPrefTypeAlignment(ElementTy); |
| 426 Value *Tmp = CopyDebug(new AllocaInst(ElementTy2, Alloca->getArraySize(), |
| 427 Alignment, "", Inst), |
| 428 Inst); |
| 429 Tmp->takeName(Alloca); |
| 430 Value *Alloca2 = new PtrToIntInst(Tmp, IntPtrType, |
| 431 Tmp->getName() + ".asint", Inst); |
| 432 FC->recordConvertedAndErase(Alloca, Alloca2); |
| 433 } else if (// These atomics only operate on integer pointers, not |
| 434 // other pointers, so we don't need to recreate the |
| 435 // instruction. |
| 436 isa<AtomicCmpXchgInst>(Inst) || |
| 437 isa<AtomicRMWInst>(Inst) || |
| 438 // Handle these instructions as a convenience to allow |
| 439 // the pass to be used in more situations, even though we |
| 440 // don't expect them in PNaCl's stable ABI. |
| 441 isa<GetElementPtrInst>(Inst) || |
| 442 isa<VAArgInst>(Inst) || |
| 443 isa<IndirectBrInst>(Inst) || |
| 444 isa<ExtractValueInst>(Inst) || |
| 445 isa<InsertValueInst>(Inst)) { |
| 446 FC->convertInPlace(Inst); |
| 447 } |
| 448 } |
| 449 |
| 450 // Convert ptrtoint+inttoptr to a bitcast because it's shorter and |
| 451 // because some intrinsics work on bitcasts but not on |
| 452 // ptrtoint+inttoptr, in particular: |
| 453 // * llvm.lifetime.start/end (although we strip these out) |
| 454 // * llvm.eh.typeid.for |
| 455 static void SimplifyCasts(Instruction *Inst, Type *IntPtrType) { |
| 456 if (IntToPtrInst *Cast1 = dyn_cast<IntToPtrInst>(Inst)) { |
| 457 if (PtrToIntInst *Cast2 = dyn_cast<PtrToIntInst>(Cast1->getOperand(0))) { |
| 458 assert(Cast2->getType() == IntPtrType); |
| 459 Value *V = Cast2->getPointerOperand(); |
| 460 if (V->getType() != Cast1->getType()) |
| 461 V = new BitCastInst(V, Cast1->getType(), V->getName() + ".bc", Cast1); |
| 462 Cast1->replaceAllUsesWith(V); |
| 463 if (Cast1->use_empty()) |
| 464 Cast1->eraseFromParent(); |
| 465 if (Cast2->use_empty()) |
| 466 Cast2->eraseFromParent(); |
| 467 } |
| 468 } |
| 469 } |
| 470 |
| 471 static void CleanUpFunction(Function *Func, Type *IntPtrType) { |
| 472 // Remove the ptrtoint/bitcast ConstantExprs we introduced for |
| 473 // referencing globals. |
| 474 FunctionPass *Pass = createExpandConstantExprPass(); |
| 475 Pass->runOnFunction(*Func); |
| 476 delete Pass; |
| 477 |
| 478 for (Function::iterator BB = Func->begin(), E = Func->end(); |
| 479 BB != E; ++BB) { |
| 480 for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); |
| 481 Iter != E; ) { |
| 482 SimplifyCasts(Iter++, IntPtrType); |
| 483 } |
| 484 } |
| 485 // Cleanup: Remove ptrtoints that were introduced for allocas but not used. |
| 486 for (Function::iterator BB = Func->begin(), E = Func->end(); |
| 487 BB != E; ++BB) { |
| 488 for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); |
| 489 Iter != E; ) { |
| 490 Instruction *Inst = Iter++; |
| 491 if (isa<PtrToIntInst>(Inst) && Inst->use_empty()) |
| 492 Inst->eraseFromParent(); |
| 493 } |
| 494 } |
| 495 } |
| 496 |
| 497 char ReplacePtrsWithInts::ID = 0; |
| 498 INITIALIZE_PASS(ReplacePtrsWithInts, "replace-ptrs-with-ints", |
| 499 "Convert pointer values to integer values", |
| 500 false, false) |
| 501 |
| 502 bool ReplacePtrsWithInts::runOnModule(Module &M) { |
| 503 DataLayout DL(&M); |
| 504 Type *IntPtrType = DL.getIntPtrType(M.getContext()); |
| 505 |
| 506 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) { |
| 507 Function *OldFunc = Iter++; |
| 508 // Intrinsics' types must be left alone. |
| 509 if (OldFunc->isIntrinsic()) |
| 510 continue; |
| 511 |
| 512 FunctionConverter FC(IntPtrType); |
| 513 FunctionType *NFTy = FC.convertFuncType(OldFunc->getFunctionType()); |
| 514 |
| 515 // In order to change the function's argument types, we have to |
| 516 // recreate the function. |
| 517 Function *NewFunc = Function::Create(NFTy, OldFunc->getLinkage()); |
| 518 NewFunc->copyAttributesFrom(OldFunc); |
| 519 NewFunc->setAttributes(RemovePointerAttrs(M.getContext(), |
| 520 NewFunc->getAttributes())); |
| 521 M.getFunctionList().insert(OldFunc, NewFunc); |
| 522 NewFunc->takeName(OldFunc); |
| 523 NewFunc->getBasicBlockList().splice(NewFunc->begin(), |
| 524 OldFunc->getBasicBlockList()); |
| 525 |
| 526 // Move the arguments across to the new function. |
| 527 for (Function::arg_iterator Arg = OldFunc->arg_begin(), |
| 528 E = OldFunc->arg_end(), NewArg = NewFunc->arg_begin(); |
| 529 Arg != E; ++Arg, ++NewArg) { |
| 530 FC.recordConverted(Arg, NewArg); |
| 531 NewArg->takeName(Arg); |
| 532 } |
| 533 |
| 534 // Convert the function body. |
| 535 for (Function::iterator BB = NewFunc->begin(), E = NewFunc->end(); |
| 536 BB != E; ++BB) { |
| 537 for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); |
| 538 Iter != E; ) { |
| 539 ConvertInstruction(&DL, IntPtrType, &FC, Iter++); |
| 540 } |
| 541 } |
| 542 FC.eraseReplacedInstructions(); |
| 543 OldFunc->replaceAllUsesWith(ConstantExpr::getBitCast(NewFunc, |
| 544 OldFunc->getType())); |
| 545 OldFunc->eraseFromParent(); |
| 546 } |
| 547 // Now that all functions have their normalized types, we can remove |
| 548 // various casts. |
| 549 for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) { |
| 550 CleanUpFunction(Func, IntPtrType); |
| 551 } |
| 552 return true; |
| 553 } |
| 554 |
| 555 ModulePass *llvm::createReplacePtrsWithIntsPass() { |
| 556 return new ReplacePtrsWithInts(); |
| 557 } |
OLD | NEW |