1*0b57cec5SDimitry Andric //===-- MakeGuardsExplicit.h - Turn guard intrinsics into guard branches --===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This pass lowers the @llvm.experimental.guard intrinsic to the new form of 10*0b57cec5SDimitry Andric // guard represented as widenable explicit branch to the deopt block. The 11*0b57cec5SDimitry Andric // difference between this pass and LowerGuardIntrinsic is that after this pass 12*0b57cec5SDimitry Andric // the guard represented as intrinsic: 13*0b57cec5SDimitry Andric // 14*0b57cec5SDimitry Andric // call void(i1, ...) @llvm.experimental.guard(i1 %old_cond) [ "deopt"() ] 15*0b57cec5SDimitry Andric // 16*0b57cec5SDimitry Andric // transforms to a guard represented as widenable explicit branch: 17*0b57cec5SDimitry Andric // 18*0b57cec5SDimitry Andric // %widenable_cond = call i1 @llvm.experimental.widenable.condition() 19*0b57cec5SDimitry Andric // br i1 (%old_cond & %widenable_cond), label %guarded, label %deopt 20*0b57cec5SDimitry Andric // 21*0b57cec5SDimitry Andric // Here: 22*0b57cec5SDimitry Andric // - The semantics of @llvm.experimental.widenable.condition allows to replace 23*0b57cec5SDimitry Andric // %widenable_cond with the construction (%widenable_cond & %any_other_cond) 24*0b57cec5SDimitry Andric // without loss of correctness; 25*0b57cec5SDimitry Andric // - %guarded is the lower part of old guard intrinsic's parent block split by 26*0b57cec5SDimitry Andric // the intrinsic call; 27*0b57cec5SDimitry Andric // - %deopt is a block containing a sole call to @llvm.experimental.deoptimize 28*0b57cec5SDimitry Andric // intrinsic. 29*0b57cec5SDimitry Andric // 30*0b57cec5SDimitry Andric // Therefore, this branch preserves the property of widenability. 31*0b57cec5SDimitry Andric // 32*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 33*0b57cec5SDimitry Andric #ifndef LLVM_TRANSFORMS_SCALAR_MAKEGUARDSEXPLICIT_H 34*0b57cec5SDimitry Andric #define LLVM_TRANSFORMS_SCALAR_MAKEGUARDSEXPLICIT_H 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric #include "llvm/IR/PassManager.h" 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric namespace llvm { 39*0b57cec5SDimitry Andric 40*0b57cec5SDimitry Andric struct MakeGuardsExplicitPass : public PassInfoMixin<MakeGuardsExplicitPass> { 41*0b57cec5SDimitry Andric PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 42*0b57cec5SDimitry Andric }; 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric } // namespace llvm 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric #endif // LLVM_TRANSFORMS_SCALAR_MAKEGUARDSEXPLICIT_H 47