| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
| (...skipping 2589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2600 if (Var->hasReg()) | 2600 if (Var->hasReg()) |
| 2601 IsSrc1ImmOrReg = true; | 2601 IsSrc1ImmOrReg = true; |
| 2602 } | 2602 } |
| 2603 | 2603 |
| 2604 // Try to fuse a compare immediately followed by a conditional branch. This | 2604 // Try to fuse a compare immediately followed by a conditional branch. This |
| 2605 // is possible when the compare dest and the branch source operands are the | 2605 // is possible when the compare dest and the branch source operands are the |
| 2606 // same, and are their only uses. TODO: implement this optimization for i64. | 2606 // same, and are their only uses. TODO: implement this optimization for i64. |
| 2607 if (InstBr *NextBr = llvm::dyn_cast_or_null<InstBr>(Context.getNextInst())) { | 2607 if (InstBr *NextBr = llvm::dyn_cast_or_null<InstBr>(Context.getNextInst())) { |
| 2608 if (Src0->getType() != IceType_i64 && !NextBr->isUnconditional() && | 2608 if (Src0->getType() != IceType_i64 && !NextBr->isUnconditional() && |
| 2609 Dest == NextBr->getSrc(0) && NextBr->isLastUse(Dest)) { | 2609 Dest == NextBr->getSrc(0) && NextBr->isLastUse(Dest)) { |
| 2610 NextBr->setDeleted(); |
| 2610 Operand *Src0RM = legalize( | 2611 Operand *Src0RM = legalize( |
| 2611 Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg, true); | 2612 Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg, true); |
| 2612 _cmp(Src0RM, Src1); | 2613 _cmp(Src0RM, Src1); |
| 2613 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), | 2614 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), |
| 2614 NextBr->getTargetFalse()); | 2615 NextBr->getTargetFalse()); |
| 2615 // Skip over the following branch instruction. | 2616 // Skip over the following branch instruction. |
| 2616 NextBr->setDeleted(); | |
| 2617 Context.advanceNext(); | 2617 Context.advanceNext(); |
| 2618 return; | 2618 return; |
| 2619 } | 2619 } |
| 2620 } | 2620 } |
| 2621 | 2621 |
| 2622 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: | 2622 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: |
| 2623 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 2623 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| 2624 Constant *One = Ctx->getConstantInt(IceType_i32, 1); | 2624 Constant *One = Ctx->getConstantInt(IceType_i32, 1); |
| 2625 if (Src0->getType() == IceType_i64) { | 2625 if (Src0->getType() == IceType_i64) { |
| 2626 InstIcmp::ICond Condition = Inst->getCondition(); | 2626 InstIcmp::ICond Condition = Inst->getCondition(); |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3187 return false; | 3187 return false; |
| 3188 if (InstBr *NextBr = llvm::dyn_cast<InstBr>(NextInst)) { | 3188 if (InstBr *NextBr = llvm::dyn_cast<InstBr>(NextInst)) { |
| 3189 if (!NextBr->isUnconditional() && | 3189 if (!NextBr->isUnconditional() && |
| 3190 NextCmp->getDest() == NextBr->getCondition() && | 3190 NextCmp->getDest() == NextBr->getCondition() && |
| 3191 NextBr->isLastUse(NextCmp->getDest())) { | 3191 NextBr->isLastUse(NextCmp->getDest())) { |
| 3192 lowerAtomicCmpxchg(Dest, PtrToMem, Expected, Desired); | 3192 lowerAtomicCmpxchg(Dest, PtrToMem, Expected, Desired); |
| 3193 for (size_t i = 0; i < PhiAssigns.size(); ++i) { | 3193 for (size_t i = 0; i < PhiAssigns.size(); ++i) { |
| 3194 // Lower the phi assignments now, before the branch (same placement | 3194 // Lower the phi assignments now, before the branch (same placement |
| 3195 // as before). | 3195 // as before). |
| 3196 InstAssign *PhiAssign = PhiAssigns[i]; | 3196 InstAssign *PhiAssign = PhiAssigns[i]; |
| 3197 PhiAssign->setDeleted(); |
| 3197 lowerAssign(PhiAssign); | 3198 lowerAssign(PhiAssign); |
| 3198 PhiAssign->setDeleted(); | |
| 3199 Context.advanceNext(); | 3199 Context.advanceNext(); |
| 3200 } | 3200 } |
| 3201 _br(InstX8632::Br_e, NextBr->getTargetTrue(), NextBr->getTargetFalse()); | 3201 _br(InstX8632::Br_e, NextBr->getTargetTrue(), NextBr->getTargetFalse()); |
| 3202 // Skip over the old compare and branch, by deleting them. | 3202 // Skip over the old compare and branch, by deleting them. |
| 3203 NextCmp->setDeleted(); | 3203 NextCmp->setDeleted(); |
| 3204 NextBr->setDeleted(); | 3204 NextBr->setDeleted(); |
| 3205 Context.advanceNext(); | 3205 Context.advanceNext(); |
| 3206 Context.advanceNext(); | 3206 Context.advanceNext(); |
| 3207 return true; | 3207 return true; |
| 3208 } | 3208 } |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3475 namespace { | 3475 namespace { |
| 3476 | 3476 |
| 3477 bool isAdd(const Inst *Inst) { | 3477 bool isAdd(const Inst *Inst) { |
| 3478 if (const InstArithmetic *Arith = | 3478 if (const InstArithmetic *Arith = |
| 3479 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { | 3479 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { |
| 3480 return (Arith->getOp() == InstArithmetic::Add); | 3480 return (Arith->getOp() == InstArithmetic::Add); |
| 3481 } | 3481 } |
| 3482 return false; | 3482 return false; |
| 3483 } | 3483 } |
| 3484 | 3484 |
| 3485 void computeAddressOpt(Variable *&Base, Variable *&Index, uint16_t &Shift, | 3485 void dumpAddressOpt(const Cfg *Func, const Variable *Base, |
| 3486 int32_t &Offset) { | 3486 const Variable *Index, uint16_t Shift, int32_t Offset, |
| 3487 const Inst *Reason) { |
| 3488 if (!Func->getContext()->isVerbose(IceV_AddrOpt)) |
| 3489 return; |
| 3490 Ostream &Str = Func->getContext()->getStrDump(); |
| 3491 Str << "Instruction: "; |
| 3492 Reason->dumpDecorated(Func); |
| 3493 Str << " results in Base="; |
| 3494 if (Base) |
| 3495 Base->dump(Func); |
| 3496 else |
| 3497 Str << "<null>"; |
| 3498 Str << ", Index="; |
| 3499 if (Index) |
| 3500 Index->dump(Func); |
| 3501 else |
| 3502 Str << "<null>"; |
| 3503 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; |
| 3504 } |
| 3505 |
| 3506 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, |
| 3507 Variable *&Index, uint16_t &Shift, int32_t &Offset) { |
| 3508 Func->setCurrentNode(NULL); |
| 3509 if (Func->getContext()->isVerbose(IceV_AddrOpt)) { |
| 3510 Ostream &Str = Func->getContext()->getStrDump(); |
| 3511 Str << "\nStarting computeAddressOpt for instruction:\n "; |
| 3512 Instr->dumpDecorated(Func); |
| 3513 } |
| 3487 (void)Offset; // TODO: pattern-match for non-zero offsets. | 3514 (void)Offset; // TODO: pattern-match for non-zero offsets. |
| 3488 if (Base == NULL) | 3515 if (Base == NULL) |
| 3489 return; | 3516 return; |
| 3490 // If the Base has more than one use or is live across multiple | 3517 // If the Base has more than one use or is live across multiple |
| 3491 // blocks, then don't go further. Alternatively (?), never consider | 3518 // blocks, then don't go further. Alternatively (?), never consider |
| 3492 // a transformation that would change a variable that is currently | 3519 // a transformation that would change a variable that is currently |
| 3493 // *not* live across basic block boundaries into one that *is*. | 3520 // *not* live across basic block boundaries into one that *is*. |
| 3494 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) | 3521 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) |
| 3495 return; | 3522 return; |
| 3496 | 3523 |
| 3497 while (true) { | 3524 while (true) { |
| 3498 // Base is Base=Var ==> | 3525 // Base is Base=Var ==> |
| 3499 // set Base=Var | 3526 // set Base=Var |
| 3500 const Inst *BaseInst = Base->getDefinition(); | 3527 const Inst *BaseInst = Base->getDefinition(); |
| 3501 Operand *BaseOperand0 = BaseInst ? BaseInst->getSrc(0) : NULL; | 3528 Operand *BaseOperand0 = BaseInst ? BaseInst->getSrc(0) : NULL; |
| 3502 Variable *BaseVariable0 = llvm::dyn_cast_or_null<Variable>(BaseOperand0); | 3529 Variable *BaseVariable0 = llvm::dyn_cast_or_null<Variable>(BaseOperand0); |
| 3503 // TODO: Helper function for all instances of assignment | 3530 // TODO: Helper function for all instances of assignment |
| 3504 // transitivity. | 3531 // transitivity. |
| 3505 if (BaseInst && llvm::isa<InstAssign>(BaseInst) && BaseVariable0 && | 3532 if (BaseInst && llvm::isa<InstAssign>(BaseInst) && BaseVariable0 && |
| 3506 // TODO: ensure BaseVariable0 stays single-BB | 3533 // TODO: ensure BaseVariable0 stays single-BB |
| 3507 true) { | 3534 true) { |
| 3508 Base = BaseVariable0; | 3535 Base = BaseVariable0; |
| 3536 dumpAddressOpt(Func, Base, Index, Shift, Offset, BaseInst); |
| 3509 continue; | 3537 continue; |
| 3510 } | 3538 } |
| 3511 | 3539 |
| 3512 // Index is Index=Var ==> | 3540 // Index is Index=Var ==> |
| 3513 // set Index=Var | 3541 // set Index=Var |
| 3514 | 3542 |
| 3515 // Index==NULL && Base is Base=Var1+Var2 ==> | 3543 // Index==NULL && Base is Base=Var1+Var2 ==> |
| 3516 // set Base=Var1, Index=Var2, Shift=0 | 3544 // set Base=Var1, Index=Var2, Shift=0 |
| 3517 Operand *BaseOperand1 = | 3545 Operand *BaseOperand1 = |
| 3518 BaseInst && BaseInst->getSrcSize() >= 2 ? BaseInst->getSrc(1) : NULL; | 3546 BaseInst && BaseInst->getSrcSize() >= 2 ? BaseInst->getSrc(1) : NULL; |
| 3519 Variable *BaseVariable1 = llvm::dyn_cast_or_null<Variable>(BaseOperand1); | 3547 Variable *BaseVariable1 = llvm::dyn_cast_or_null<Variable>(BaseOperand1); |
| 3520 if (Index == NULL && isAdd(BaseInst) && BaseVariable0 && BaseVariable1 && | 3548 if (Index == NULL && isAdd(BaseInst) && BaseVariable0 && BaseVariable1 && |
| 3521 // TODO: ensure BaseVariable0 and BaseVariable1 stay single-BB | 3549 // TODO: ensure BaseVariable0 and BaseVariable1 stay single-BB |
| 3522 true) { | 3550 true) { |
| 3523 Base = BaseVariable0; | 3551 Base = BaseVariable0; |
| 3524 Index = BaseVariable1; | 3552 Index = BaseVariable1; |
| 3525 Shift = 0; // should already have been 0 | 3553 Shift = 0; // should already have been 0 |
| 3554 dumpAddressOpt(Func, Base, Index, Shift, Offset, BaseInst); |
| 3526 continue; | 3555 continue; |
| 3527 } | 3556 } |
| 3528 | 3557 |
| 3529 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==> | 3558 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==> |
| 3530 // Index=Var, Shift+=log2(Const) | 3559 // Index=Var, Shift+=log2(Const) |
| 3531 const Inst *IndexInst = Index ? Index->getDefinition() : NULL; | 3560 const Inst *IndexInst = Index ? Index->getDefinition() : NULL; |
| 3532 if (const InstArithmetic *ArithInst = | 3561 if (const InstArithmetic *ArithInst = |
| 3533 llvm::dyn_cast_or_null<InstArithmetic>(IndexInst)) { | 3562 llvm::dyn_cast_or_null<InstArithmetic>(IndexInst)) { |
| 3534 Operand *IndexOperand0 = ArithInst->getSrc(0); | 3563 Operand *IndexOperand0 = ArithInst->getSrc(0); |
| 3535 Variable *IndexVariable0 = llvm::dyn_cast<Variable>(IndexOperand0); | 3564 Variable *IndexVariable0 = llvm::dyn_cast<Variable>(IndexOperand0); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3553 case 8: | 3582 case 8: |
| 3554 LogMult = 3; | 3583 LogMult = 3; |
| 3555 break; | 3584 break; |
| 3556 default: | 3585 default: |
| 3557 LogMult = 4; | 3586 LogMult = 4; |
| 3558 break; | 3587 break; |
| 3559 } | 3588 } |
| 3560 if (Shift + LogMult <= 3) { | 3589 if (Shift + LogMult <= 3) { |
| 3561 Index = IndexVariable0; | 3590 Index = IndexVariable0; |
| 3562 Shift += LogMult; | 3591 Shift += LogMult; |
| 3592 dumpAddressOpt(Func, Base, Index, Shift, Offset, IndexInst); |
| 3563 continue; | 3593 continue; |
| 3564 } | 3594 } |
| 3565 } | 3595 } |
| 3566 } | 3596 } |
| 3567 | 3597 |
| 3568 // Base is Base=Var+Const || Base is Base=Const+Var ==> | 3598 // Base is Base=Var+Const || Base is Base=Const+Var ==> |
| 3569 // set Base=Var, Offset+=Const | 3599 // set Base=Var, Offset+=Const |
| 3570 // Base is Base=Var-Const ==> | 3600 // Base is Base=Var-Const ==> |
| 3571 // set Base=Var, Offset-=Const | 3601 // set Base=Var, Offset-=Const |
| 3572 const InstArithmetic *ArithInst = | 3602 const InstArithmetic *ArithInst = |
| 3573 llvm::dyn_cast_or_null<const InstArithmetic>(BaseInst); | 3603 llvm::dyn_cast_or_null<const InstArithmetic>(BaseInst); |
| 3574 if (ArithInst && (ArithInst->getOp() == InstArithmetic::Add || | 3604 if (ArithInst && (ArithInst->getOp() == InstArithmetic::Add || |
| 3575 ArithInst->getOp() == InstArithmetic::Sub)) { | 3605 ArithInst->getOp() == InstArithmetic::Sub)) { |
| 3576 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; | 3606 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; |
| 3577 Variable *Var = NULL; | 3607 Variable *Var = NULL; |
| 3578 ConstantInteger *Const = NULL; | 3608 ConstantInteger *Const = NULL; |
| 3579 if (Variable *VariableOperand = | 3609 if (Variable *VariableOperand = |
| 3580 llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) { | 3610 llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) { |
| 3581 Var = VariableOperand; | 3611 Var = VariableOperand; |
| 3582 Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(1)); | 3612 Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(1)); |
| 3583 } else if (IsAdd) { | 3613 } else if (IsAdd) { |
| 3584 Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(0)); | 3614 Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(0)); |
| 3585 Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1)); | 3615 Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1)); |
| 3586 } | 3616 } |
| 3587 if (!(Const && Var)) { | 3617 if (!(Const && Var)) { |
| 3588 break; | 3618 break; |
| 3589 } | 3619 } |
| 3590 Base = Var; | 3620 Base = Var; |
| 3591 Offset += IsAdd ? Const->getValue() : -Const->getValue(); | 3621 Offset += IsAdd ? Const->getValue() : -Const->getValue(); |
| 3622 dumpAddressOpt(Func, Base, Index, Shift, Offset, BaseInst); |
| 3592 continue; | 3623 continue; |
| 3593 } | 3624 } |
| 3594 | 3625 |
| 3595 // Index is Index=Var<<Const && Const+Shift<=3 ==> | 3626 // Index is Index=Var<<Const && Const+Shift<=3 ==> |
| 3596 // Index=Var, Shift+=Const | 3627 // Index=Var, Shift+=Const |
| 3597 | 3628 |
| 3598 // Index is Index=Const*Var && log2(Const)+Shift<=3 ==> | 3629 // Index is Index=Const*Var && log2(Const)+Shift<=3 ==> |
| 3599 // Index=Var, Shift+=log2(Const) | 3630 // Index=Var, Shift+=log2(Const) |
| 3600 | 3631 |
| 3601 // Index && Shift==0 && Base is Base=Var*Const && log2(Const)+Shift<=3 ==> | 3632 // Index && Shift==0 && Base is Base=Var*Const && log2(Const)+Shift<=3 ==> |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3677 Variable *Index = NULL; | 3708 Variable *Index = NULL; |
| 3678 uint16_t Shift = 0; | 3709 uint16_t Shift = 0; |
| 3679 int32_t Offset = 0; // TODO: make Constant | 3710 int32_t Offset = 0; // TODO: make Constant |
| 3680 // Vanilla ICE load instructions should not use the segment registers, | 3711 // Vanilla ICE load instructions should not use the segment registers, |
| 3681 // and computeAddressOpt only works at the level of Variables and Constants, | 3712 // and computeAddressOpt only works at the level of Variables and Constants, |
| 3682 // not other OperandX8632Mem, so there should be no mention of segment | 3713 // not other OperandX8632Mem, so there should be no mention of segment |
| 3683 // registers there either. | 3714 // registers there either. |
| 3684 const OperandX8632Mem::SegmentRegisters SegmentReg = | 3715 const OperandX8632Mem::SegmentRegisters SegmentReg = |
| 3685 OperandX8632Mem::DefaultSegment; | 3716 OperandX8632Mem::DefaultSegment; |
| 3686 Variable *Base = llvm::dyn_cast<Variable>(Addr); | 3717 Variable *Base = llvm::dyn_cast<Variable>(Addr); |
| 3687 computeAddressOpt(Base, Index, Shift, Offset); | 3718 computeAddressOpt(Func, Inst, Base, Index, Shift, Offset); |
| 3688 if (Base && Addr != Base) { | 3719 if (Base && Addr != Base) { |
| 3720 Inst->setDeleted(); |
| 3689 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); | 3721 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); |
| 3690 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, | 3722 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, |
| 3691 Shift, SegmentReg); | 3723 Shift, SegmentReg); |
| 3692 Inst->setDeleted(); | |
| 3693 Context.insert(InstLoad::create(Func, Dest, Addr)); | 3724 Context.insert(InstLoad::create(Func, Dest, Addr)); |
| 3694 } | 3725 } |
| 3695 } | 3726 } |
| 3696 | 3727 |
| 3697 void TargetX8632::randomlyInsertNop(float Probability) { | 3728 void TargetX8632::randomlyInsertNop(float Probability) { |
| 3698 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); | 3729 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); |
| 3699 if (RNG.getTrueWithProbability(Probability)) { | 3730 if (RNG.getTrueWithProbability(Probability)) { |
| 3700 _nop(RNG.next(X86_NUM_NOP_VARIANTS)); | 3731 _nop(RNG.next(X86_NUM_NOP_VARIANTS)); |
| 3701 } | 3732 } |
| 3702 } | 3733 } |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3859 Variable *Index = NULL; | 3890 Variable *Index = NULL; |
| 3860 uint16_t Shift = 0; | 3891 uint16_t Shift = 0; |
| 3861 int32_t Offset = 0; // TODO: make Constant | 3892 int32_t Offset = 0; // TODO: make Constant |
| 3862 Variable *Base = llvm::dyn_cast<Variable>(Addr); | 3893 Variable *Base = llvm::dyn_cast<Variable>(Addr); |
| 3863 // Vanilla ICE store instructions should not use the segment registers, | 3894 // Vanilla ICE store instructions should not use the segment registers, |
| 3864 // and computeAddressOpt only works at the level of Variables and Constants, | 3895 // and computeAddressOpt only works at the level of Variables and Constants, |
| 3865 // not other OperandX8632Mem, so there should be no mention of segment | 3896 // not other OperandX8632Mem, so there should be no mention of segment |
| 3866 // registers there either. | 3897 // registers there either. |
| 3867 const OperandX8632Mem::SegmentRegisters SegmentReg = | 3898 const OperandX8632Mem::SegmentRegisters SegmentReg = |
| 3868 OperandX8632Mem::DefaultSegment; | 3899 OperandX8632Mem::DefaultSegment; |
| 3869 computeAddressOpt(Base, Index, Shift, Offset); | 3900 computeAddressOpt(Func, Inst, Base, Index, Shift, Offset); |
| 3870 if (Base && Addr != Base) { | 3901 if (Base && Addr != Base) { |
| 3902 Inst->setDeleted(); |
| 3871 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); | 3903 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); |
| 3872 Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index, | 3904 Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index, |
| 3873 Shift, SegmentReg); | 3905 Shift, SegmentReg); |
| 3874 Inst->setDeleted(); | |
| 3875 Context.insert(InstStore::create(Func, Data, Addr)); | 3906 Context.insert(InstStore::create(Func, Data, Addr)); |
| 3876 } | 3907 } |
| 3877 } | 3908 } |
| 3878 | 3909 |
| 3879 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { | 3910 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { |
| 3880 // This implements the most naive possible lowering. | 3911 // This implements the most naive possible lowering. |
| 3881 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default | 3912 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default |
| 3882 Operand *Src0 = Inst->getComparison(); | 3913 Operand *Src0 = Inst->getComparison(); |
| 3883 SizeT NumCases = Inst->getNumCases(); | 3914 SizeT NumCases = Inst->getNumCases(); |
| 3884 // OK, we'll be slightly less naive by forcing Src into a physical | 3915 // OK, we'll be slightly less naive by forcing Src into a physical |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3936 // | 3967 // |
| 3937 // We can eliminate the sext operation by copying the result of pcmpeqd, | 3968 // We can eliminate the sext operation by copying the result of pcmpeqd, |
| 3938 // pcmpgtd, or cmpps (which produce sign extended results) to the result | 3969 // pcmpgtd, or cmpps (which produce sign extended results) to the result |
| 3939 // of the sext operation. | 3970 // of the sext operation. |
| 3940 void | 3971 void |
| 3941 TargetX8632::eliminateNextVectorSextInstruction(Variable *SignExtendedResult) { | 3972 TargetX8632::eliminateNextVectorSextInstruction(Variable *SignExtendedResult) { |
| 3942 if (InstCast *NextCast = | 3973 if (InstCast *NextCast = |
| 3943 llvm::dyn_cast_or_null<InstCast>(Context.getNextInst())) { | 3974 llvm::dyn_cast_or_null<InstCast>(Context.getNextInst())) { |
| 3944 if (NextCast->getCastKind() == InstCast::Sext && | 3975 if (NextCast->getCastKind() == InstCast::Sext && |
| 3945 NextCast->getSrc(0) == SignExtendedResult) { | 3976 NextCast->getSrc(0) == SignExtendedResult) { |
| 3977 NextCast->setDeleted(); |
| 3946 _movp(NextCast->getDest(), legalizeToVar(SignExtendedResult)); | 3978 _movp(NextCast->getDest(), legalizeToVar(SignExtendedResult)); |
| 3947 // Skip over the instruction. | 3979 // Skip over the instruction. |
| 3948 NextCast->setDeleted(); | |
| 3949 Context.advanceNext(); | 3980 Context.advanceNext(); |
| 3950 } | 3981 } |
| 3951 } | 3982 } |
| 3952 } | 3983 } |
| 3953 | 3984 |
| 3954 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { | 3985 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { |
| 3955 const SizeT MaxSrcs = 0; | 3986 const SizeT MaxSrcs = 0; |
| 3956 Variable *Dest = NULL; | 3987 Variable *Dest = NULL; |
| 3957 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs); | 3988 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs); |
| 3958 lowerCall(Call); | 3989 lowerCall(Call); |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4387 Str << "\t.align\t" << Align << "\n"; | 4418 Str << "\t.align\t" << Align << "\n"; |
| 4388 Str << MangledName << ":\n"; | 4419 Str << MangledName << ":\n"; |
| 4389 for (SizeT i = 0; i < Size; ++i) { | 4420 for (SizeT i = 0; i < Size; ++i) { |
| 4390 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4421 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 4391 } | 4422 } |
| 4392 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4423 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 4393 } | 4424 } |
| 4394 } | 4425 } |
| 4395 | 4426 |
| 4396 } // end of namespace Ice | 4427 } // end of namespace Ice |
| OLD | NEW |