Changeset View
Changeset View
Standalone View
Standalone View
lib/CodeGen/CGBuiltin.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 766 Lines • ▼ Show 20 Line(s) | 749 | for (const auto &Item : Layout.Items) { | |||
---|---|---|---|---|---|
767 | ++I; | 767 | ++I; | ||
768 | } | 768 | } | ||
769 | 769 | | |||
770 | FinishFunction(); | 770 | FinishFunction(); | ||
771 | 771 | | |||
772 | return Fn; | 772 | return Fn; | ||
773 | } | 773 | } | ||
774 | 774 | | |||
775 | /// @brief Utility to insert expansion for __builtin_load_no_speculate for | ||||
776 | /// targets than don't support llvm.nospeculateload. Expand | ||||
777 | /// __builtin_load_no_speculate(ptr, lower, upper, failval, cmpptr) | ||||
778 | /// to a call to: | ||||
779 | /// inline TYP __builtin_load_no_speculate | ||||
780 | /// (const volatile TYP *ptr, | ||||
781 | /// const volatile void *lower, | ||||
782 | /// const volatile void *upper, | ||||
783 | /// TYP failval, | ||||
784 | /// const volatile void *cmpptr) | ||||
785 | /// { | ||||
786 | /// TYP result; | ||||
787 | /// if (cmpptr >= lower && cmpptr < upper) | ||||
788 | /// result = *ptr; | ||||
789 | /// else | ||||
790 | /// result = failval; | ||||
791 | /// return result; | ||||
792 | /// } | ||||
793 | /// | ||||
794 | static Value *MakeBuiltinLoadNoSpeculate(CodeGenFunction &CGF, Value *Ptr, | ||||
795 | Value *LowerBound, Value *UpperBound, | ||||
796 | Value *FailVal, Value *CmpPtr, | ||||
797 | clang::QualType ResultType) { | ||||
798 | Value *LowerBoundCmp = nullptr; | ||||
799 | Value *UpperBoundCmp = nullptr; | ||||
800 | Value *Condition = nullptr; | ||||
801 | if (LowerBound) | ||||
802 | LowerBoundCmp = CGF.Builder.CreateICmp(llvm::CmpInst::ICMP_UGE, CmpPtr, | ||||
803 | LowerBound, "cmplower"); | ||||
804 | if (UpperBound) | ||||
805 | UpperBoundCmp = CGF.Builder.CreateICmp(llvm::CmpInst::ICMP_ULT, CmpPtr, | ||||
806 | UpperBound, "cmpupper"); | ||||
807 | if (LowerBoundCmp && UpperBoundCmp) | ||||
808 | Condition = CGF.Builder.CreateAnd(LowerBoundCmp, UpperBoundCmp, "cond"); | ||||
809 | else if (LowerBoundCmp) | ||||
810 | Condition = LowerBoundCmp; | ||||
811 | else { | ||||
812 | assert(UpperBoundCmp != nullptr); | ||||
813 | Condition = UpperBoundCmp; | ||||
814 | } | ||||
815 | | ||||
816 | llvm::BasicBlock *InitialBB = CGF.Builder.GetInsertBlock(); | ||||
817 | llvm::BasicBlock *InBoundsBB = | ||||
818 | CGF.createBasicBlock("inBoundsBB", CGF.CurFn, InitialBB->getNextNode()); | ||||
819 | llvm::BasicBlock *NextBB = | ||||
820 | CGF.createBasicBlock("loadnospecJoinBB", CGF.CurFn, | ||||
821 | InBoundsBB->getNextNode()); | ||||
822 | | ||||
823 | CGF.Builder.CreateCondBr(Condition, InBoundsBB, NextBB); | ||||
824 | | ||||
825 | CGF.Builder.SetInsertPoint(InBoundsBB); | ||||
826 | Address PtrAddress(Ptr, | ||||
827 | CGF.getContext().getTypeAlignInChars(ResultType)); | ||||
828 | Value *PtrDeref = | ||||
829 | CGF.Builder.CreateLoad(PtrAddress, true /*IsVolatile*/, "PtrDeref"); | ||||
830 | CGF.Builder.CreateBr(NextBB); | ||||
831 | | ||||
832 | CGF.Builder.SetInsertPoint(NextBB); | ||||
833 | llvm::PHINode *Phi = | ||||
834 | CGF.Builder.CreatePHI(FailVal->getType(), 2, "load_no_speculate_res"); | ||||
835 | Phi->addIncoming(PtrDeref, InBoundsBB); | ||||
836 | Phi->addIncoming(FailVal, InitialBB); | ||||
837 | | ||||
838 | return Phi; | ||||
839 | } | ||||
840 | | ||||
841 | | ||||
775 | RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { | 842 | RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { | ||
776 | assert(E.getNumArgs() >= 2 && | 843 | assert(E.getNumArgs() >= 2 && | ||
777 | "__builtin_os_log_format takes at least 2 arguments"); | 844 | "__builtin_os_log_format takes at least 2 arguments"); | ||
778 | ASTContext &Ctx = getContext(); | 845 | ASTContext &Ctx = getContext(); | ||
779 | analyze_os_log::OSLogBufferLayout Layout; | 846 | analyze_os_log::OSLogBufferLayout Layout; | ||
780 | analyze_os_log::computeOSLogBufferLayout(Ctx, &E, Layout); | 847 | analyze_os_log::computeOSLogBufferLayout(Ctx, &E, Layout); | ||
781 | Address BufAddr = EmitPointerWithAlignment(E.getArg(0)); | 848 | Address BufAddr = EmitPointerWithAlignment(E.getArg(0)); | ||
782 | llvm::SmallVector<llvm::Value *, 4> RetainableOperands; | 849 | llvm::SmallVector<llvm::Value *, 4> RetainableOperands; | ||
▲ Show 20 Lines • Show All 2440 Lines • ▼ Show 20 Line(s) | 3278 | case Builtin::BI__builtin_ms_va_copy: { | |||
3223 | DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"), | 3290 | DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"), | ||
3224 | DestAddr.getAlignment()); | 3291 | DestAddr.getAlignment()); | ||
3225 | SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"), | 3292 | SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"), | ||
3226 | SrcAddr.getAlignment()); | 3293 | SrcAddr.getAlignment()); | ||
3227 | 3294 | | |||
3228 | Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val"); | 3295 | Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val"); | ||
3229 | return RValue::get(Builder.CreateStore(ArgPtr, DestAddr)); | 3296 | return RValue::get(Builder.CreateStore(ArgPtr, DestAddr)); | ||
3230 | } | 3297 | } | ||
3298 | case Builtin::BI__builtin_load_no_speculate: { | ||||
3299 | Value *Ptr = EmitScalarExpr(E->getArg(0)); | ||||
3300 | | ||||
3301 | bool LowerBoundNull = | ||||
3302 | E->getArg(1)->IgnoreParenCasts()->isNullPointerConstant( | ||||
3303 | getContext(), Expr::NPC_ValueDependentIsNotNull); | ||||
3304 | bool UpperBoundNull = | ||||
3305 | E->getArg(2)->IgnoreParenCasts()->isNullPointerConstant( | ||||
3306 | getContext(), Expr::NPC_ValueDependentIsNotNull); | ||||
3307 | | ||||
3308 | assert((!LowerBoundNull || !UpperBoundNull) && | ||||
3309 | "at least one bound must be non-null!"); | ||||
3310 | | ||||
3311 | Value *LowerBound = LowerBoundNull ? nullptr : EmitScalarExpr(E->getArg(1)); | ||||
3312 | Value *UpperBound = UpperBoundNull ? nullptr : EmitScalarExpr(E->getArg(2)); | ||||
3313 | | ||||
3314 | llvm::Type *T = ConvertType(E->getType()); | ||||
3315 | assert((isa<llvm::IntegerType>(T) || isa<llvm::PointerType>(T)) && | ||||
3316 | "unsupported type"); | ||||
3317 | | ||||
3318 | if (isa<llvm::IntegerType>(T)) { | ||||
3319 | CharUnits LoadSize = getContext().getTypeSizeInChars(E->getType()); | ||||
3320 | T = llvm::IntegerType::get(getLLVMContext(), LoadSize.getQuantity() * 8); | ||||
3321 | Ptr = Builder.CreateBitCast(Ptr, T->getPointerTo()); | ||||
3322 | } | ||||
3323 | | ||||
3324 | // If failval is omitted, zero of the appropriate type will be used. | ||||
3325 | Value *FailVal = nullptr; | ||||
3326 | if (E->getNumArgs() >= 4) { | ||||
3327 | FailVal = EmitScalarExpr(E->getArg(3)); | ||||
3328 | if (T != FailVal->getType()) { | ||||
3329 | assert(T->getScalarSizeInBits() > | ||||
3330 | FailVal->getType()->getScalarSizeInBits()); | ||||
3331 | FailVal = Builder.CreateZExt(FailVal, T); | ||||
3332 | } | ||||
3333 | } else { | ||||
3334 | if (isa<llvm::IntegerType>(T)) { | ||||
3335 | FailVal = llvm::ConstantInt::get(T, 0); | ||||
3336 | } else if (isa<llvm::PointerType>(T)) { | ||||
3337 | FailVal = llvm::ConstantPointerNull::get(cast<llvm::PointerType>(T)); | ||||
3338 | } | ||||
3339 | } | ||||
3340 | assert(FailVal && "default FailVal not set"); | ||||
3341 | | ||||
3342 | // If cmpptr is omitted, ptr will be used. | ||||
3343 | Value *CmpPtr = (E->getNumArgs() >= 5) ? EmitScalarExpr(E->getArg(4)) : Ptr; | ||||
3344 | CmpPtr = Builder.CreateBitCast(CmpPtr, Builder.getInt8PtrTy()); | ||||
3345 | | ||||
3346 | if (!getContext().getTargetInfo().hasBuiltinLoadNoSpeculate()) | ||||
3347 | return RValue::get(MakeBuiltinLoadNoSpeculate( | ||||
3348 | *this, Ptr, LowerBound, UpperBound, FailVal, CmpPtr, | ||||
3349 | E->getType())); | ||||
3350 | else if (LowerBoundNull) | ||||
3351 | return RValue::get(Builder.CreateCall( | ||||
3352 | CGM.getIntrinsic(Intrinsic::nospeculateload_nolower, T), | ||||
3353 | {Ptr, UpperBound, FailVal, CmpPtr})); | ||||
3354 | else if (UpperBoundNull) | ||||
3355 | return RValue::get(Builder.CreateCall( | ||||
3356 | CGM.getIntrinsic(Intrinsic::nospeculateload_noupper, T), | ||||
3357 | {Ptr, LowerBound, FailVal, CmpPtr})); | ||||
3358 | else | ||||
3359 | return RValue::get( | ||||
3360 | Builder.CreateCall(CGM.getIntrinsic(Intrinsic::nospeculateload, T), | ||||
3361 | {Ptr, LowerBound, UpperBound, FailVal, CmpPtr})); | ||||
3362 | } | ||||
3231 | } | 3363 | } | ||
3232 | 3364 | | |||
3233 | // If this is an alias for a lib function (e.g. __builtin_sin), emit | 3365 | // If this is an alias for a lib function (e.g. __builtin_sin), emit | ||
3234 | // the call using the normal call path, but using the unmangled | 3366 | // the call using the normal call path, but using the unmangled | ||
3235 | // version of the function name. | 3367 | // version of the function name. | ||
3236 | if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) | 3368 | if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) | ||
3237 | return emitLibraryCall(*this, FD, E, | 3369 | return emitLibraryCall(*this, FD, E, | ||
3238 | CGM.getBuiltinLibFunction(FD, BuiltinID)); | 3370 | CGM.getBuiltinLibFunction(FD, BuiltinID)); | ||
▲ Show 20 Lines • Show All 7079 Lines • Show Last 20 Lines |