IntrinsicLowering.cpp (208954) | IntrinsicLowering.cpp (210299) |
---|---|
1//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 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 file implements the IntrinsicLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/Constants.h" 15#include "llvm/DerivedTypes.h" 16#include "llvm/Module.h" 17#include "llvm/Type.h" 18#include "llvm/CodeGen/IntrinsicLowering.h" | 1//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 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 file implements the IntrinsicLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/Constants.h" 15#include "llvm/DerivedTypes.h" 16#include "llvm/Module.h" 17#include "llvm/Type.h" 18#include "llvm/CodeGen/IntrinsicLowering.h" |
19#include "llvm/Support/CallSite.h" |
|
19#include "llvm/Support/ErrorHandling.h" 20#include "llvm/Support/IRBuilder.h" 21#include "llvm/Support/raw_ostream.h" 22#include "llvm/Target/TargetData.h" 23#include "llvm/ADT/SmallVector.h" 24using namespace llvm; 25 26template <class ArgIt> --- 282 unchanged lines hidden (view full) --- 309 310 V = Builder.CreateNot(V); 311 return LowerCTPOP(Context, V, IP); 312} 313 314static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, 315 const char *Dname, 316 const char *LDname) { | 20#include "llvm/Support/ErrorHandling.h" 21#include "llvm/Support/IRBuilder.h" 22#include "llvm/Support/raw_ostream.h" 23#include "llvm/Target/TargetData.h" 24#include "llvm/ADT/SmallVector.h" 25using namespace llvm; 26 27template <class ArgIt> --- 282 unchanged lines hidden (view full) --- 310 311 V = Builder.CreateNot(V); 312 return LowerCTPOP(Context, V, IP); 313} 314 315static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, 316 const char *Dname, 317 const char *LDname) { |
317 switch (CI->getOperand(1)->getType()->getTypeID()) { | 318 CallSite CS(CI); 319 switch (CI->getArgOperand(0)->getType()->getTypeID()) { |
318 default: llvm_unreachable("Invalid type in intrinsic"); 319 case Type::FloatTyID: | 320 default: llvm_unreachable("Invalid type in intrinsic"); 321 case Type::FloatTyID: |
320 ReplaceCallWith(Fname, CI, CI->op_begin() + 1, CI->op_end(), | 322 ReplaceCallWith(Fname, CI, CS.arg_begin(), CS.arg_end(), |
321 Type::getFloatTy(CI->getContext())); 322 break; 323 case Type::DoubleTyID: | 323 Type::getFloatTy(CI->getContext())); 324 break; 325 case Type::DoubleTyID: |
324 ReplaceCallWith(Dname, CI, CI->op_begin() + 1, CI->op_end(), | 326 ReplaceCallWith(Dname, CI, CS.arg_begin(), CS.arg_end(), |
325 Type::getDoubleTy(CI->getContext())); 326 break; 327 case Type::X86_FP80TyID: 328 case Type::FP128TyID: 329 case Type::PPC_FP128TyID: | 327 Type::getDoubleTy(CI->getContext())); 328 break; 329 case Type::X86_FP80TyID: 330 case Type::FP128TyID: 331 case Type::PPC_FP128TyID: |
330 ReplaceCallWith(LDname, CI, CI->op_begin() + 1, CI->op_end(), 331 CI->getOperand(1)->getType()); | 332 ReplaceCallWith(LDname, CI, CS.arg_begin(), CS.arg_end(), 333 CI->getArgOperand(0)->getType()); |
332 break; 333 } 334} 335 336void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { 337 IRBuilder<> Builder(CI->getParent(), CI); 338 LLVMContext &Context = CI->getContext(); 339 340 const Function *Callee = CI->getCalledFunction(); 341 assert(Callee && "Cannot lower an indirect call!"); 342 | 334 break; 335 } 336} 337 338void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { 339 IRBuilder<> Builder(CI->getParent(), CI); 340 LLVMContext &Context = CI->getContext(); 341 342 const Function *Callee = CI->getCalledFunction(); 343 assert(Callee && "Cannot lower an indirect call!"); 344 |
345 CallSite CS(CI); |
|
343 switch (Callee->getIntrinsicID()) { 344 case Intrinsic::not_intrinsic: 345 report_fatal_error("Cannot lower a call to a non-intrinsic function '"+ 346 Callee->getName() + "'!"); 347 default: 348 report_fatal_error("Code generator does not support intrinsic function '"+ 349 Callee->getName()+"'!"); 350 351 // The setjmp/longjmp intrinsics should only exist in the code if it was 352 // never optimized (ie, right out of the CFE), or if it has been hacked on 353 // by the lowerinvoke pass. In both cases, the right thing to do is to 354 // convert the call to an explicit setjmp or longjmp call. 355 case Intrinsic::setjmp: { | 346 switch (Callee->getIntrinsicID()) { 347 case Intrinsic::not_intrinsic: 348 report_fatal_error("Cannot lower a call to a non-intrinsic function '"+ 349 Callee->getName() + "'!"); 350 default: 351 report_fatal_error("Code generator does not support intrinsic function '"+ 352 Callee->getName()+"'!"); 353 354 // The setjmp/longjmp intrinsics should only exist in the code if it was 355 // never optimized (ie, right out of the CFE), or if it has been hacked on 356 // by the lowerinvoke pass. In both cases, the right thing to do is to 357 // convert the call to an explicit setjmp or longjmp call. 358 case Intrinsic::setjmp: { |
356 Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin() + 1, CI->op_end(), | 359 Value *V = ReplaceCallWith("setjmp", CI, CS.arg_begin(), CS.arg_end(), |
357 Type::getInt32Ty(Context)); 358 if (!CI->getType()->isVoidTy()) 359 CI->replaceAllUsesWith(V); 360 break; 361 } 362 case Intrinsic::sigsetjmp: 363 if (!CI->getType()->isVoidTy()) 364 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 365 break; 366 367 case Intrinsic::longjmp: { | 360 Type::getInt32Ty(Context)); 361 if (!CI->getType()->isVoidTy()) 362 CI->replaceAllUsesWith(V); 363 break; 364 } 365 case Intrinsic::sigsetjmp: 366 if (!CI->getType()->isVoidTy()) 367 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 368 break; 369 370 case Intrinsic::longjmp: { |
368 ReplaceCallWith("longjmp", CI, CI->op_begin() + 1, CI->op_end(), | 371 ReplaceCallWith("longjmp", CI, CS.arg_begin(), CS.arg_end(), |
369 Type::getVoidTy(Context)); 370 break; 371 } 372 373 case Intrinsic::siglongjmp: { 374 // Insert the call to abort | 372 Type::getVoidTy(Context)); 373 break; 374 } 375 376 case Intrinsic::siglongjmp: { 377 // Insert the call to abort |
375 ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(), | 378 ReplaceCallWith("abort", CI, CS.arg_end(), CS.arg_end(), |
376 Type::getVoidTy(Context)); 377 break; 378 } 379 case Intrinsic::ctpop: | 379 Type::getVoidTy(Context)); 380 break; 381 } 382 case Intrinsic::ctpop: |
380 CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getOperand(1), CI)); | 383 CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getArgOperand(0), CI)); |
381 break; 382 383 case Intrinsic::bswap: | 384 break; 385 386 case Intrinsic::bswap: |
384 CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getOperand(1), CI)); | 387 CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getArgOperand(0), CI)); |
385 break; 386 387 case Intrinsic::ctlz: | 388 break; 389 390 case Intrinsic::ctlz: |
388 CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getOperand(1), CI)); | 391 CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getArgOperand(0), CI)); |
389 break; 390 391 case Intrinsic::cttz: { 392 // cttz(x) -> ctpop(~X & (X-1)) | 392 break; 393 394 case Intrinsic::cttz: { 395 // cttz(x) -> ctpop(~X & (X-1)) |
393 Value *Src = CI->getOperand(1); | 396 Value *Src = CI->getArgOperand(0); |
394 Value *NotSrc = Builder.CreateNot(Src); 395 NotSrc->setName(Src->getName() + ".not"); 396 Value *SrcM1 = ConstantInt::get(Src->getType(), 1); 397 SrcM1 = Builder.CreateSub(Src, SrcM1); 398 Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); 399 CI->replaceAllUsesWith(Src); 400 break; 401 } --- 44 unchanged lines hidden (view full) --- 446 CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 447 break; 448 449 case Intrinsic::var_annotation: 450 break; // Strip out annotate intrinsic 451 452 case Intrinsic::memcpy: { 453 const IntegerType *IntPtr = TD.getIntPtrType(Context); | 397 Value *NotSrc = Builder.CreateNot(Src); 398 NotSrc->setName(Src->getName() + ".not"); 399 Value *SrcM1 = ConstantInt::get(Src->getType(), 1); 400 SrcM1 = Builder.CreateSub(Src, SrcM1); 401 Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); 402 CI->replaceAllUsesWith(Src); 403 break; 404 } --- 44 unchanged lines hidden (view full) --- 449 CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 450 break; 451 452 case Intrinsic::var_annotation: 453 break; // Strip out annotate intrinsic 454 455 case Intrinsic::memcpy: { 456 const IntegerType *IntPtr = TD.getIntPtrType(Context); |
454 Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr, | 457 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, |
455 /* isSigned */ false); 456 Value *Ops[3]; | 458 /* isSigned */ false); 459 Value *Ops[3]; |
457 Ops[0] = CI->getOperand(1); 458 Ops[1] = CI->getOperand(2); | 460 Ops[0] = CI->getArgOperand(0); 461 Ops[1] = CI->getArgOperand(1); |
459 Ops[2] = Size; | 462 Ops[2] = Size; |
460 ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getOperand(1)->getType()); | 463 ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); |
461 break; 462 } 463 case Intrinsic::memmove: { 464 const IntegerType *IntPtr = TD.getIntPtrType(Context); | 464 break; 465 } 466 case Intrinsic::memmove: { 467 const IntegerType *IntPtr = TD.getIntPtrType(Context); |
465 Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr, | 468 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, |
466 /* isSigned */ false); 467 Value *Ops[3]; | 469 /* isSigned */ false); 470 Value *Ops[3]; |
468 Ops[0] = CI->getOperand(1); 469 Ops[1] = CI->getOperand(2); | 471 Ops[0] = CI->getArgOperand(0); 472 Ops[1] = CI->getArgOperand(1); |
470 Ops[2] = Size; | 473 Ops[2] = Size; |
471 ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getOperand(1)->getType()); | 474 ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); |
472 break; 473 } 474 case Intrinsic::memset: { 475 const IntegerType *IntPtr = TD.getIntPtrType(Context); | 475 break; 476 } 477 case Intrinsic::memset: { 478 const IntegerType *IntPtr = TD.getIntPtrType(Context); |
476 Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr, | 479 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, |
477 /* isSigned */ false); 478 Value *Ops[3]; | 480 /* isSigned */ false); 481 Value *Ops[3]; |
479 Ops[0] = CI->getOperand(1); | 482 Ops[0] = CI->getArgOperand(0); |
480 // Extend the amount to i32. | 483 // Extend the amount to i32. |
481 Ops[1] = Builder.CreateIntCast(CI->getOperand(2), Type::getInt32Ty(Context), | 484 Ops[1] = Builder.CreateIntCast(CI->getArgOperand(1), Type::getInt32Ty(Context), |
482 /* isSigned */ false); 483 Ops[2] = Size; | 485 /* isSigned */ false); 486 Ops[2] = Size; |
484 ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getOperand(1)->getType()); | 487 ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); |
485 break; 486 } 487 case Intrinsic::sqrt: { 488 ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); 489 break; 490 } 491 case Intrinsic::log: { 492 ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); --- 42 unchanged lines hidden --- | 488 break; 489 } 490 case Intrinsic::sqrt: { 491 ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); 492 break; 493 } 494 case Intrinsic::log: { 495 ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); --- 42 unchanged lines hidden --- |