[llvm] r211735 - [FastISel][X86] Refactor XALU folding. NFC.
Eric Christopher
echristo at gmail.com
Wed Jun 25 15:46:03 PDT 2014
Thanks!
-eric
On Wed, Jun 25, 2014 at 3:17 PM, Juergen Ributzka <juergen at apple.com> wrote:
> Author: ributzka
> Date: Wed Jun 25 17:17:23 2014
> New Revision: 211735
>
> URL: http://llvm.org/viewvc/llvm-project?rev=211735&view=rev
> Log:
> [FastISel][X86] Refactor XALU folding. NFC.
>
> Modified:
> llvm/trunk/lib/Target/X86/X86FastISel.cpp
>
> Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=211735&r1=211734&r2=211735&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Jun 25 17:17:23 2014
> @@ -157,6 +157,9 @@ private:
>
> bool TryEmitSmallMemcpy(X86AddressMode DestAM,
> X86AddressMode SrcAM, uint64_t Len);
> +
> + std::pair<bool, X86::CondCode>
> + foldX86XALUIntrinsic(const Instruction *I, const Value *Cond);
> };
>
> } // end anonymous namespace.
> @@ -274,6 +277,61 @@ getX86SSECondtionCode(CmpInst::Predicate
> return std::make_pair(CC, NeedSwap);
> }
>
> +/// \brief Check if it is possible to fold the condition from the XALU intrinsic
> +/// into the user.
> +std::pair<bool, X86::CondCode>
> +X86FastISel::foldX86XALUIntrinsic(const Instruction *I, const Value *Cond) {
> + if (!isa<ExtractValueInst>(Cond))
> + return std::make_pair(false, X86::COND_INVALID);
> +
> + const auto *EV = cast<ExtractValueInst>(Cond);
> + if (!isa<IntrinsicInst>(EV->getAggregateOperand()))
> + return std::make_pair(false, X86::COND_INVALID);
> +
> + const auto *II = cast<IntrinsicInst>(EV->getAggregateOperand());
> + MVT RetVT;
> + const Function *Callee = II->getCalledFunction();
> + Type *RetTy =
> + cast<StructType>(Callee->getReturnType())->getTypeAtIndex(0U);
> + if (!isTypeLegal(RetTy, RetVT))
> + return std::make_pair(false, X86::COND_INVALID);
> +
> + if (RetVT != MVT::i32 && RetVT != MVT::i64)
> + return std::make_pair(false, X86::COND_INVALID);
> +
> + X86::CondCode CC;
> + switch (II->getIntrinsicID()) {
> + default: return std::make_pair(false, X86::COND_INVALID);
> + case Intrinsic::sadd_with_overflow:
> + case Intrinsic::ssub_with_overflow:
> + case Intrinsic::smul_with_overflow:
> + case Intrinsic::umul_with_overflow: CC = X86::COND_O; break;
> + case Intrinsic::uadd_with_overflow:
> + case Intrinsic::usub_with_overflow: CC = X86::COND_B; break;
> + }
> +
> + // Check if both instructions are in the same basic block.
> + if (II->getParent() != I->getParent())
> + return std::make_pair(false, X86::COND_INVALID);
> +
> + // Make sure nothing is in the way
> + BasicBlock::const_iterator Start = I;
> + BasicBlock::const_iterator End = II;
> + for (auto Itr = std::prev(Start); Itr != End; --Itr) {
> + // We only expect extractvalue instructions between the intrinsic and the
> + // instruction to be selected.
> + if (!isa<ExtractValueInst>(Itr))
> + return std::make_pair(false, X86::COND_INVALID);
> +
> + // Check that the extractvalue operand comes from the intrinsic.
> + const auto *EVI = cast<ExtractValueInst>(Itr);
> + if (EVI->getAggregateOperand() != II)
> + return std::make_pair(false, X86::COND_INVALID);
> + }
> +
> + return std::make_pair(true, CC);
> +}
> +
> bool X86FastISel::isTypeLegal(Type *Ty, MVT &VT, bool AllowI1) {
> EVT evt = TLI.getValueType(Ty, /*HandleUnknown=*/true);
> if (evt == MVT::Other || !evt.isSimple())
> @@ -1398,73 +1456,18 @@ bool X86FastISel::X86SelectBranch(const
> return true;
> }
> }
> - } else if (auto *EV = dyn_cast<ExtractValueInst>(BI->getCondition())) {
> - bool FoldIntrinsic = false;
> - if (const auto *II = dyn_cast<IntrinsicInst>(EV->getAggregateOperand())) {
> - switch (II->getIntrinsicID()) {
> - default: break;
> - case Intrinsic::sadd_with_overflow:
> - case Intrinsic::uadd_with_overflow:
> - case Intrinsic::ssub_with_overflow:
> - case Intrinsic::usub_with_overflow:
> - case Intrinsic::smul_with_overflow:
> - case Intrinsic::umul_with_overflow: FoldIntrinsic = true; break;
> - }
> -
> - // Check if both instructions are in the same basic block.
> - if (FoldIntrinsic && (II->getParent() != I->getParent()))
> - FoldIntrinsic = false;
> -
> - // Make sure nothing is in the way
> - if (FoldIntrinsic) {
> - BasicBlock::const_iterator Start = I;
> - BasicBlock::const_iterator End = II;
> - for (auto Itr = std::prev(Start); Itr != End; --Itr) {
> - // We only expect extractvalue instructions between the intrinsic and
> - // the branch.
> - if (!isa<ExtractValueInst>(Itr)) {
> - FoldIntrinsic = false;
> - break;
> - }
> -
> - // Check that the extractvalue operand comes from the intrinsic.
> - const auto *EVI = cast<ExtractValueInst>(Itr);
> - if (EVI->getAggregateOperand() != II) {
> - FoldIntrinsic = false;
> - break;
> - }
> - }
> - }
> - }
> -
> + } else {
> + bool FoldIntrinsic;
> + X86::CondCode CC;
> + std::tie(FoldIntrinsic, CC) = foldX86XALUIntrinsic(BI, BI->getCondition());
> if (FoldIntrinsic) {
> - MVT RetVT;
> - const IntrinsicInst *II = cast<IntrinsicInst>(EV->getAggregateOperand());
> - const Function *Callee = II->getCalledFunction();
> - Type *RetTy =
> - cast<StructType>(Callee->getReturnType())->getTypeAtIndex(0U);
> - if (!isTypeLegal(RetTy, RetVT))
> - return false;
> -
> - if (RetVT != MVT::i32 && RetVT != MVT::i64)
> - return false;
> -
> // Fake request the condition, otherwise the intrinsic might be completely
> // optimized away.
> - unsigned TmpReg = getRegForValue(EV);
> + unsigned TmpReg = getRegForValue(BI->getCondition());
> if (TmpReg == 0)
> return false;
>
> - unsigned BranchOpc = 0;
> - switch (II->getIntrinsicID()) {
> - default: llvm_unreachable("Unexpected intrinsic instruction.");
> - case Intrinsic::sadd_with_overflow:
> - case Intrinsic::ssub_with_overflow:
> - case Intrinsic::smul_with_overflow:
> - case Intrinsic::umul_with_overflow: BranchOpc = X86::JO_4; break;
> - case Intrinsic::uadd_with_overflow:
> - case Intrinsic::usub_with_overflow: BranchOpc = X86::JB_4; break;
> - }
> + unsigned BranchOpc = X86::GetCondBranchFromCond(CC);
>
> BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(BranchOpc))
> .addMBB(TrueMBB);
> @@ -1813,76 +1816,19 @@ bool X86FastISel::X86FastEmitCMoveSelect
> }
> }
> NeedTest = false;
> - } else if (auto *EV = dyn_cast<ExtractValueInst>(Cond)) {
> - bool FoldIntrinsic = false;
> - if (const auto *II = dyn_cast<IntrinsicInst>(EV->getAggregateOperand())) {
> - switch (II->getIntrinsicID()) {
> - default: break;
> - case Intrinsic::sadd_with_overflow:
> - case Intrinsic::uadd_with_overflow:
> - case Intrinsic::ssub_with_overflow:
> - case Intrinsic::usub_with_overflow:
> - case Intrinsic::smul_with_overflow:
> - case Intrinsic::umul_with_overflow: FoldIntrinsic = true; break;
> - }
> -
> - // Check if both instructions are in the same basic block.
> - if (FoldIntrinsic && (II->getParent() != I->getParent()))
> - FoldIntrinsic = false;
> -
> - // Make sure nothing is in the way
> - if (FoldIntrinsic) {
> - BasicBlock::const_iterator Start = I;
> - BasicBlock::const_iterator End = II;
> - for (auto Itr = std::prev(Start); Itr != End; --Itr) {
> - // We only expect extractvalue instructions between the intrinsic and
> - // the branch.
> - if (!isa<ExtractValueInst>(Itr)) {
> - FoldIntrinsic = false;
> - break;
> - }
> -
> - // Check that the extractvalue operand comes from the intrinsic.
> - const auto *EVI = cast<ExtractValueInst>(Itr);
> - if (EVI->getAggregateOperand() != II) {
> - FoldIntrinsic = false;
> - break;
> - }
> - }
> - }
> - }
> + } else {
> + bool FoldIntrinsic;
> + X86::CondCode CC;
> + std::tie(FoldIntrinsic, CC) = foldX86XALUIntrinsic(I, Cond);
>
> if (FoldIntrinsic) {
> - MVT RetVT;
> - const IntrinsicInst *II = cast<IntrinsicInst>(EV->getAggregateOperand());
> - const Function *Callee = II->getCalledFunction();
> - Type *RetTy =
> - cast<StructType>(Callee->getReturnType())->getTypeAtIndex(0U);
> - if (!isTypeLegal(RetTy, RetVT))
> - return false;
> -
> - if (RetVT != MVT::i32 && RetVT != MVT::i64)
> - return false;
> -
> // Fake request the condition, otherwise the intrinsic might be completely
> // optimized away.
> - unsigned TmpReg = getRegForValue(EV);
> + unsigned TmpReg = getRegForValue(Cond);
> if (TmpReg == 0)
> return false;
>
> - switch (II->getIntrinsicID()) {
> - default: llvm_unreachable("Unexpected intrinsic instruction.");
> - case Intrinsic::sadd_with_overflow:
> - case Intrinsic::ssub_with_overflow:
> - case Intrinsic::smul_with_overflow:
> - case Intrinsic::umul_with_overflow:
> - Opc = X86::getCMovFromCond(X86::COND_O, RC->getSize());
> - break;
> - case Intrinsic::uadd_with_overflow:
> - case Intrinsic::usub_with_overflow:
> - Opc = X86::getCMovFromCond(X86::COND_B, RC->getSize());
> - break;
> - }
> + Opc = X86::getCMovFromCond(CC, RC->getSize());
> NeedTest = false;
> }
> }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list