Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(723)

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 557953007: Subzero: Fix incorrect address mode inference involving Phi temporaries. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Add check against Var2->getIsMultidef() Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceOperand.h ('k') | tests_lit/llvm2ice_tests/phi.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 3529 matching lines...) Expand 10 before | Expand all | Expand 10 after
3540 else 3540 else
3541 Str << "<null>"; 3541 Str << "<null>";
3542 Str << ", Index="; 3542 Str << ", Index=";
3543 if (Index) 3543 if (Index)
3544 Index->dump(Func); 3544 Index->dump(Func);
3545 else 3545 else
3546 Str << "<null>"; 3546 Str << "<null>";
3547 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; 3547 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n";
3548 } 3548 }
3549 3549
3550 bool matchTransitiveAssign(Variable *&Var, const Inst *&Reason) {
3551 // Var originates from Var=SrcVar ==>
3552 // set Var:=SrcVar
3553 if (Var == NULL)
3554 return false;
3555 if (const Inst *VarAssign = Var->getDefinition()) {
3556 if (llvm::isa<InstAssign>(VarAssign)) {
3557 Operand *SrcOp = VarAssign->getSrc(0);
3558 assert(SrcOp);
3559 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) {
3560 if (!SrcVar->getIsMultidef() &&
3561 // TODO: ensure SrcVar stays single-BB
3562 true) {
3563 Var = SrcVar;
3564 Reason = VarAssign;
3565 return true;
3566 }
3567 }
3568 }
3569 }
3570 return false;
3571 }
3572
3573 bool matchCombinedBaseIndex(Variable *&Base, Variable *&Index, uint16_t &Shift,
3574 const Inst *&Reason) {
3575 // Index==NULL && Base is Base=Var1+Var2 ==>
3576 // set Base=Var1, Index=Var2, Shift=0
3577 if (Base == NULL)
3578 return false;
3579 if (Index != NULL)
3580 return false;
3581 const Inst *BaseInst = Base->getDefinition();
3582 if (BaseInst == NULL)
3583 return false;
3584 if (BaseInst->getSrcSize() < 2)
3585 return false;
3586 if (Variable *Var1 = llvm::dyn_cast<Variable>(BaseInst->getSrc(0))) {
3587 if (Var1->getIsMultidef())
3588 return false;
3589 if (Variable *Var2 = llvm::dyn_cast<Variable>(BaseInst->getSrc(1))) {
3590 if (Var2->getIsMultidef())
3591 return false;
3592 if (isAdd(BaseInst) &&
3593 // TODO: ensure Var1 and Var2 stay single-BB
3594 true) {
3595 Base = Var1;
3596 Index = Var2;
3597 Shift = 0; // should already have been 0
3598 Reason = BaseInst;
3599 return true;
3600 }
3601 }
3602 }
3603 return false;
3604 }
3605
3606 bool matchShiftedIndex(Variable *&Index, uint16_t &Shift, const Inst *&Reason) {
3607 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==>
3608 // Index=Var, Shift+=log2(Const)
3609 if (Index == NULL)
3610 return false;
3611 const Inst *IndexInst = Index->getDefinition();
3612 if (IndexInst == NULL)
3613 return false;
3614 if (IndexInst->getSrcSize() < 2)
3615 return false;
3616 if (const InstArithmetic *ArithInst =
3617 llvm::dyn_cast<InstArithmetic>(IndexInst)) {
3618 if (Variable *Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) {
3619 if (ConstantInteger *Const =
3620 llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(1))) {
3621 if (ArithInst->getOp() == InstArithmetic::Mul &&
3622 !Var->getIsMultidef() && Const->getType() == IceType_i32) {
3623 uint64_t Mult = Const->getValue();
3624 uint32_t LogMult;
3625 switch (Mult) {
3626 case 1:
3627 LogMult = 0;
3628 break;
3629 case 2:
3630 LogMult = 1;
3631 break;
3632 case 4:
3633 LogMult = 2;
3634 break;
3635 case 8:
3636 LogMult = 3;
3637 break;
3638 default:
3639 return false;
3640 }
3641 if (Shift + LogMult <= 3) {
3642 Index = Var;
3643 Shift += LogMult;
3644 Reason = IndexInst;
3645 return true;
3646 }
3647 }
3648 }
3649 }
3650 }
3651 return false;
3652 }
3653
3654 bool matchOffsetBase(Variable *&Base, int32_t &Offset, const Inst *&Reason) {
3655 // Base is Base=Var+Const || Base is Base=Const+Var ==>
3656 // set Base=Var, Offset+=Const
3657 // Base is Base=Var-Const ==>
3658 // set Base=Var, Offset-=Const
3659 if (Base == NULL)
3660 return false;
3661 const Inst *BaseInst = Base->getDefinition();
3662 if (BaseInst == NULL)
3663 return false;
3664 if (const InstArithmetic *ArithInst =
3665 llvm::dyn_cast<const InstArithmetic>(BaseInst)) {
3666 if (ArithInst->getOp() != InstArithmetic::Add &&
3667 ArithInst->getOp() != InstArithmetic::Sub)
3668 return false;
3669 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add;
3670 Variable *Var = NULL;
3671 ConstantInteger *Const = NULL;
3672 if (Variable *VariableOperand =
3673 llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) {
3674 Var = VariableOperand;
3675 Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(1));
3676 } else if (IsAdd) {
3677 Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(0));
3678 Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1));
3679 }
3680 if (Var == NULL || Const == NULL || Var->getIsMultidef())
3681 return false;
3682 Base = Var;
3683 Offset += IsAdd ? Const->getValue() : -Const->getValue();
3684 Reason = BaseInst;
3685 return true;
3686 }
3687 return false;
3688 }
3689
3550 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, 3690 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base,
3551 Variable *&Index, uint16_t &Shift, int32_t &Offset) { 3691 Variable *&Index, uint16_t &Shift, int32_t &Offset) {
3552 Func->setCurrentNode(NULL); 3692 Func->setCurrentNode(NULL);
3553 if (Func->getContext()->isVerbose(IceV_AddrOpt)) { 3693 if (Func->getContext()->isVerbose(IceV_AddrOpt)) {
3554 Ostream &Str = Func->getContext()->getStrDump(); 3694 Ostream &Str = Func->getContext()->getStrDump();
3555 Str << "\nStarting computeAddressOpt for instruction:\n "; 3695 Str << "\nStarting computeAddressOpt for instruction:\n ";
3556 Instr->dumpDecorated(Func); 3696 Instr->dumpDecorated(Func);
3557 } 3697 }
3558 (void)Offset; // TODO: pattern-match for non-zero offsets. 3698 (void)Offset; // TODO: pattern-match for non-zero offsets.
3559 if (Base == NULL) 3699 if (Base == NULL)
3560 return; 3700 return;
3561 // If the Base has more than one use or is live across multiple 3701 // If the Base has more than one use or is live across multiple
3562 // blocks, then don't go further. Alternatively (?), never consider 3702 // blocks, then don't go further. Alternatively (?), never consider
3563 // a transformation that would change a variable that is currently 3703 // a transformation that would change a variable that is currently
3564 // *not* live across basic block boundaries into one that *is*. 3704 // *not* live across basic block boundaries into one that *is*.
3565 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) 3705 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/)
3566 return; 3706 return;
3567 3707
3568 while (true) { 3708 bool Continue = true;
3569 // Base is Base=Var ==> 3709 while (Continue) {
3570 // set Base=Var 3710 const Inst *Reason = NULL;
3571 const Inst *BaseInst = Base->getDefinition(); 3711 if (matchTransitiveAssign(Base, Reason) ||
3572 Operand *BaseOperand0 = BaseInst ? BaseInst->getSrc(0) : NULL; 3712 matchTransitiveAssign(Index, Reason) ||
3573 Variable *BaseVariable0 = llvm::dyn_cast_or_null<Variable>(BaseOperand0); 3713 matchCombinedBaseIndex(Base, Index, Shift, Reason) ||
3574 // TODO: Helper function for all instances of assignment 3714 matchShiftedIndex(Index, Shift, Reason) ||
3575 // transitivity. 3715 matchOffsetBase(Base, Offset, Reason)) {
3576 if (BaseInst && llvm::isa<InstAssign>(BaseInst) && BaseVariable0 && 3716 dumpAddressOpt(Func, Base, Index, Shift, Offset, Reason);
3577 // TODO: ensure BaseVariable0 stays single-BB 3717 } else {
3578 true) { 3718 Continue = false;
3579 Base = BaseVariable0;
3580 dumpAddressOpt(Func, Base, Index, Shift, Offset, BaseInst);
3581 continue;
3582 }
3583
3584 // Index is Index=Var ==>
3585 // set Index=Var
3586
3587 // Index==NULL && Base is Base=Var1+Var2 ==>
3588 // set Base=Var1, Index=Var2, Shift=0
3589 Operand *BaseOperand1 =
3590 BaseInst && BaseInst->getSrcSize() >= 2 ? BaseInst->getSrc(1) : NULL;
3591 Variable *BaseVariable1 = llvm::dyn_cast_or_null<Variable>(BaseOperand1);
3592 if (Index == NULL && isAdd(BaseInst) && BaseVariable0 && BaseVariable1 &&
3593 // TODO: ensure BaseVariable0 and BaseVariable1 stay single-BB
3594 true) {
3595 Base = BaseVariable0;
3596 Index = BaseVariable1;
3597 Shift = 0; // should already have been 0
3598 dumpAddressOpt(Func, Base, Index, Shift, Offset, BaseInst);
3599 continue;
3600 }
3601
3602 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==>
3603 // Index=Var, Shift+=log2(Const)
3604 const Inst *IndexInst = Index ? Index->getDefinition() : NULL;
3605 if (const InstArithmetic *ArithInst =
3606 llvm::dyn_cast_or_null<InstArithmetic>(IndexInst)) {
3607 Operand *IndexOperand0 = ArithInst->getSrc(0);
3608 Variable *IndexVariable0 = llvm::dyn_cast<Variable>(IndexOperand0);
3609 Operand *IndexOperand1 = ArithInst->getSrc(1);
3610 ConstantInteger *IndexConstant1 =
3611 llvm::dyn_cast<ConstantInteger>(IndexOperand1);
3612 if (ArithInst->getOp() == InstArithmetic::Mul && IndexVariable0 &&
3613 IndexOperand1->getType() == IceType_i32 && IndexConstant1) {
3614 uint64_t Mult = IndexConstant1->getValue();
3615 uint32_t LogMult;
3616 switch (Mult) {
3617 case 1:
3618 LogMult = 0;
3619 break;
3620 case 2:
3621 LogMult = 1;
3622 break;
3623 case 4:
3624 LogMult = 2;
3625 break;
3626 case 8:
3627 LogMult = 3;
3628 break;
3629 default:
3630 LogMult = 4;
3631 break;
3632 }
3633 if (Shift + LogMult <= 3) {
3634 Index = IndexVariable0;
3635 Shift += LogMult;
3636 dumpAddressOpt(Func, Base, Index, Shift, Offset, IndexInst);
3637 continue;
3638 }
3639 }
3640 }
3641
3642 // Base is Base=Var+Const || Base is Base=Const+Var ==>
3643 // set Base=Var, Offset+=Const
3644 // Base is Base=Var-Const ==>
3645 // set Base=Var, Offset-=Const
3646 const InstArithmetic *ArithInst =
3647 llvm::dyn_cast_or_null<const InstArithmetic>(BaseInst);
3648 if (ArithInst && (ArithInst->getOp() == InstArithmetic::Add ||
3649 ArithInst->getOp() == InstArithmetic::Sub)) {
3650 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add;
3651 Variable *Var = NULL;
3652 ConstantInteger *Const = NULL;
3653 if (Variable *VariableOperand =
3654 llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) {
3655 Var = VariableOperand;
3656 Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(1));
3657 } else if (IsAdd) {
3658 Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(0));
3659 Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1));
3660 }
3661 if (!(Const && Var)) {
3662 break;
3663 }
3664 Base = Var;
3665 Offset += IsAdd ? Const->getValue() : -Const->getValue();
3666 dumpAddressOpt(Func, Base, Index, Shift, Offset, BaseInst);
3667 continue;
3668 } 3719 }
3669 3720
3670 // Index is Index=Var<<Const && Const+Shift<=3 ==> 3721 // Index is Index=Var<<Const && Const+Shift<=3 ==>
3671 // Index=Var, Shift+=Const 3722 // Index=Var, Shift+=Const
3672 3723
3673 // Index is Index=Const*Var && log2(Const)+Shift<=3 ==> 3724 // Index is Index=Const*Var && log2(Const)+Shift<=3 ==>
3674 // Index=Var, Shift+=log2(Const) 3725 // Index=Var, Shift+=log2(Const)
3675 3726
3676 // Index && Shift==0 && Base is Base=Var*Const && log2(Const)+Shift<=3 ==> 3727 // Index && Shift==0 && Base is Base=Var*Const && log2(Const)+Shift<=3 ==>
3677 // swap(Index,Base) 3728 // swap(Index,Base)
3678 // Similar for Base=Const*Var and Base=Var<<Const 3729 // Similar for Base=Const*Var and Base=Var<<Const
3679 3730
3680 // Index is Index=Var+Const ==> 3731 // Index is Index=Var+Const ==>
3681 // set Index=Var, Offset+=(Const<<Shift) 3732 // set Index=Var, Offset+=(Const<<Shift)
3682 3733
3683 // Index is Index=Const+Var ==> 3734 // Index is Index=Const+Var ==>
3684 // set Index=Var, Offset+=(Const<<Shift) 3735 // set Index=Var, Offset+=(Const<<Shift)
3685 3736
3686 // Index is Index=Var-Const ==> 3737 // Index is Index=Var-Const ==>
3687 // set Index=Var, Offset-=(Const<<Shift) 3738 // set Index=Var, Offset-=(Const<<Shift)
3688 3739
3689 // TODO: consider overflow issues with respect to Offset. 3740 // TODO: consider overflow issues with respect to Offset.
3690 // TODO: handle symbolic constants. 3741 // TODO: handle symbolic constants.
3691 break;
3692 } 3742 }
3693 } 3743 }
3694 3744
3695 } // anonymous namespace 3745 } // anonymous namespace
3696 3746
3697 void TargetX8632::lowerLoad(const InstLoad *Inst) { 3747 void TargetX8632::lowerLoad(const InstLoad *Inst) {
3698 // A Load instruction can be treated the same as an Assign 3748 // A Load instruction can be treated the same as an Assign
3699 // instruction, after the source operand is transformed into an 3749 // instruction, after the source operand is transformed into an
3700 // OperandX8632Mem operand. Note that the address mode 3750 // OperandX8632Mem operand. Note that the address mode
3701 // optimization already creates an OperandX8632Mem operand, so it 3751 // optimization already creates an OperandX8632Mem operand, so it
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
4463 Str << "\t.align\t" << Align << "\n"; 4513 Str << "\t.align\t" << Align << "\n";
4464 Str << MangledName << ":\n"; 4514 Str << MangledName << ":\n";
4465 for (SizeT i = 0; i < Size; ++i) { 4515 for (SizeT i = 0; i < Size; ++i) {
4466 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; 4516 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
4467 } 4517 }
4468 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; 4518 Str << "\t.size\t" << MangledName << ", " << Size << "\n";
4469 } 4519 }
4470 } 4520 }
4471 4521
4472 } // end of namespace Ice 4522 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceOperand.h ('k') | tests_lit/llvm2ice_tests/phi.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698