Skip to content

Commit 885b758

Browse files
committed
IRGen: throws prediction for non-SIL calls
Some calls to throwing functions aren't represented with `try_apply` in SIL, so we generate llvm.expect's when throw prediction is enabled.
1 parent 0cce602 commit 885b758

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

lib/IRGen/GenThunk.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,12 @@ void IRGenThunk::emit() {
357357
llvm::Value *nil = llvm::ConstantPointerNull::get(
358358
cast<llvm::PointerType>(errorValue->getType()));
359359
auto *hasError = IGF.Builder.CreateICmpNE(errorValue, nil);
360+
361+
// Predict no error is thrown.
362+
hasError =
363+
IGF.IGM.getSILModule().getOptions().EnableThrowsPrediction ?
364+
IGF.Builder.CreateExpectCond(IGF.IGM, hasError, false) : hasError;
365+
360366
IGF.Builder.CreateCondBr(hasError, errorBB, successBB);
361367

362368
IGF.Builder.emitBlock(errorBB);

lib/IRGen/IRBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,11 @@ class IRBuilder : public IRBuilderBase {
410410
name);
411411
}
412412

413+
// Creates an @llvm.expect.i1 call, where the value should be an i1 type.
414+
llvm::CallInst *CreateExpectCond(IRGenModule &IGM,
415+
llvm::Value *value,
416+
bool expectedValue, const Twine &name = "");
417+
413418
/// Call the trap intrinsic. If optimizations are enabled, an inline asm
414419
/// gadget is emitted before the trap. The gadget inhibits transforms which
415420
/// merge trap calls together, which makes debugging crashes easier.

lib/IRGen/IRGenFunction.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,14 @@ Address IRGenFunction::emitAddressAtOffset(llvm::Value *base, Offset offset,
446446
return Address(slotPtr, objectTy, objectAlignment);
447447
}
448448

449+
llvm::CallInst *IRBuilder::CreateExpectCond(IRGenModule &IGM,
450+
llvm::Value *value,
451+
bool expectedValue,
452+
const Twine &name) {
453+
unsigned flag = expectedValue ? 1 : 0;
454+
return CreateExpect(value, llvm::ConstantInt::get(IGM.Int1Ty, flag), name);
455+
}
456+
449457
llvm::CallInst *IRBuilder::CreateNonMergeableTrap(IRGenModule &IGM,
450458
StringRef failureMsg) {
451459
if (IGM.DebugInfo && IGM.getOptions().isDebugInfoCodeView()) {
@@ -777,6 +785,12 @@ void IRGenFunction::emitAwaitAsyncContinuation(
777785
auto nullError = llvm::Constant::getNullValue(errorRes->getType());
778786
auto hasError = Builder.CreateICmpNE(errorRes, nullError);
779787
optionalErrorResult->addIncoming(errorRes, Builder.GetInsertBlock());
788+
789+
// Predict no error.
790+
hasError =
791+
getSILModule().getOptions().EnableThrowsPrediction ?
792+
Builder.CreateExpectCond(IGM, hasError, false) : hasError;
793+
780794
Builder.CreateCondBr(hasError, optionalErrorBB, normalContBB);
781795
Builder.emitBlock(normalContBB);
782796
}

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4636,6 +4636,12 @@ void IRGenSILFunction::visitYieldInst(swift::YieldInst *i) {
46364636
// Branch to the appropriate destination.
46374637
auto unwindBB = getLoweredBB(i->getUnwindBB()).bb;
46384638
auto resumeBB = getLoweredBB(i->getResumeBB()).bb;
4639+
4640+
// Predict no unwind happens.
4641+
isUnwind =
4642+
IGM.getSILModule().getOptions().EnableThrowsPrediction ?
4643+
Builder.CreateExpectCond(IGM, isUnwind, false) : isUnwind;
4644+
46394645
Builder.CreateCondBr(isUnwind, unwindBB, resumeBB);
46404646
}
46414647

0 commit comments

Comments
 (0)