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

Side by Side Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1217443024: Changes the TargetX8632 to inherit from TargetX86Base<TargetX8632>. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: s/Func-> /Func->/g (no functional changes) Created 5 years, 5 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
OLDNEW
1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==//
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 /// \file 10 /// \file
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 } 257 }
258 258
259 template <class Machine> 259 template <class Machine>
260 void TargetX86Base<Machine>::initNodeForLowering(CfgNode *Node) { 260 void TargetX86Base<Machine>::initNodeForLowering(CfgNode *Node) {
261 FoldingInfo.init(Node); 261 FoldingInfo.init(Node);
262 FoldingInfo.dump(Func); 262 FoldingInfo.dump(Func);
263 } 263 }
264 264
265 template <class Machine> 265 template <class Machine>
266 TargetX86Base<Machine>::TargetX86Base(Cfg *Func) 266 TargetX86Base<Machine>::TargetX86Base(Cfg *Func)
267 : Machine(Func) { 267 : TargetLowering(Func) {
268 static_assert( 268 static_assert(
269 (Traits::InstructionSet::End - Traits::InstructionSet::Begin) == 269 (Traits::InstructionSet::End - Traits::InstructionSet::Begin) ==
270 (TargetInstructionSet::X86InstructionSet_End - 270 (TargetInstructionSet::X86InstructionSet_End -
271 TargetInstructionSet::X86InstructionSet_Begin), 271 TargetInstructionSet::X86InstructionSet_Begin),
272 "Traits::InstructionSet range different from TargetInstructionSet"); 272 "Traits::InstructionSet range different from TargetInstructionSet");
273 if (Func->getContext()->getFlags().getTargetInstructionSet() != 273 if (Func->getContext()->getFlags().getTargetInstructionSet() !=
274 TargetInstructionSet::BaseInstructionSet) { 274 TargetInstructionSet::BaseInstructionSet) {
275 InstructionSet = static_cast<typename Traits::InstructionSet>( 275 InstructionSet = static_cast<typename Traits::InstructionSet>(
276 (Func->getContext()->getFlags().getTargetInstructionSet() - 276 (Func->getContext()->getFlags().getTargetInstructionSet() -
277 TargetInstructionSet::X86InstructionSet_Begin) + 277 TargetInstructionSet::X86InstructionSet_Begin) +
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 if (Func->hasError()) 445 if (Func->hasError())
446 return; 446 return;
447 Func->dump("After stack frame mapping"); 447 Func->dump("After stack frame mapping");
448 448
449 // Nop insertion 449 // Nop insertion
450 if (Ctx->getFlags().shouldDoNopInsertion()) { 450 if (Ctx->getFlags().shouldDoNopInsertion()) {
451 Func->doNopInsertion(); 451 Func->doNopInsertion();
452 } 452 }
453 } 453 }
454 454
455 bool canRMW(const InstArithmetic *Arith) { 455 inline bool canRMW(const InstArithmetic *Arith) {
456 Type Ty = Arith->getDest()->getType(); 456 Type Ty = Arith->getDest()->getType();
457 // X86 vector instructions write to a register and have no RMW option. 457 // X86 vector instructions write to a register and have no RMW option.
458 if (isVectorType(Ty)) 458 if (isVectorType(Ty))
459 return false; 459 return false;
460 bool isI64 = Ty == IceType_i64; 460 bool isI64 = Ty == IceType_i64;
461 461
462 switch (Arith->getOp()) { 462 switch (Arith->getOp()) {
463 // Not handled for lack of simple lowering: 463 // Not handled for lack of simple lowering:
464 // shift on i64 464 // shift on i64
465 // mul, udiv, urem, sdiv, srem, frem 465 // mul, udiv, urem, sdiv, srem, frem
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 continue; 569 continue;
570 if (Func->isVerbose(IceV_RMW)) { 570 if (Func->isVerbose(IceV_RMW)) {
571 Str << "Found RMW in " << Func->getFunctionName() << ":\n "; 571 Str << "Found RMW in " << Func->getFunctionName() << ":\n ";
572 Load->dump(Func); 572 Load->dump(Func);
573 Str << "\n "; 573 Str << "\n ";
574 Arith->dump(Func); 574 Arith->dump(Func);
575 Str << "\n "; 575 Str << "\n ";
576 Store->dump(Func); 576 Store->dump(Func);
577 Str << "\n"; 577 Str << "\n";
578 } 578 }
579 Variable *Beacon = Func->template makeVariable(IceType_i32); 579 Variable *Beacon = Func->makeVariable(IceType_i32);
580 Beacon->setWeight(0); 580 Beacon->setWeight(0);
581 Store->setRmwBeacon(Beacon); 581 Store->setRmwBeacon(Beacon);
582 InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon); 582 InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon);
583 Node->getInsts().insert(I3, BeaconDef); 583 Node->getInsts().insert(I3, BeaconDef);
584 auto *RMW = Traits::Insts::FakeRMW::create( 584 auto *RMW = Traits::Insts::FakeRMW::create(
585 Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp()); 585 Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp());
586 Node->getInsts().insert(I3, RMW); 586 Node->getInsts().insert(I3, RMW);
587 } 587 }
588 } 588 }
589 } 589 }
590 } 590 }
591 } 591 }
592 } 592 }
593 593
594 // Converts a ConstantInteger32 operand into its constant value, or 594 // Converts a ConstantInteger32 operand into its constant value, or
595 // MemoryOrderInvalid if the operand is not a ConstantInteger32. 595 // MemoryOrderInvalid if the operand is not a ConstantInteger32.
596 uint64_t getConstantMemoryOrder(Operand *Opnd) { 596 inline uint64_t getConstantMemoryOrder(Operand *Opnd) {
597 if (auto Integer = llvm::dyn_cast<ConstantInteger32>(Opnd)) 597 if (auto Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
598 return Integer->getValue(); 598 return Integer->getValue();
599 return Intrinsics::MemoryOrderInvalid; 599 return Intrinsics::MemoryOrderInvalid;
600 } 600 }
601 601
602 /// Determines whether the dest of a Load instruction can be folded 602 /// Determines whether the dest of a Load instruction can be folded
603 /// into one of the src operands of a 2-operand instruction. This is 603 /// into one of the src operands of a 2-operand instruction. This is
604 /// true as long as the load dest matches exactly one of the binary 604 /// true as long as the load dest matches exactly one of the binary
605 /// instruction's src operands. Replaces Src0 or Src1 with LoadSrc if 605 /// instruction's src operands. Replaces Src0 or Src1 with LoadSrc if
606 /// the answer is true. 606 /// the answer is true.
607 bool canFoldLoadIntoBinaryInst(Operand *LoadSrc, Variable *LoadDest, 607 inline bool canFoldLoadIntoBinaryInst(Operand *LoadSrc, Variable *LoadDest,
608 Operand *&Src0, Operand *&Src1) { 608 Operand *&Src0, Operand *&Src1) {
609 if (Src0 == LoadDest && Src1 != LoadDest) { 609 if (Src0 == LoadDest && Src1 != LoadDest) {
610 Src0 = LoadSrc; 610 Src0 = LoadSrc;
611 return true; 611 return true;
612 } 612 }
613 if (Src0 != LoadDest && Src1 == LoadDest) { 613 if (Src0 != LoadDest && Src1 == LoadDest) {
614 Src1 = LoadSrc; 614 Src1 = LoadSrc;
615 return true; 615 return true;
616 } 616 }
617 return false; 617 return false;
618 } 618 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 717
718 template <class Machine> 718 template <class Machine>
719 Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) { 719 Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) {
720 if (Ty == IceType_void) 720 if (Ty == IceType_void)
721 Ty = IceType_i32; 721 Ty = IceType_i32;
722 if (PhysicalRegisters[Ty].empty()) 722 if (PhysicalRegisters[Ty].empty())
723 PhysicalRegisters[Ty].resize(Traits::RegisterSet::Reg_NUM); 723 PhysicalRegisters[Ty].resize(Traits::RegisterSet::Reg_NUM);
724 assert(RegNum < PhysicalRegisters[Ty].size()); 724 assert(RegNum < PhysicalRegisters[Ty].size());
725 Variable *Reg = PhysicalRegisters[Ty][RegNum]; 725 Variable *Reg = PhysicalRegisters[Ty][RegNum];
726 if (Reg == nullptr) { 726 if (Reg == nullptr) {
727 Reg = Func->template makeVariable(Ty); 727 Reg = Func->makeVariable(Ty);
728 Reg->setRegNum(RegNum); 728 Reg->setRegNum(RegNum);
729 PhysicalRegisters[Ty][RegNum] = Reg; 729 PhysicalRegisters[Ty][RegNum] = Reg;
730 // Specially mark esp as an "argument" so that it is considered 730 // Specially mark esp as an "argument" so that it is considered
731 // live upon function entry. 731 // live upon function entry.
732 if (RegNum == Traits::RegisterSet::Reg_esp) { 732 if (RegNum == Traits::RegisterSet::Reg_esp) {
733 Func->addImplicitArg(Reg); 733 Func->addImplicitArg(Reg);
734 Reg->setIgnoreLiveness(); 734 Reg->setIgnoreLiveness();
735 } 735 }
736 } 736 }
737 return Reg; 737 return Reg;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 I < E && NumXmmArgs < Traits::X86_MAX_XMM_ARGS; ++I) { 790 I < E && NumXmmArgs < Traits::X86_MAX_XMM_ARGS; ++I) {
791 Variable *Arg = Args[I]; 791 Variable *Arg = Args[I];
792 Type Ty = Arg->getType(); 792 Type Ty = Arg->getType();
793 if (!isVectorType(Ty)) 793 if (!isVectorType(Ty))
794 continue; 794 continue;
795 // Replace Arg in the argument list with the home register. Then 795 // Replace Arg in the argument list with the home register. Then
796 // generate an instruction in the prolog to copy the home register 796 // generate an instruction in the prolog to copy the home register
797 // to the assigned location of Arg. 797 // to the assigned location of Arg.
798 int32_t RegNum = Traits::RegisterSet::Reg_xmm0 + NumXmmArgs; 798 int32_t RegNum = Traits::RegisterSet::Reg_xmm0 + NumXmmArgs;
799 ++NumXmmArgs; 799 ++NumXmmArgs;
800 Variable *RegisterArg = Func->template makeVariable(Ty); 800 Variable *RegisterArg = Func->makeVariable(Ty);
801 if (BuildDefs::dump()) 801 if (BuildDefs::dump())
802 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); 802 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
803 RegisterArg->setRegNum(RegNum); 803 RegisterArg->setRegNum(RegNum);
804 RegisterArg->setIsArg(); 804 RegisterArg->setIsArg();
805 Arg->setIsArg(false); 805 Arg->setIsArg(false);
806 806
807 Args[I] = RegisterArg; 807 Args[I] = RegisterArg;
808 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); 808 Context.insert(InstAssign::create(Func, Arg, RegisterArg));
809 } 809 }
810 } 810 }
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 1105
1106 if (!Ctx->getFlags().getUseSandboxing()) 1106 if (!Ctx->getFlags().getUseSandboxing())
1107 return; 1107 return;
1108 // Change the original ret instruction into a sandboxed return sequence. 1108 // Change the original ret instruction into a sandboxed return sequence.
1109 // t:ecx = pop 1109 // t:ecx = pop
1110 // bundle_lock 1110 // bundle_lock
1111 // and t, ~31 1111 // and t, ~31
1112 // jmp *t 1112 // jmp *t
1113 // bundle_unlock 1113 // bundle_unlock
1114 // FakeUse <original_ret_operand> 1114 // FakeUse <original_ret_operand>
1115 const SizeT BundleSize = 1115 const SizeT BundleSize = 1
1116 1 << Func->template getAssembler<>()->getBundleAlignLog2Bytes(); 1116 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
1117 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx); 1117 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
1118 _pop(T_ecx); 1118 _pop(T_ecx);
1119 _bundle_lock(); 1119 _bundle_lock();
1120 _and(T_ecx, Ctx->getConstantInt32(~(BundleSize - 1))); 1120 _and(T_ecx, Ctx->getConstantInt32(~(BundleSize - 1)));
1121 _jmp(T_ecx); 1121 _jmp(T_ecx);
1122 _bundle_unlock(); 1122 _bundle_unlock();
1123 if (RI->getSrcSize()) { 1123 if (RI->getSrcSize()) {
1124 Variable *RetValue = llvm::cast<Variable>(RI->getSrc(0)); 1124 Variable *RetValue = llvm::cast<Variable>(RI->getSrc(0));
1125 Context.insert(InstFakeUse::create(Func, RetValue)); 1125 Context.insert(InstFakeUse::create(Func, RetValue));
1126 } 1126 }
(...skipping 11 matching lines...) Expand all
1138 case IceType_f64: 1138 case IceType_f64:
1139 break; 1139 break;
1140 } 1140 }
1141 Variable *Lo = Var->getLo(); 1141 Variable *Lo = Var->getLo();
1142 Variable *Hi = Var->getHi(); 1142 Variable *Hi = Var->getHi();
1143 if (Lo) { 1143 if (Lo) {
1144 assert(Hi); 1144 assert(Hi);
1145 return; 1145 return;
1146 } 1146 }
1147 assert(Hi == nullptr); 1147 assert(Hi == nullptr);
1148 Lo = Func->template makeVariable(IceType_i32); 1148 Lo = Func->makeVariable(IceType_i32);
1149 Hi = Func->template makeVariable(IceType_i32); 1149 Hi = Func->makeVariable(IceType_i32);
1150 if (BuildDefs::dump()) { 1150 if (BuildDefs::dump()) {
1151 Lo->setName(Func, Var->getName(Func) + "__lo"); 1151 Lo->setName(Func, Var->getName(Func) + "__lo");
1152 Hi->setName(Func, Var->getName(Func) + "__hi"); 1152 Hi->setName(Func, Var->getName(Func) + "__hi");
1153 } 1153 }
1154 Var->setLoHi(Lo, Hi); 1154 Var->setLoHi(Lo, Hi);
1155 if (Var->getIsArg()) { 1155 if (Var->getIsArg()) {
1156 Lo->setIsArg(); 1156 Lo->setIsArg();
1157 Hi->setIsArg(); 1157 Hi->setIsArg();
1158 } 1158 }
1159 } 1159 }
(...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 Operand *CallTarget = legalize(Instr->getCallTarget()); 2232 Operand *CallTarget = legalize(Instr->getCallTarget());
2233 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); 2233 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
2234 if (NeedSandboxing) { 2234 if (NeedSandboxing) {
2235 if (llvm::isa<Constant>(CallTarget)) { 2235 if (llvm::isa<Constant>(CallTarget)) {
2236 _bundle_lock(InstBundleLock::Opt_AlignToEnd); 2236 _bundle_lock(InstBundleLock::Opt_AlignToEnd);
2237 } else { 2237 } else {
2238 Variable *CallTargetVar = nullptr; 2238 Variable *CallTargetVar = nullptr;
2239 _mov(CallTargetVar, CallTarget); 2239 _mov(CallTargetVar, CallTarget);
2240 _bundle_lock(InstBundleLock::Opt_AlignToEnd); 2240 _bundle_lock(InstBundleLock::Opt_AlignToEnd);
2241 const SizeT BundleSize = 2241 const SizeT BundleSize =
2242 1 << Func->template getAssembler<>()->getBundleAlignLog2Bytes(); 2242 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
2243 _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1))); 2243 _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1)));
2244 CallTarget = CallTargetVar; 2244 CallTarget = CallTargetVar;
2245 } 2245 }
2246 } 2246 }
2247 Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget); 2247 Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget);
2248 Context.insert(NewCall); 2248 Context.insert(NewCall);
2249 if (NeedSandboxing) 2249 if (NeedSandboxing)
2250 _bundle_unlock(); 2250 _bundle_unlock();
2251 if (ReturnRegHi) 2251 if (ReturnRegHi)
2252 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); 2252 Context.insert(InstFakeDef::create(Func, ReturnRegHi));
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
2661 assert((DestType == IceType_i32 && SrcType == IceType_f32) || 2661 assert((DestType == IceType_i32 && SrcType == IceType_f32) ||
2662 (DestType == IceType_f32 && SrcType == IceType_i32)); 2662 (DestType == IceType_f32 && SrcType == IceType_i32));
2663 // a.i32 = bitcast b.f32 ==> 2663 // a.i32 = bitcast b.f32 ==>
2664 // t.f32 = b.f32 2664 // t.f32 = b.f32
2665 // s.f32 = spill t.f32 2665 // s.f32 = spill t.f32
2666 // a.i32 = s.f32 2666 // a.i32 = s.f32
2667 Variable *T = nullptr; 2667 Variable *T = nullptr;
2668 // TODO: Should be able to force a spill setup by calling legalize() with 2668 // TODO: Should be able to force a spill setup by calling legalize() with
2669 // Legal_Mem and not Legal_Reg or Legal_Imm. 2669 // Legal_Mem and not Legal_Reg or Legal_Imm.
2670 typename Traits::SpillVariable *SpillVar = 2670 typename Traits::SpillVariable *SpillVar =
2671 Func->template makeVariable<typename Traits::SpillVariable>(SrcType); 2671 Func->makeVariable<typename Traits::SpillVariable>(SrcType);
2672 SpillVar->setLinkedTo(Dest); 2672 SpillVar->setLinkedTo(Dest);
2673 Variable *Spill = SpillVar; 2673 Variable *Spill = SpillVar;
2674 Spill->setWeight(RegWeight::Zero); 2674 Spill->setWeight(RegWeight::Zero);
2675 _mov(T, Src0RM); 2675 _mov(T, Src0RM);
2676 _mov(Spill, T); 2676 _mov(Spill, T);
2677 _mov(Dest, Spill); 2677 _mov(Dest, Spill);
2678 } break; 2678 } break;
2679 case IceType_i64: { 2679 case IceType_i64: {
2680 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2680 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2681 assert(Src0RM->getType() == IceType_f64); 2681 assert(Src0RM->getType() == IceType_f64);
2682 // a.i64 = bitcast b.f64 ==> 2682 // a.i64 = bitcast b.f64 ==>
2683 // s.f64 = spill b.f64 2683 // s.f64 = spill b.f64
2684 // t_lo.i32 = lo(s.f64) 2684 // t_lo.i32 = lo(s.f64)
2685 // a_lo.i32 = t_lo.i32 2685 // a_lo.i32 = t_lo.i32
2686 // t_hi.i32 = hi(s.f64) 2686 // t_hi.i32 = hi(s.f64)
2687 // a_hi.i32 = t_hi.i32 2687 // a_hi.i32 = t_hi.i32
2688 Operand *SpillLo, *SpillHi; 2688 Operand *SpillLo, *SpillHi;
2689 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) { 2689 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) {
2690 typename Traits::SpillVariable *SpillVar = 2690 typename Traits::SpillVariable *SpillVar =
2691 Func->template makeVariable<typename Traits::SpillVariable>( 2691 Func->makeVariable<typename Traits::SpillVariable>(IceType_f64);
2692 IceType_f64);
2693 SpillVar->setLinkedTo(Src0Var); 2692 SpillVar->setLinkedTo(Src0Var);
2694 Variable *Spill = SpillVar; 2693 Variable *Spill = SpillVar;
2695 Spill->setWeight(RegWeight::Zero); 2694 Spill->setWeight(RegWeight::Zero);
2696 _movq(Spill, Src0RM); 2695 _movq(Spill, Src0RM);
2697 SpillLo = Traits::VariableSplit::create(Func, Spill, 2696 SpillLo = Traits::VariableSplit::create(Func, Spill,
2698 Traits::VariableSplit::Low); 2697 Traits::VariableSplit::Low);
2699 SpillHi = Traits::VariableSplit::create(Func, Spill, 2698 SpillHi = Traits::VariableSplit::create(Func, Spill,
2700 Traits::VariableSplit::High); 2699 Traits::VariableSplit::High);
2701 } else { 2700 } else {
2702 SpillLo = loOperand(Src0RM); 2701 SpillLo = loOperand(Src0RM);
2703 SpillHi = hiOperand(Src0RM); 2702 SpillHi = hiOperand(Src0RM);
2704 } 2703 }
2705 2704
2706 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2705 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2707 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2706 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2708 Variable *T_Lo = makeReg(IceType_i32); 2707 Variable *T_Lo = makeReg(IceType_i32);
2709 Variable *T_Hi = makeReg(IceType_i32); 2708 Variable *T_Hi = makeReg(IceType_i32);
2710 2709
2711 _mov(T_Lo, SpillLo); 2710 _mov(T_Lo, SpillLo);
2712 _mov(DestLo, T_Lo); 2711 _mov(DestLo, T_Lo);
2713 _mov(T_Hi, SpillHi); 2712 _mov(T_Hi, SpillHi);
2714 _mov(DestHi, T_Hi); 2713 _mov(DestHi, T_Hi);
2715 } break; 2714 } break;
2716 case IceType_f64: { 2715 case IceType_f64: {
2717 Src0 = legalize(Src0); 2716 Src0 = legalize(Src0);
2718 assert(Src0->getType() == IceType_i64); 2717 assert(Src0->getType() == IceType_i64);
2719 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) { 2718 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) {
2720 Variable *T = Func->template makeVariable(Dest->getType()); 2719 Variable *T = Func->makeVariable(Dest->getType());
2721 _movq(T, Src0); 2720 _movq(T, Src0);
2722 _movq(Dest, T); 2721 _movq(Dest, T);
2723 break; 2722 break;
2724 } 2723 }
2725 // a.f64 = bitcast b.i64 ==> 2724 // a.f64 = bitcast b.i64 ==>
2726 // t_lo.i32 = b_lo.i32 2725 // t_lo.i32 = b_lo.i32
2727 // FakeDef(s.f64) 2726 // FakeDef(s.f64)
2728 // lo(s.f64) = t_lo.i32 2727 // lo(s.f64) = t_lo.i32
2729 // t_hi.i32 = b_hi.i32 2728 // t_hi.i32 = b_hi.i32
2730 // hi(s.f64) = t_hi.i32 2729 // hi(s.f64) = t_hi.i32
2731 // a.f64 = s.f64 2730 // a.f64 = s.f64
2732 typename Traits::SpillVariable *SpillVar = 2731 typename Traits::SpillVariable *SpillVar =
2733 Func->template makeVariable<typename Traits::SpillVariable>( 2732 Func->makeVariable<typename Traits::SpillVariable>(IceType_f64);
2734 IceType_f64);
2735 SpillVar->setLinkedTo(Dest); 2733 SpillVar->setLinkedTo(Dest);
2736 Variable *Spill = SpillVar; 2734 Variable *Spill = SpillVar;
2737 Spill->setWeight(RegWeight::Zero); 2735 Spill->setWeight(RegWeight::Zero);
2738 2736
2739 Variable *T_Lo = nullptr, *T_Hi = nullptr; 2737 Variable *T_Lo = nullptr, *T_Hi = nullptr;
2740 typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create( 2738 typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create(
2741 Func, Spill, Traits::VariableSplit::Low); 2739 Func, Spill, Traits::VariableSplit::Low);
2742 typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create( 2740 typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create(
2743 Func, Spill, Traits::VariableSplit::High); 2741 Func, Spill, Traits::VariableSplit::High);
2744 _mov(T_Lo, loOperand(Src0)); 2742 _mov(T_Lo, loOperand(Src0));
2745 // Technically, the Spill is defined after the _store happens, but 2743 // Technically, the Spill is defined after the _store happens, but
2746 // SpillLo is considered a "use" of Spill so define Spill before it 2744 // SpillLo is considered a "use" of Spill so define Spill before it
2747 // is used. 2745 // is used.
2748 Context.insert(InstFakeDef::create(Func, Spill)); 2746 Context.insert(InstFakeDef::create(Func, Spill));
2749 _store(T_Lo, SpillLo); 2747 _store(T_Lo, SpillLo);
2750 _mov(T_Hi, hiOperand(Src0)); 2748 _mov(T_Hi, hiOperand(Src0));
2751 _store(T_Hi, SpillHi); 2749 _store(T_Hi, SpillHi);
2752 _movq(Dest, Spill); 2750 _movq(Dest, Spill);
2753 } break; 2751 } break;
2754 case IceType_v8i1: { 2752 case IceType_v8i1: {
2755 assert(Src0->getType() == IceType_i8); 2753 assert(Src0->getType() == IceType_i8);
2756 InstCall *Call = makeHelperCall(H_bitcast_i8_8xi1, Dest, 1); 2754 InstCall *Call = makeHelperCall(H_bitcast_i8_8xi1, Dest, 1);
2757 Variable *Src0AsI32 = Func->template makeVariable(stackSlotType()); 2755 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
2758 // Arguments to functions are required to be at least 32 bits wide. 2756 // Arguments to functions are required to be at least 32 bits wide.
2759 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2757 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2760 Call->addArg(Src0AsI32); 2758 Call->addArg(Src0AsI32);
2761 lowerCall(Call); 2759 lowerCall(Call);
2762 } break; 2760 } break;
2763 case IceType_v16i1: { 2761 case IceType_v16i1: {
2764 assert(Src0->getType() == IceType_i16); 2762 assert(Src0->getType() == IceType_i16);
2765 InstCall *Call = makeHelperCall(H_bitcast_i16_16xi1, Dest, 1); 2763 InstCall *Call = makeHelperCall(H_bitcast_i16_16xi1, Dest, 1);
2766 Variable *Src0AsI32 = Func->template makeVariable(stackSlotType()); 2764 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
2767 // Arguments to functions are required to be at least 32 bits wide. 2765 // Arguments to functions are required to be at least 32 bits wide.
2768 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2766 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2769 Call->addArg(Src0AsI32); 2767 Call->addArg(Src0AsI32);
2770 lowerCall(Call); 2768 lowerCall(Call);
2771 } break; 2769 } break;
2772 case IceType_v8i16: 2770 case IceType_v8i16:
2773 case IceType_v16i8: 2771 case IceType_v16i8:
2774 case IceType_v4i32: 2772 case IceType_v4i32:
2775 case IceType_v4f32: { 2773 case IceType_v4f32: {
2776 _movp(Dest, legalizeToVar(Src0)); 2774 _movp(Dest, legalizeToVar(Src0));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2827 // keep the live range analysis consistent. 2825 // keep the live range analysis consistent.
2828 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); 2826 Context.insert(InstFakeDef::create(Func, ExtractedElementR));
2829 _movss(ExtractedElementR, T); 2827 _movss(ExtractedElementR, T);
2830 } 2828 }
2831 } else { 2829 } else {
2832 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 2830 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
2833 // Spill the value to a stack slot and do the extraction in memory. 2831 // Spill the value to a stack slot and do the extraction in memory.
2834 // 2832 //
2835 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when 2833 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
2836 // support for legalizing to mem is implemented. 2834 // support for legalizing to mem is implemented.
2837 Variable *Slot = Func->template makeVariable(Ty); 2835 Variable *Slot = Func->makeVariable(Ty);
2838 Slot->setWeight(RegWeight::Zero); 2836 Slot->setWeight(RegWeight::Zero);
2839 _movp(Slot, legalizeToVar(SourceVectNotLegalized)); 2837 _movp(Slot, legalizeToVar(SourceVectNotLegalized));
2840 2838
2841 // Compute the location of the element in memory. 2839 // Compute the location of the element in memory.
2842 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 2840 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
2843 typename Traits::X86OperandMem *Loc = 2841 typename Traits::X86OperandMem *Loc =
2844 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 2842 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
2845 _mov(ExtractedElementR, Loc); 2843 _mov(ExtractedElementR, Loc);
2846 } 2844 }
2847 2845
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 case IceType_v4i1: 2990 case IceType_v4i1:
2993 NewTy = IceType_v4i32; 2991 NewTy = IceType_v4i32;
2994 break; 2992 break;
2995 case IceType_v8i1: 2993 case IceType_v8i1:
2996 NewTy = IceType_v8i16; 2994 NewTy = IceType_v8i16;
2997 break; 2995 break;
2998 case IceType_v16i1: 2996 case IceType_v16i1:
2999 NewTy = IceType_v16i8; 2997 NewTy = IceType_v16i8;
3000 break; 2998 break;
3001 } 2999 }
3002 Variable *NewSrc0 = Func->template makeVariable(NewTy); 3000 Variable *NewSrc0 = Func->makeVariable(NewTy);
3003 Variable *NewSrc1 = Func->template makeVariable(NewTy); 3001 Variable *NewSrc1 = Func->makeVariable(NewTy);
3004 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0)); 3002 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0));
3005 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1)); 3003 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1));
3006 Src0 = NewSrc0; 3004 Src0 = NewSrc0;
3007 Src1 = NewSrc1; 3005 Src1 = NewSrc1;
3008 Ty = NewTy; 3006 Ty = NewTy;
3009 } 3007 }
3010 3008
3011 InstIcmp::ICond Condition = Inst->getCondition(); 3009 InstIcmp::ICond Condition = Inst->getCondition();
3012 3010
3013 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 3011 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
3135 unsigned Index = ElementIndex->getValue(); 3133 unsigned Index = ElementIndex->getValue();
3136 assert(Index < typeNumElements(SourceVectNotLegalized->getType())); 3134 assert(Index < typeNumElements(SourceVectNotLegalized->getType()));
3137 3135
3138 Type Ty = SourceVectNotLegalized->getType(); 3136 Type Ty = SourceVectNotLegalized->getType();
3139 Type ElementTy = typeElementType(Ty); 3137 Type ElementTy = typeElementType(Ty);
3140 Type InVectorElementTy = Traits::getInVectorElementType(Ty); 3138 Type InVectorElementTy = Traits::getInVectorElementType(Ty);
3141 3139
3142 if (ElementTy == IceType_i1) { 3140 if (ElementTy == IceType_i1) {
3143 // Expand the element to the appropriate size for it to be inserted 3141 // Expand the element to the appropriate size for it to be inserted
3144 // in the vector. 3142 // in the vector.
3145 Variable *Expanded = Func->template makeVariable(InVectorElementTy); 3143 Variable *Expanded = Func->makeVariable(InVectorElementTy);
3146 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded, 3144 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded,
3147 ElementToInsertNotLegalized); 3145 ElementToInsertNotLegalized);
3148 lowerCast(Cast); 3146 lowerCast(Cast);
3149 ElementToInsertNotLegalized = Expanded; 3147 ElementToInsertNotLegalized = Expanded;
3150 } 3148 }
3151 3149
3152 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 || 3150 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 ||
3153 InstructionSet >= Traits::SSE4_1) { 3151 InstructionSet >= Traits::SSE4_1) {
3154 // Use insertps, pinsrb, pinsrw, or pinsrd. 3152 // Use insertps, pinsrb, pinsrw, or pinsrd.
3155 Operand *ElementRM = 3153 Operand *ElementRM =
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3226 _shufps(T, ElementR, Mask2Constant); 3224 _shufps(T, ElementR, Mask2Constant);
3227 _movp(Inst->getDest(), T); 3225 _movp(Inst->getDest(), T);
3228 } 3226 }
3229 } else { 3227 } else {
3230 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 3228 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
3231 // Spill the value to a stack slot and perform the insertion in 3229 // Spill the value to a stack slot and perform the insertion in
3232 // memory. 3230 // memory.
3233 // 3231 //
3234 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when 3232 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
3235 // support for legalizing to mem is implemented. 3233 // support for legalizing to mem is implemented.
3236 Variable *Slot = Func->template makeVariable(Ty); 3234 Variable *Slot = Func->makeVariable(Ty);
3237 Slot->setWeight(RegWeight::Zero); 3235 Slot->setWeight(RegWeight::Zero);
3238 _movp(Slot, legalizeToVar(SourceVectNotLegalized)); 3236 _movp(Slot, legalizeToVar(SourceVectNotLegalized));
3239 3237
3240 // Compute the location of the position to insert in memory. 3238 // Compute the location of the position to insert in memory.
3241 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 3239 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
3242 typename Traits::X86OperandMem *Loc = 3240 typename Traits::X86OperandMem *Loc =
3243 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 3241 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
3244 _store(legalizeToVar(ElementToInsertNotLegalized), Loc); 3242 _store(legalizeToVar(ElementToInsertNotLegalized), Loc);
3245 3243
3246 Variable *T = makeReg(Ty); 3244 Variable *T = makeReg(Ty);
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3519 Call->addArg(Instr->getArg(2)); 3517 Call->addArg(Instr->getArg(2));
3520 lowerCall(Call); 3518 lowerCall(Call);
3521 return; 3519 return;
3522 } 3520 }
3523 case Intrinsics::Memset: { 3521 case Intrinsics::Memset: {
3524 // The value operand needs to be extended to a stack slot size 3522 // The value operand needs to be extended to a stack slot size
3525 // because the PNaCl ABI requires arguments to be at least 32 bits 3523 // because the PNaCl ABI requires arguments to be at least 32 bits
3526 // wide. 3524 // wide.
3527 Operand *ValOp = Instr->getArg(1); 3525 Operand *ValOp = Instr->getArg(1);
3528 assert(ValOp->getType() == IceType_i8); 3526 assert(ValOp->getType() == IceType_i8);
3529 Variable *ValExt = Func->template makeVariable(stackSlotType()); 3527 Variable *ValExt = Func->makeVariable(stackSlotType());
3530 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); 3528 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp));
3531 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); 3529 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3);
3532 Call->addArg(Instr->getArg(0)); 3530 Call->addArg(Instr->getArg(0));
3533 Call->addArg(ValExt); 3531 Call->addArg(ValExt);
3534 Call->addArg(Instr->getArg(2)); 3532 Call->addArg(Instr->getArg(2));
3535 lowerCall(Call); 3533 lowerCall(Call);
3536 return; 3534 return;
3537 } 3535 }
3538 case Intrinsics::NaClReadTP: { 3536 case Intrinsics::NaClReadTP: {
3539 if (Ctx->getFlags().getUseSandboxing()) { 3537 if (Ctx->getFlags().getUseSandboxing()) {
3540 Constant *Zero = Ctx->getConstantZero(IceType_i32); 3538 Operand *Src = dispatchToConcrete(&Machine::createNaClReadTPSrcOperand);
3541 Operand *Src = Traits::X86OperandMem::create(
3542 Func, IceType_i32, nullptr, Zero, nullptr, 0,
3543 Traits::X86OperandMem::SegReg_GS);
3544 Variable *Dest = Instr->getDest(); 3539 Variable *Dest = Instr->getDest();
3545 Variable *T = nullptr; 3540 Variable *T = nullptr;
3546 _mov(T, Src); 3541 _mov(T, Src);
3547 _mov(Dest, T); 3542 _mov(Dest, T);
3548 } else { 3543 } else {
3549 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0); 3544 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0);
3550 lowerCall(Call); 3545 lowerCall(Call);
3551 } 3546 }
3552 return; 3547 return;
3553 } 3548 }
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3966 } else { 3961 } else {
3967 _bsr(T_Dest2, SecondVar); 3962 _bsr(T_Dest2, SecondVar);
3968 _xor(T_Dest2, ThirtyOne); 3963 _xor(T_Dest2, ThirtyOne);
3969 } 3964 }
3970 _test(SecondVar, SecondVar); 3965 _test(SecondVar, SecondVar);
3971 _cmov(T_Dest2, T_Dest, Traits::Cond::Br_e); 3966 _cmov(T_Dest2, T_Dest, Traits::Cond::Br_e);
3972 _mov(DestLo, T_Dest2); 3967 _mov(DestLo, T_Dest2);
3973 _mov(DestHi, Ctx->getConstantZero(IceType_i32)); 3968 _mov(DestHi, Ctx->getConstantZero(IceType_i32));
3974 } 3969 }
3975 3970
3976 bool isAdd(const Inst *Inst) { 3971 inline bool isAdd(const Inst *Inst) {
3977 if (const InstArithmetic *Arith = 3972 if (const InstArithmetic *Arith =
3978 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { 3973 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) {
3979 return (Arith->getOp() == InstArithmetic::Add); 3974 return (Arith->getOp() == InstArithmetic::Add);
3980 } 3975 }
3981 return false; 3976 return false;
3982 } 3977 }
3983 3978
3984 void dumpAddressOpt(const Cfg *Func, const Variable *Base, 3979 inline void dumpAddressOpt(const Cfg *Func, const Variable *Base,
3985 const Variable *Index, uint16_t Shift, int32_t Offset, 3980 const Variable *Index, uint16_t Shift,
3986 const Inst *Reason) { 3981 int32_t Offset, const Inst *Reason) {
3987 if (!BuildDefs::dump()) 3982 if (!BuildDefs::dump())
3988 return; 3983 return;
3989 if (!Func->isVerbose(IceV_AddrOpt)) 3984 if (!Func->isVerbose(IceV_AddrOpt))
3990 return; 3985 return;
3991 OstreamLocker L(Func->getContext()); 3986 OstreamLocker L(Func->getContext());
3992 Ostream &Str = Func->getContext()->getStrDump(); 3987 Ostream &Str = Func->getContext()->getStrDump();
3993 Str << "Instruction: "; 3988 Str << "Instruction: ";
3994 Reason->dumpDecorated(Func); 3989 Reason->dumpDecorated(Func);
3995 Str << " results in Base="; 3990 Str << " results in Base=";
3996 if (Base) 3991 if (Base)
3997 Base->dump(Func); 3992 Base->dump(Func);
3998 else 3993 else
3999 Str << "<null>"; 3994 Str << "<null>";
4000 Str << ", Index="; 3995 Str << ", Index=";
4001 if (Index) 3996 if (Index)
4002 Index->dump(Func); 3997 Index->dump(Func);
4003 else 3998 else
4004 Str << "<null>"; 3999 Str << "<null>";
4005 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; 4000 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n";
4006 } 4001 }
4007 4002
4008 bool matchTransitiveAssign(const VariablesMetadata *VMetadata, Variable *&Var, 4003 inline bool matchTransitiveAssign(const VariablesMetadata *VMetadata,
4009 const Inst *&Reason) { 4004 Variable *&Var, const Inst *&Reason) {
4010 // Var originates from Var=SrcVar ==> 4005 // Var originates from Var=SrcVar ==>
4011 // set Var:=SrcVar 4006 // set Var:=SrcVar
4012 if (Var == nullptr) 4007 if (Var == nullptr)
4013 return false; 4008 return false;
4014 if (const Inst *VarAssign = VMetadata->getSingleDefinition(Var)) { 4009 if (const Inst *VarAssign = VMetadata->getSingleDefinition(Var)) {
4015 assert(!VMetadata->isMultiDef(Var)); 4010 assert(!VMetadata->isMultiDef(Var));
4016 if (llvm::isa<InstAssign>(VarAssign)) { 4011 if (llvm::isa<InstAssign>(VarAssign)) {
4017 Operand *SrcOp = VarAssign->getSrc(0); 4012 Operand *SrcOp = VarAssign->getSrc(0);
4018 assert(SrcOp); 4013 assert(SrcOp);
4019 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) { 4014 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) {
4020 if (!VMetadata->isMultiDef(SrcVar) && 4015 if (!VMetadata->isMultiDef(SrcVar) &&
4021 // TODO: ensure SrcVar stays single-BB 4016 // TODO: ensure SrcVar stays single-BB
4022 true) { 4017 true) {
4023 Var = SrcVar; 4018 Var = SrcVar;
4024 Reason = VarAssign; 4019 Reason = VarAssign;
4025 return true; 4020 return true;
4026 } 4021 }
4027 } 4022 }
4028 } 4023 }
4029 } 4024 }
4030 return false; 4025 return false;
4031 } 4026 }
4032 4027
4033 bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata, Variable *&Base, 4028 inline bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata,
4034 Variable *&Index, uint16_t &Shift, 4029 Variable *&Base, Variable *&Index,
4035 const Inst *&Reason) { 4030 uint16_t &Shift, const Inst *&Reason) {
4036 // Index==nullptr && Base is Base=Var1+Var2 ==> 4031 // Index==nullptr && Base is Base=Var1+Var2 ==>
4037 // set Base=Var1, Index=Var2, Shift=0 4032 // set Base=Var1, Index=Var2, Shift=0
4038 if (Base == nullptr) 4033 if (Base == nullptr)
4039 return false; 4034 return false;
4040 if (Index != nullptr) 4035 if (Index != nullptr)
4041 return false; 4036 return false;
4042 const Inst *BaseInst = VMetadata->getSingleDefinition(Base); 4037 const Inst *BaseInst = VMetadata->getSingleDefinition(Base);
4043 if (BaseInst == nullptr) 4038 if (BaseInst == nullptr)
4044 return false; 4039 return false;
4045 assert(!VMetadata->isMultiDef(Base)); 4040 assert(!VMetadata->isMultiDef(Base));
(...skipping 12 matching lines...) Expand all
4058 Index = Var2; 4053 Index = Var2;
4059 Shift = 0; // should already have been 0 4054 Shift = 0; // should already have been 0
4060 Reason = BaseInst; 4055 Reason = BaseInst;
4061 return true; 4056 return true;
4062 } 4057 }
4063 } 4058 }
4064 } 4059 }
4065 return false; 4060 return false;
4066 } 4061 }
4067 4062
4068 bool matchShiftedIndex(const VariablesMetadata *VMetadata, Variable *&Index, 4063 inline bool matchShiftedIndex(const VariablesMetadata *VMetadata,
4069 uint16_t &Shift, const Inst *&Reason) { 4064 Variable *&Index, uint16_t &Shift,
4065 const Inst *&Reason) {
4070 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==> 4066 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==>
4071 // Index=Var, Shift+=log2(Const) 4067 // Index=Var, Shift+=log2(Const)
4072 if (Index == nullptr) 4068 if (Index == nullptr)
4073 return false; 4069 return false;
4074 const Inst *IndexInst = VMetadata->getSingleDefinition(Index); 4070 const Inst *IndexInst = VMetadata->getSingleDefinition(Index);
4075 if (IndexInst == nullptr) 4071 if (IndexInst == nullptr)
4076 return false; 4072 return false;
4077 assert(!VMetadata->isMultiDef(Index)); 4073 assert(!VMetadata->isMultiDef(Index));
4078 if (IndexInst->getSrcSize() < 2) 4074 if (IndexInst->getSrcSize() < 2)
4079 return false; 4075 return false;
(...skipping 28 matching lines...) Expand all
4108 Reason = IndexInst; 4104 Reason = IndexInst;
4109 return true; 4105 return true;
4110 } 4106 }
4111 } 4107 }
4112 } 4108 }
4113 } 4109 }
4114 } 4110 }
4115 return false; 4111 return false;
4116 } 4112 }
4117 4113
4118 bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base, 4114 inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
4119 int32_t &Offset, const Inst *&Reason) { 4115 int32_t &Offset, const Inst *&Reason) {
4120 // Base is Base=Var+Const || Base is Base=Const+Var ==> 4116 // Base is Base=Var+Const || Base is Base=Const+Var ==>
4121 // set Base=Var, Offset+=Const 4117 // set Base=Var, Offset+=Const
4122 // Base is Base=Var-Const ==> 4118 // Base is Base=Var-Const ==>
4123 // set Base=Var, Offset-=Const 4119 // set Base=Var, Offset-=Const
4124 if (Base == nullptr) 4120 if (Base == nullptr)
4125 return false; 4121 return false;
4126 const Inst *BaseInst = VMetadata->getSingleDefinition(Base); 4122 const Inst *BaseInst = VMetadata->getSingleDefinition(Base);
4127 if (BaseInst == nullptr) 4123 if (BaseInst == nullptr)
4128 return false; 4124 return false;
4129 assert(!VMetadata->isMultiDef(Base)); 4125 assert(!VMetadata->isMultiDef(Base));
(...skipping 19 matching lines...) Expand all
4149 if (Utils::WouldOverflowAdd(Offset, MoreOffset)) 4145 if (Utils::WouldOverflowAdd(Offset, MoreOffset))
4150 return false; 4146 return false;
4151 Base = Var; 4147 Base = Var;
4152 Offset += MoreOffset; 4148 Offset += MoreOffset;
4153 Reason = BaseInst; 4149 Reason = BaseInst;
4154 return true; 4150 return true;
4155 } 4151 }
4156 return false; 4152 return false;
4157 } 4153 }
4158 4154
4159 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, 4155 inline void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base,
4160 Variable *&Index, uint16_t &Shift, int32_t &Offset) { 4156 Variable *&Index, uint16_t &Shift,
4157 int32_t &Offset) {
4161 Func->resetCurrentNode(); 4158 Func->resetCurrentNode();
4162 if (Func->isVerbose(IceV_AddrOpt)) { 4159 if (Func->isVerbose(IceV_AddrOpt)) {
4163 OstreamLocker L(Func->getContext()); 4160 OstreamLocker L(Func->getContext());
4164 Ostream &Str = Func->getContext()->getStrDump(); 4161 Ostream &Str = Func->getContext()->getStrDump();
4165 Str << "\nStarting computeAddressOpt for instruction:\n "; 4162 Str << "\nStarting computeAddressOpt for instruction:\n ";
4166 Instr->dumpDecorated(Func); 4163 Instr->dumpDecorated(Func);
4167 } 4164 }
4168 (void)Offset; // TODO: pattern-match for non-zero offsets. 4165 (void)Offset; // TODO: pattern-match for non-zero offsets.
4169 if (Base == nullptr) 4166 if (Base == nullptr)
4170 return; 4167 return;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
4339 } 4336 }
4340 // Lower select without Traits::SSE4.1: 4337 // Lower select without Traits::SSE4.1:
4341 // a=d?b:c ==> 4338 // a=d?b:c ==>
4342 // if elementtype(d) != i1: 4339 // if elementtype(d) != i1:
4343 // d=sext(d); 4340 // d=sext(d);
4344 // a=(b&d)|(c&~d); 4341 // a=(b&d)|(c&~d);
4345 Variable *T2 = makeReg(SrcTy); 4342 Variable *T2 = makeReg(SrcTy);
4346 // Sign extend the condition operand if applicable. 4343 // Sign extend the condition operand if applicable.
4347 if (SrcTy == IceType_v4f32) { 4344 if (SrcTy == IceType_v4f32) {
4348 // The sext operation takes only integer arguments. 4345 // The sext operation takes only integer arguments.
4349 Variable *T3 = Func->template makeVariable(IceType_v4i32); 4346 Variable *T3 = Func->makeVariable(IceType_v4i32);
4350 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition)); 4347 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition));
4351 _movp(T, T3); 4348 _movp(T, T3);
4352 } else if (typeElementType(SrcTy) != IceType_i1) { 4349 } else if (typeElementType(SrcTy) != IceType_i1) {
4353 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition)); 4350 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition));
4354 } else { 4351 } else {
4355 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); 4352 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem);
4356 _movp(T, ConditionRM); 4353 _movp(T, ConditionRM);
4357 } 4354 }
4358 _movp(T2, T); 4355 _movp(T2, T);
4359 _pand(T, SrcTRM); 4356 _pand(T, SrcTRM);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 assert(isVectorType(Dest->getType())); 4541 assert(isVectorType(Dest->getType()));
4545 Type Ty = Dest->getType(); 4542 Type Ty = Dest->getType();
4546 Type ElementTy = typeElementType(Ty); 4543 Type ElementTy = typeElementType(Ty);
4547 SizeT NumElements = typeNumElements(Ty); 4544 SizeT NumElements = typeNumElements(Ty);
4548 4545
4549 Operand *T = Ctx->getConstantUndef(Ty); 4546 Operand *T = Ctx->getConstantUndef(Ty);
4550 for (SizeT I = 0; I < NumElements; ++I) { 4547 for (SizeT I = 0; I < NumElements; ++I) {
4551 Constant *Index = Ctx->getConstantInt32(I); 4548 Constant *Index = Ctx->getConstantInt32(I);
4552 4549
4553 // Extract the next two inputs. 4550 // Extract the next two inputs.
4554 Variable *Op0 = Func->template makeVariable(ElementTy); 4551 Variable *Op0 = Func->makeVariable(ElementTy);
4555 lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index)); 4552 lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index));
4556 Variable *Op1 = Func->template makeVariable(ElementTy); 4553 Variable *Op1 = Func->makeVariable(ElementTy);
4557 lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index)); 4554 lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index));
4558 4555
4559 // Perform the arithmetic as a scalar operation. 4556 // Perform the arithmetic as a scalar operation.
4560 Variable *Res = Func->template makeVariable(ElementTy); 4557 Variable *Res = Func->makeVariable(ElementTy);
4561 lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1)); 4558 lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1));
4562 4559
4563 // Insert the result into position. 4560 // Insert the result into position.
4564 Variable *DestT = Func->template makeVariable(Ty); 4561 Variable *DestT = Func->makeVariable(Ty);
4565 lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index)); 4562 lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index));
4566 T = DestT; 4563 T = DestT;
4567 } 4564 }
4568 4565
4569 lowerAssign(InstAssign::create(Func, Dest, T)); 4566 lowerAssign(InstAssign::create(Func, Dest, T));
4570 } 4567 }
4571 4568
4572 /// The following pattern occurs often in lowered C and C++ code: 4569 /// The following pattern occurs often in lowered C and C++ code:
4573 /// 4570 ///
4574 /// %cmp = fcmp/icmp pred <n x ty> %src0, %src1 4571 /// %cmp = fcmp/icmp pred <n x ty> %src0, %src1
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
4714 PhiLo->addArgument(loOperand(Src), Label); 4711 PhiLo->addArgument(loOperand(Src), Label);
4715 PhiHi->addArgument(hiOperand(Src), Label); 4712 PhiHi->addArgument(hiOperand(Src), Label);
4716 } 4713 }
4717 Node->getPhis().push_back(PhiLo); 4714 Node->getPhis().push_back(PhiLo);
4718 Node->getPhis().push_back(PhiHi); 4715 Node->getPhis().push_back(PhiHi);
4719 Phi->setDeleted(); 4716 Phi->setDeleted();
4720 } 4717 }
4721 } 4718 }
4722 } 4719 }
4723 4720
4724 bool isMemoryOperand(const Operand *Opnd) { 4721 inline bool isMemoryOperand(const Operand *Opnd) {
4725 if (const auto Var = llvm::dyn_cast<Variable>(Opnd)) 4722 if (const auto Var = llvm::dyn_cast<Variable>(Opnd))
4726 return !Var->hasReg(); 4723 return !Var->hasReg();
4727 // We treat vector undef values the same as a memory operand, 4724 // We treat vector undef values the same as a memory operand,
4728 // because they do in fact need a register to materialize the vector 4725 // because they do in fact need a register to materialize the vector
4729 // of zeroes into. 4726 // of zeroes into.
4730 if (llvm::isa<ConstantUndef>(Opnd)) 4727 if (llvm::isa<ConstantUndef>(Opnd))
4731 return isScalarFloatingType(Opnd->getType()) || 4728 return isScalarFloatingType(Opnd->getType()) ||
4732 isVectorType(Opnd->getType()); 4729 isVectorType(Opnd->getType());
4733 if (llvm::isa<Constant>(Opnd)) 4730 if (llvm::isa<Constant>(Opnd))
4734 return isScalarFloatingType(Opnd->getType()); 4731 return isScalarFloatingType(Opnd->getType());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
4827 Variable *Preg = nullptr; 4824 Variable *Preg = nullptr;
4828 // TODO(stichnot): Opportunity for register randomization. 4825 // TODO(stichnot): Opportunity for register randomization.
4829 int32_t RegNum = AvailRegsForType.find_first(); 4826 int32_t RegNum = AvailRegsForType.find_first();
4830 bool IsVector = isVectorType(Dest->getType()); 4827 bool IsVector = isVectorType(Dest->getType());
4831 bool NeedSpill = (RegNum == -1); 4828 bool NeedSpill = (RegNum == -1);
4832 if (NeedSpill) { 4829 if (NeedSpill) {
4833 // Pick some register to spill and update RegNum. 4830 // Pick some register to spill and update RegNum.
4834 // TODO(stichnot): Opportunity for register randomization. 4831 // TODO(stichnot): Opportunity for register randomization.
4835 RegNum = RegsForType.find_first(); 4832 RegNum = RegsForType.find_first();
4836 Preg = getPhysicalRegister(RegNum, Dest->getType()); 4833 Preg = getPhysicalRegister(RegNum, Dest->getType());
4837 SpillLoc = Func->template makeVariable(Dest->getType()); 4834 SpillLoc = Func->makeVariable(Dest->getType());
4838 // Create a fake def of the physical register to avoid 4835 // Create a fake def of the physical register to avoid
4839 // liveness inconsistency problems during late-stage liveness 4836 // liveness inconsistency problems during late-stage liveness
4840 // analysis (e.g. asm-verbose mode). 4837 // analysis (e.g. asm-verbose mode).
4841 Context.insert(InstFakeDef::create(Func, Preg)); 4838 Context.insert(InstFakeDef::create(Func, Preg));
4842 if (IsVector) 4839 if (IsVector)
4843 _movp(SpillLoc, Preg); 4840 _movp(SpillLoc, Preg);
4844 else 4841 else
4845 _mov(SpillLoc, Preg); 4842 _mov(SpillLoc, Preg);
4846 } 4843 }
4847 assert(RegNum >= 0); 4844 assert(RegNum >= 0);
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
5157 // Do legalization, which contains randomization/pooling 5154 // Do legalization, which contains randomization/pooling
5158 // or do randomization/pooling. 5155 // or do randomization/pooling.
5159 return llvm::cast<typename Traits::X86OperandMem>( 5156 return llvm::cast<typename Traits::X86OperandMem>(
5160 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem)); 5157 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
5161 } 5158 }
5162 5159
5163 template <class Machine> 5160 template <class Machine>
5164 Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) { 5161 Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) {
5165 // There aren't any 64-bit integer registers for x86-32. 5162 // There aren't any 64-bit integer registers for x86-32.
5166 assert(Type != IceType_i64); 5163 assert(Type != IceType_i64);
5167 Variable *Reg = Func->template makeVariable(Type); 5164 Variable *Reg = Func->makeVariable(Type);
5168 if (RegNum == Variable::NoRegister) 5165 if (RegNum == Variable::NoRegister)
5169 Reg->setWeightInfinite(); 5166 Reg->setWeightInfinite();
5170 else 5167 else
5171 Reg->setRegNum(RegNum); 5168 Reg->setRegNum(RegNum);
5172 return Reg; 5169 return Reg;
5173 } 5170 }
5174 5171
5175 template <class Machine> void TargetX86Base<Machine>::postLower() { 5172 template <class Machine> void TargetX86Base<Machine>::postLower() {
5176 if (Ctx->getFlags().getOptLevel() == Opt_m1) 5173 if (Ctx->getFlags().getOptLevel() == Opt_m1)
5177 return; 5174 return;
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
5419 } 5416 }
5420 // the offset is not eligible for blinding or pooling, return the original 5417 // the offset is not eligible for blinding or pooling, return the original
5421 // mem operand 5418 // mem operand
5422 return MemOperand; 5419 return MemOperand;
5423 } 5420 }
5424 5421
5425 } // end of namespace X86Internal 5422 } // end of namespace X86Internal
5426 } // end of namespace Ice 5423 } // end of namespace Ice
5427 5424
5428 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H 5425 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H
OLDNEW
« src/IceTargetLoweringX86Base.h ('K') | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698