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

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: git pull 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
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | 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/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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 260 }
261 261
262 template <class Machine> 262 template <class Machine>
263 void TargetX86Base<Machine>::initNodeForLowering(CfgNode *Node) { 263 void TargetX86Base<Machine>::initNodeForLowering(CfgNode *Node) {
264 FoldingInfo.init(Node); 264 FoldingInfo.init(Node);
265 FoldingInfo.dump(Func); 265 FoldingInfo.dump(Func);
266 } 266 }
267 267
268 template <class Machine> 268 template <class Machine>
269 TargetX86Base<Machine>::TargetX86Base(Cfg *Func) 269 TargetX86Base<Machine>::TargetX86Base(Cfg *Func)
270 : Machine(Func) { 270 : TargetLowering(Func) {
271 static_assert( 271 static_assert(
272 (Traits::InstructionSet::End - Traits::InstructionSet::Begin) == 272 (Traits::InstructionSet::End - Traits::InstructionSet::Begin) ==
273 (TargetInstructionSet::X86InstructionSet_End - 273 (TargetInstructionSet::X86InstructionSet_End -
274 TargetInstructionSet::X86InstructionSet_Begin), 274 TargetInstructionSet::X86InstructionSet_Begin),
275 "Traits::InstructionSet range different from TargetInstructionSet"); 275 "Traits::InstructionSet range different from TargetInstructionSet");
276 if (Func->getContext()->getFlags().getTargetInstructionSet() != 276 if (Func->getContext()->getFlags().getTargetInstructionSet() !=
277 TargetInstructionSet::BaseInstructionSet) { 277 TargetInstructionSet::BaseInstructionSet) {
278 InstructionSet = static_cast<typename Traits::InstructionSet>( 278 InstructionSet = static_cast<typename Traits::InstructionSet>(
279 (Func->getContext()->getFlags().getTargetInstructionSet() - 279 (Func->getContext()->getFlags().getTargetInstructionSet() -
280 TargetInstructionSet::X86InstructionSet_Begin) + 280 TargetInstructionSet::X86InstructionSet_Begin) +
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 if (Func->hasError()) 448 if (Func->hasError())
449 return; 449 return;
450 Func->dump("After stack frame mapping"); 450 Func->dump("After stack frame mapping");
451 451
452 // Nop insertion 452 // Nop insertion
453 if (Ctx->getFlags().shouldDoNopInsertion()) { 453 if (Ctx->getFlags().shouldDoNopInsertion()) {
454 Func->doNopInsertion(); 454 Func->doNopInsertion();
455 } 455 }
456 } 456 }
457 457
458 bool canRMW(const InstArithmetic *Arith) { 458 inline bool canRMW(const InstArithmetic *Arith) {
459 Type Ty = Arith->getDest()->getType(); 459 Type Ty = Arith->getDest()->getType();
460 // X86 vector instructions write to a register and have no RMW option. 460 // X86 vector instructions write to a register and have no RMW option.
461 if (isVectorType(Ty)) 461 if (isVectorType(Ty))
462 return false; 462 return false;
463 bool isI64 = Ty == IceType_i64; 463 bool isI64 = Ty == IceType_i64;
464 464
465 switch (Arith->getOp()) { 465 switch (Arith->getOp()) {
466 // Not handled for lack of simple lowering: 466 // Not handled for lack of simple lowering:
467 // shift on i64 467 // shift on i64
468 // mul, udiv, urem, sdiv, srem, frem 468 // mul, udiv, urem, sdiv, srem, frem
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 continue; 572 continue;
573 if (Func->isVerbose(IceV_RMW)) { 573 if (Func->isVerbose(IceV_RMW)) {
574 Str << "Found RMW in " << Func->getFunctionName() << ":\n "; 574 Str << "Found RMW in " << Func->getFunctionName() << ":\n ";
575 Load->dump(Func); 575 Load->dump(Func);
576 Str << "\n "; 576 Str << "\n ";
577 Arith->dump(Func); 577 Arith->dump(Func);
578 Str << "\n "; 578 Str << "\n ";
579 Store->dump(Func); 579 Store->dump(Func);
580 Str << "\n"; 580 Str << "\n";
581 } 581 }
582 Variable *Beacon = Func->template makeVariable(IceType_i32); 582 Variable *Beacon = Func->makeVariable(IceType_i32);
583 Beacon->setWeight(0); 583 Beacon->setWeight(0);
584 Store->setRmwBeacon(Beacon); 584 Store->setRmwBeacon(Beacon);
585 InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon); 585 InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon);
586 Node->getInsts().insert(I3, BeaconDef); 586 Node->getInsts().insert(I3, BeaconDef);
587 auto *RMW = Traits::Insts::FakeRMW::create( 587 auto *RMW = Traits::Insts::FakeRMW::create(
588 Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp()); 588 Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp());
589 Node->getInsts().insert(I3, RMW); 589 Node->getInsts().insert(I3, RMW);
590 } 590 }
591 } 591 }
592 } 592 }
593 } 593 }
594 } 594 }
595 } 595 }
596 596
597 // Converts a ConstantInteger32 operand into its constant value, or 597 // Converts a ConstantInteger32 operand into its constant value, or
598 // MemoryOrderInvalid if the operand is not a ConstantInteger32. 598 // MemoryOrderInvalid if the operand is not a ConstantInteger32.
599 uint64_t getConstantMemoryOrder(Operand *Opnd) { 599 inline uint64_t getConstantMemoryOrder(Operand *Opnd) {
600 if (auto Integer = llvm::dyn_cast<ConstantInteger32>(Opnd)) 600 if (auto Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
601 return Integer->getValue(); 601 return Integer->getValue();
602 return Intrinsics::MemoryOrderInvalid; 602 return Intrinsics::MemoryOrderInvalid;
603 } 603 }
604 604
605 /// Determines whether the dest of a Load instruction can be folded 605 /// Determines whether the dest of a Load instruction can be folded
606 /// into one of the src operands of a 2-operand instruction. This is 606 /// into one of the src operands of a 2-operand instruction. This is
607 /// true as long as the load dest matches exactly one of the binary 607 /// true as long as the load dest matches exactly one of the binary
608 /// instruction's src operands. Replaces Src0 or Src1 with LoadSrc if 608 /// instruction's src operands. Replaces Src0 or Src1 with LoadSrc if
609 /// the answer is true. 609 /// the answer is true.
610 bool canFoldLoadIntoBinaryInst(Operand *LoadSrc, Variable *LoadDest, 610 inline bool canFoldLoadIntoBinaryInst(Operand *LoadSrc, Variable *LoadDest,
611 Operand *&Src0, Operand *&Src1) { 611 Operand *&Src0, Operand *&Src1) {
612 if (Src0 == LoadDest && Src1 != LoadDest) { 612 if (Src0 == LoadDest && Src1 != LoadDest) {
613 Src0 = LoadSrc; 613 Src0 = LoadSrc;
614 return true; 614 return true;
615 } 615 }
616 if (Src0 != LoadDest && Src1 == LoadDest) { 616 if (Src0 != LoadDest && Src1 == LoadDest) {
617 Src1 = LoadSrc; 617 Src1 = LoadSrc;
618 return true; 618 return true;
619 } 619 }
620 return false; 620 return false;
621 } 621 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 720
721 template <class Machine> 721 template <class Machine>
722 Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) { 722 Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) {
723 if (Ty == IceType_void) 723 if (Ty == IceType_void)
724 Ty = IceType_i32; 724 Ty = IceType_i32;
725 if (PhysicalRegisters[Ty].empty()) 725 if (PhysicalRegisters[Ty].empty())
726 PhysicalRegisters[Ty].resize(Traits::RegisterSet::Reg_NUM); 726 PhysicalRegisters[Ty].resize(Traits::RegisterSet::Reg_NUM);
727 assert(RegNum < PhysicalRegisters[Ty].size()); 727 assert(RegNum < PhysicalRegisters[Ty].size());
728 Variable *Reg = PhysicalRegisters[Ty][RegNum]; 728 Variable *Reg = PhysicalRegisters[Ty][RegNum];
729 if (Reg == nullptr) { 729 if (Reg == nullptr) {
730 Reg = Func->template makeVariable(Ty); 730 Reg = Func->makeVariable(Ty);
731 Reg->setRegNum(RegNum); 731 Reg->setRegNum(RegNum);
732 PhysicalRegisters[Ty][RegNum] = Reg; 732 PhysicalRegisters[Ty][RegNum] = Reg;
733 // Specially mark esp as an "argument" so that it is considered 733 // Specially mark esp as an "argument" so that it is considered
734 // live upon function entry. 734 // live upon function entry.
735 if (RegNum == Traits::RegisterSet::Reg_esp) { 735 if (RegNum == Traits::RegisterSet::Reg_esp) {
736 Func->addImplicitArg(Reg); 736 Func->addImplicitArg(Reg);
737 Reg->setIgnoreLiveness(); 737 Reg->setIgnoreLiveness();
738 } 738 }
739 } 739 }
740 return Reg; 740 return Reg;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 I < E && NumXmmArgs < Traits::X86_MAX_XMM_ARGS; ++I) { 793 I < E && NumXmmArgs < Traits::X86_MAX_XMM_ARGS; ++I) {
794 Variable *Arg = Args[I]; 794 Variable *Arg = Args[I];
795 Type Ty = Arg->getType(); 795 Type Ty = Arg->getType();
796 if (!isVectorType(Ty)) 796 if (!isVectorType(Ty))
797 continue; 797 continue;
798 // Replace Arg in the argument list with the home register. Then 798 // Replace Arg in the argument list with the home register. Then
799 // generate an instruction in the prolog to copy the home register 799 // generate an instruction in the prolog to copy the home register
800 // to the assigned location of Arg. 800 // to the assigned location of Arg.
801 int32_t RegNum = Traits::RegisterSet::Reg_xmm0 + NumXmmArgs; 801 int32_t RegNum = Traits::RegisterSet::Reg_xmm0 + NumXmmArgs;
802 ++NumXmmArgs; 802 ++NumXmmArgs;
803 Variable *RegisterArg = Func->template makeVariable(Ty); 803 Variable *RegisterArg = Func->makeVariable(Ty);
804 if (BuildDefs::dump()) 804 if (BuildDefs::dump())
805 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); 805 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
806 RegisterArg->setRegNum(RegNum); 806 RegisterArg->setRegNum(RegNum);
807 RegisterArg->setIsArg(); 807 RegisterArg->setIsArg();
808 Arg->setIsArg(false); 808 Arg->setIsArg(false);
809 809
810 Args[I] = RegisterArg; 810 Args[I] = RegisterArg;
811 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); 811 Context.insert(InstAssign::create(Func, Arg, RegisterArg));
812 } 812 }
813 } 813 }
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 1108
1109 if (!Ctx->getFlags().getUseSandboxing()) 1109 if (!Ctx->getFlags().getUseSandboxing())
1110 return; 1110 return;
1111 // Change the original ret instruction into a sandboxed return sequence. 1111 // Change the original ret instruction into a sandboxed return sequence.
1112 // t:ecx = pop 1112 // t:ecx = pop
1113 // bundle_lock 1113 // bundle_lock
1114 // and t, ~31 1114 // and t, ~31
1115 // jmp *t 1115 // jmp *t
1116 // bundle_unlock 1116 // bundle_unlock
1117 // FakeUse <original_ret_operand> 1117 // FakeUse <original_ret_operand>
1118 const SizeT BundleSize = 1118 const SizeT BundleSize = 1
1119 1 << Func->template getAssembler<>()->getBundleAlignLog2Bytes(); 1119 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
1120 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx); 1120 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
1121 _pop(T_ecx); 1121 _pop(T_ecx);
1122 _bundle_lock(); 1122 _bundle_lock();
1123 _and(T_ecx, Ctx->getConstantInt32(~(BundleSize - 1))); 1123 _and(T_ecx, Ctx->getConstantInt32(~(BundleSize - 1)));
1124 _jmp(T_ecx); 1124 _jmp(T_ecx);
1125 _bundle_unlock(); 1125 _bundle_unlock();
1126 if (RI->getSrcSize()) { 1126 if (RI->getSrcSize()) {
1127 Variable *RetValue = llvm::cast<Variable>(RI->getSrc(0)); 1127 Variable *RetValue = llvm::cast<Variable>(RI->getSrc(0));
1128 Context.insert(InstFakeUse::create(Func, RetValue)); 1128 Context.insert(InstFakeUse::create(Func, RetValue));
1129 } 1129 }
(...skipping 11 matching lines...) Expand all
1141 case IceType_f64: 1141 case IceType_f64:
1142 break; 1142 break;
1143 } 1143 }
1144 Variable *Lo = Var->getLo(); 1144 Variable *Lo = Var->getLo();
1145 Variable *Hi = Var->getHi(); 1145 Variable *Hi = Var->getHi();
1146 if (Lo) { 1146 if (Lo) {
1147 assert(Hi); 1147 assert(Hi);
1148 return; 1148 return;
1149 } 1149 }
1150 assert(Hi == nullptr); 1150 assert(Hi == nullptr);
1151 Lo = Func->template makeVariable(IceType_i32); 1151 Lo = Func->makeVariable(IceType_i32);
1152 Hi = Func->template makeVariable(IceType_i32); 1152 Hi = Func->makeVariable(IceType_i32);
1153 if (BuildDefs::dump()) { 1153 if (BuildDefs::dump()) {
1154 Lo->setName(Func, Var->getName(Func) + "__lo"); 1154 Lo->setName(Func, Var->getName(Func) + "__lo");
1155 Hi->setName(Func, Var->getName(Func) + "__hi"); 1155 Hi->setName(Func, Var->getName(Func) + "__hi");
1156 } 1156 }
1157 Var->setLoHi(Lo, Hi); 1157 Var->setLoHi(Lo, Hi);
1158 if (Var->getIsArg()) { 1158 if (Var->getIsArg()) {
1159 Lo->setIsArg(); 1159 Lo->setIsArg();
1160 Hi->setIsArg(); 1160 Hi->setIsArg();
1161 } 1161 }
1162 } 1162 }
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
2234 Operand *CallTarget = legalize(Instr->getCallTarget()); 2234 Operand *CallTarget = legalize(Instr->getCallTarget());
2235 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); 2235 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
2236 if (NeedSandboxing) { 2236 if (NeedSandboxing) {
2237 if (llvm::isa<Constant>(CallTarget)) { 2237 if (llvm::isa<Constant>(CallTarget)) {
2238 _bundle_lock(InstBundleLock::Opt_AlignToEnd); 2238 _bundle_lock(InstBundleLock::Opt_AlignToEnd);
2239 } else { 2239 } else {
2240 Variable *CallTargetVar = nullptr; 2240 Variable *CallTargetVar = nullptr;
2241 _mov(CallTargetVar, CallTarget); 2241 _mov(CallTargetVar, CallTarget);
2242 _bundle_lock(InstBundleLock::Opt_AlignToEnd); 2242 _bundle_lock(InstBundleLock::Opt_AlignToEnd);
2243 const SizeT BundleSize = 2243 const SizeT BundleSize =
2244 1 << Func->template getAssembler<>()->getBundleAlignLog2Bytes(); 2244 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
2245 _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1))); 2245 _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1)));
2246 CallTarget = CallTargetVar; 2246 CallTarget = CallTargetVar;
2247 } 2247 }
2248 } 2248 }
2249 Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget); 2249 Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget);
2250 Context.insert(NewCall); 2250 Context.insert(NewCall);
2251 if (NeedSandboxing) 2251 if (NeedSandboxing)
2252 _bundle_unlock(); 2252 _bundle_unlock();
2253 if (ReturnRegHi) 2253 if (ReturnRegHi)
2254 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); 2254 Context.insert(InstFakeDef::create(Func, ReturnRegHi));
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
2663 assert((DestType == IceType_i32 && SrcType == IceType_f32) || 2663 assert((DestType == IceType_i32 && SrcType == IceType_f32) ||
2664 (DestType == IceType_f32 && SrcType == IceType_i32)); 2664 (DestType == IceType_f32 && SrcType == IceType_i32));
2665 // a.i32 = bitcast b.f32 ==> 2665 // a.i32 = bitcast b.f32 ==>
2666 // t.f32 = b.f32 2666 // t.f32 = b.f32
2667 // s.f32 = spill t.f32 2667 // s.f32 = spill t.f32
2668 // a.i32 = s.f32 2668 // a.i32 = s.f32
2669 Variable *T = nullptr; 2669 Variable *T = nullptr;
2670 // TODO: Should be able to force a spill setup by calling legalize() with 2670 // TODO: Should be able to force a spill setup by calling legalize() with
2671 // Legal_Mem and not Legal_Reg or Legal_Imm. 2671 // Legal_Mem and not Legal_Reg or Legal_Imm.
2672 typename Traits::SpillVariable *SpillVar = 2672 typename Traits::SpillVariable *SpillVar =
2673 Func->template makeVariable<typename Traits::SpillVariable>(SrcType); 2673 Func->makeVariable<typename Traits::SpillVariable>(SrcType);
2674 SpillVar->setLinkedTo(Dest); 2674 SpillVar->setLinkedTo(Dest);
2675 Variable *Spill = SpillVar; 2675 Variable *Spill = SpillVar;
2676 Spill->setWeight(RegWeight::Zero); 2676 Spill->setWeight(RegWeight::Zero);
2677 _mov(T, Src0RM); 2677 _mov(T, Src0RM);
2678 _mov(Spill, T); 2678 _mov(Spill, T);
2679 _mov(Dest, Spill); 2679 _mov(Dest, Spill);
2680 } break; 2680 } break;
2681 case IceType_i64: { 2681 case IceType_i64: {
2682 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2682 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2683 assert(Src0RM->getType() == IceType_f64); 2683 assert(Src0RM->getType() == IceType_f64);
2684 // a.i64 = bitcast b.f64 ==> 2684 // a.i64 = bitcast b.f64 ==>
2685 // s.f64 = spill b.f64 2685 // s.f64 = spill b.f64
2686 // t_lo.i32 = lo(s.f64) 2686 // t_lo.i32 = lo(s.f64)
2687 // a_lo.i32 = t_lo.i32 2687 // a_lo.i32 = t_lo.i32
2688 // t_hi.i32 = hi(s.f64) 2688 // t_hi.i32 = hi(s.f64)
2689 // a_hi.i32 = t_hi.i32 2689 // a_hi.i32 = t_hi.i32
2690 Operand *SpillLo, *SpillHi; 2690 Operand *SpillLo, *SpillHi;
2691 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) { 2691 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) {
2692 typename Traits::SpillVariable *SpillVar = 2692 typename Traits::SpillVariable *SpillVar =
2693 Func->template makeVariable<typename Traits::SpillVariable>( 2693 Func->makeVariable<typename Traits::SpillVariable>(IceType_f64);
2694 IceType_f64);
2695 SpillVar->setLinkedTo(Src0Var); 2694 SpillVar->setLinkedTo(Src0Var);
2696 Variable *Spill = SpillVar; 2695 Variable *Spill = SpillVar;
2697 Spill->setWeight(RegWeight::Zero); 2696 Spill->setWeight(RegWeight::Zero);
2698 _movq(Spill, Src0RM); 2697 _movq(Spill, Src0RM);
2699 SpillLo = Traits::VariableSplit::create(Func, Spill, 2698 SpillLo = Traits::VariableSplit::create(Func, Spill,
2700 Traits::VariableSplit::Low); 2699 Traits::VariableSplit::Low);
2701 SpillHi = Traits::VariableSplit::create(Func, Spill, 2700 SpillHi = Traits::VariableSplit::create(Func, Spill,
2702 Traits::VariableSplit::High); 2701 Traits::VariableSplit::High);
2703 } else { 2702 } else {
2704 SpillLo = loOperand(Src0RM); 2703 SpillLo = loOperand(Src0RM);
2705 SpillHi = hiOperand(Src0RM); 2704 SpillHi = hiOperand(Src0RM);
2706 } 2705 }
2707 2706
2708 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2707 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2709 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2708 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2710 Variable *T_Lo = makeReg(IceType_i32); 2709 Variable *T_Lo = makeReg(IceType_i32);
2711 Variable *T_Hi = makeReg(IceType_i32); 2710 Variable *T_Hi = makeReg(IceType_i32);
2712 2711
2713 _mov(T_Lo, SpillLo); 2712 _mov(T_Lo, SpillLo);
2714 _mov(DestLo, T_Lo); 2713 _mov(DestLo, T_Lo);
2715 _mov(T_Hi, SpillHi); 2714 _mov(T_Hi, SpillHi);
2716 _mov(DestHi, T_Hi); 2715 _mov(DestHi, T_Hi);
2717 } break; 2716 } break;
2718 case IceType_f64: { 2717 case IceType_f64: {
2719 Src0 = legalize(Src0); 2718 Src0 = legalize(Src0);
2720 assert(Src0->getType() == IceType_i64); 2719 assert(Src0->getType() == IceType_i64);
2721 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) { 2720 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) {
2722 Variable *T = Func->template makeVariable(Dest->getType()); 2721 Variable *T = Func->makeVariable(Dest->getType());
2723 _movq(T, Src0); 2722 _movq(T, Src0);
2724 _movq(Dest, T); 2723 _movq(Dest, T);
2725 break; 2724 break;
2726 } 2725 }
2727 // a.f64 = bitcast b.i64 ==> 2726 // a.f64 = bitcast b.i64 ==>
2728 // t_lo.i32 = b_lo.i32 2727 // t_lo.i32 = b_lo.i32
2729 // FakeDef(s.f64) 2728 // FakeDef(s.f64)
2730 // lo(s.f64) = t_lo.i32 2729 // lo(s.f64) = t_lo.i32
2731 // t_hi.i32 = b_hi.i32 2730 // t_hi.i32 = b_hi.i32
2732 // hi(s.f64) = t_hi.i32 2731 // hi(s.f64) = t_hi.i32
2733 // a.f64 = s.f64 2732 // a.f64 = s.f64
2734 typename Traits::SpillVariable *SpillVar = 2733 typename Traits::SpillVariable *SpillVar =
2735 Func->template makeVariable<typename Traits::SpillVariable>( 2734 Func->makeVariable<typename Traits::SpillVariable>(IceType_f64);
2736 IceType_f64);
2737 SpillVar->setLinkedTo(Dest); 2735 SpillVar->setLinkedTo(Dest);
2738 Variable *Spill = SpillVar; 2736 Variable *Spill = SpillVar;
2739 Spill->setWeight(RegWeight::Zero); 2737 Spill->setWeight(RegWeight::Zero);
2740 2738
2741 Variable *T_Lo = nullptr, *T_Hi = nullptr; 2739 Variable *T_Lo = nullptr, *T_Hi = nullptr;
2742 typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create( 2740 typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create(
2743 Func, Spill, Traits::VariableSplit::Low); 2741 Func, Spill, Traits::VariableSplit::Low);
2744 typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create( 2742 typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create(
2745 Func, Spill, Traits::VariableSplit::High); 2743 Func, Spill, Traits::VariableSplit::High);
2746 _mov(T_Lo, loOperand(Src0)); 2744 _mov(T_Lo, loOperand(Src0));
2747 // Technically, the Spill is defined after the _store happens, but 2745 // Technically, the Spill is defined after the _store happens, but
2748 // SpillLo is considered a "use" of Spill so define Spill before it 2746 // SpillLo is considered a "use" of Spill so define Spill before it
2749 // is used. 2747 // is used.
2750 Context.insert(InstFakeDef::create(Func, Spill)); 2748 Context.insert(InstFakeDef::create(Func, Spill));
2751 _store(T_Lo, SpillLo); 2749 _store(T_Lo, SpillLo);
2752 _mov(T_Hi, hiOperand(Src0)); 2750 _mov(T_Hi, hiOperand(Src0));
2753 _store(T_Hi, SpillHi); 2751 _store(T_Hi, SpillHi);
2754 _movq(Dest, Spill); 2752 _movq(Dest, Spill);
2755 } break; 2753 } break;
2756 case IceType_v8i1: { 2754 case IceType_v8i1: {
2757 assert(Src0->getType() == IceType_i8); 2755 assert(Src0->getType() == IceType_i8);
2758 InstCall *Call = makeHelperCall(H_bitcast_i8_8xi1, Dest, 1); 2756 InstCall *Call = makeHelperCall(H_bitcast_i8_8xi1, Dest, 1);
2759 Variable *Src0AsI32 = Func->template makeVariable(stackSlotType()); 2757 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
2760 // Arguments to functions are required to be at least 32 bits wide. 2758 // Arguments to functions are required to be at least 32 bits wide.
2761 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2759 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2762 Call->addArg(Src0AsI32); 2760 Call->addArg(Src0AsI32);
2763 lowerCall(Call); 2761 lowerCall(Call);
2764 } break; 2762 } break;
2765 case IceType_v16i1: { 2763 case IceType_v16i1: {
2766 assert(Src0->getType() == IceType_i16); 2764 assert(Src0->getType() == IceType_i16);
2767 InstCall *Call = makeHelperCall(H_bitcast_i16_16xi1, Dest, 1); 2765 InstCall *Call = makeHelperCall(H_bitcast_i16_16xi1, Dest, 1);
2768 Variable *Src0AsI32 = Func->template makeVariable(stackSlotType()); 2766 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
2769 // Arguments to functions are required to be at least 32 bits wide. 2767 // Arguments to functions are required to be at least 32 bits wide.
2770 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2768 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2771 Call->addArg(Src0AsI32); 2769 Call->addArg(Src0AsI32);
2772 lowerCall(Call); 2770 lowerCall(Call);
2773 } break; 2771 } break;
2774 case IceType_v8i16: 2772 case IceType_v8i16:
2775 case IceType_v16i8: 2773 case IceType_v16i8:
2776 case IceType_v4i32: 2774 case IceType_v4i32:
2777 case IceType_v4f32: { 2775 case IceType_v4f32: {
2778 _movp(Dest, legalizeToReg(Src0)); 2776 _movp(Dest, legalizeToReg(Src0));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2829 // keep the live range analysis consistent. 2827 // keep the live range analysis consistent.
2830 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); 2828 Context.insert(InstFakeDef::create(Func, ExtractedElementR));
2831 _movss(ExtractedElementR, T); 2829 _movss(ExtractedElementR, T);
2832 } 2830 }
2833 } else { 2831 } else {
2834 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 2832 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
2835 // Spill the value to a stack slot and do the extraction in memory. 2833 // Spill the value to a stack slot and do the extraction in memory.
2836 // 2834 //
2837 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when 2835 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
2838 // support for legalizing to mem is implemented. 2836 // support for legalizing to mem is implemented.
2839 Variable *Slot = Func->template makeVariable(Ty); 2837 Variable *Slot = Func->makeVariable(Ty);
2840 Slot->setWeight(RegWeight::Zero); 2838 Slot->setWeight(RegWeight::Zero);
2841 _movp(Slot, legalizeToReg(SourceVectNotLegalized)); 2839 _movp(Slot, legalizeToReg(SourceVectNotLegalized));
2842 2840
2843 // Compute the location of the element in memory. 2841 // Compute the location of the element in memory.
2844 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 2842 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
2845 typename Traits::X86OperandMem *Loc = 2843 typename Traits::X86OperandMem *Loc =
2846 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 2844 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
2847 _mov(ExtractedElementR, Loc); 2845 _mov(ExtractedElementR, Loc);
2848 } 2846 }
2849 2847
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2994 case IceType_v4i1: 2992 case IceType_v4i1:
2995 NewTy = IceType_v4i32; 2993 NewTy = IceType_v4i32;
2996 break; 2994 break;
2997 case IceType_v8i1: 2995 case IceType_v8i1:
2998 NewTy = IceType_v8i16; 2996 NewTy = IceType_v8i16;
2999 break; 2997 break;
3000 case IceType_v16i1: 2998 case IceType_v16i1:
3001 NewTy = IceType_v16i8; 2999 NewTy = IceType_v16i8;
3002 break; 3000 break;
3003 } 3001 }
3004 Variable *NewSrc0 = Func->template makeVariable(NewTy); 3002 Variable *NewSrc0 = Func->makeVariable(NewTy);
3005 Variable *NewSrc1 = Func->template makeVariable(NewTy); 3003 Variable *NewSrc1 = Func->makeVariable(NewTy);
3006 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0)); 3004 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0));
3007 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1)); 3005 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1));
3008 Src0 = NewSrc0; 3006 Src0 = NewSrc0;
3009 Src1 = NewSrc1; 3007 Src1 = NewSrc1;
3010 Ty = NewTy; 3008 Ty = NewTy;
3011 } 3009 }
3012 3010
3013 InstIcmp::ICond Condition = Inst->getCondition(); 3011 InstIcmp::ICond Condition = Inst->getCondition();
3014 3012
3015 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 3013 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
3137 unsigned Index = ElementIndex->getValue(); 3135 unsigned Index = ElementIndex->getValue();
3138 assert(Index < typeNumElements(SourceVectNotLegalized->getType())); 3136 assert(Index < typeNumElements(SourceVectNotLegalized->getType()));
3139 3137
3140 Type Ty = SourceVectNotLegalized->getType(); 3138 Type Ty = SourceVectNotLegalized->getType();
3141 Type ElementTy = typeElementType(Ty); 3139 Type ElementTy = typeElementType(Ty);
3142 Type InVectorElementTy = Traits::getInVectorElementType(Ty); 3140 Type InVectorElementTy = Traits::getInVectorElementType(Ty);
3143 3141
3144 if (ElementTy == IceType_i1) { 3142 if (ElementTy == IceType_i1) {
3145 // Expand the element to the appropriate size for it to be inserted 3143 // Expand the element to the appropriate size for it to be inserted
3146 // in the vector. 3144 // in the vector.
3147 Variable *Expanded = Func->template makeVariable(InVectorElementTy); 3145 Variable *Expanded = Func->makeVariable(InVectorElementTy);
3148 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded, 3146 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded,
3149 ElementToInsertNotLegalized); 3147 ElementToInsertNotLegalized);
3150 lowerCast(Cast); 3148 lowerCast(Cast);
3151 ElementToInsertNotLegalized = Expanded; 3149 ElementToInsertNotLegalized = Expanded;
3152 } 3150 }
3153 3151
3154 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 || 3152 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 ||
3155 InstructionSet >= Traits::SSE4_1) { 3153 InstructionSet >= Traits::SSE4_1) {
3156 // Use insertps, pinsrb, pinsrw, or pinsrd. 3154 // Use insertps, pinsrb, pinsrw, or pinsrd.
3157 Operand *ElementRM = 3155 Operand *ElementRM =
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3228 _shufps(T, ElementR, Mask2Constant); 3226 _shufps(T, ElementR, Mask2Constant);
3229 _movp(Inst->getDest(), T); 3227 _movp(Inst->getDest(), T);
3230 } 3228 }
3231 } else { 3229 } else {
3232 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 3230 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
3233 // Spill the value to a stack slot and perform the insertion in 3231 // Spill the value to a stack slot and perform the insertion in
3234 // memory. 3232 // memory.
3235 // 3233 //
3236 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when 3234 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
3237 // support for legalizing to mem is implemented. 3235 // support for legalizing to mem is implemented.
3238 Variable *Slot = Func->template makeVariable(Ty); 3236 Variable *Slot = Func->makeVariable(Ty);
3239 Slot->setWeight(RegWeight::Zero); 3237 Slot->setWeight(RegWeight::Zero);
3240 _movp(Slot, legalizeToReg(SourceVectNotLegalized)); 3238 _movp(Slot, legalizeToReg(SourceVectNotLegalized));
3241 3239
3242 // Compute the location of the position to insert in memory. 3240 // Compute the location of the position to insert in memory.
3243 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 3241 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
3244 typename Traits::X86OperandMem *Loc = 3242 typename Traits::X86OperandMem *Loc =
3245 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 3243 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
3246 _store(legalizeToReg(ElementToInsertNotLegalized), Loc); 3244 _store(legalizeToReg(ElementToInsertNotLegalized), Loc);
3247 3245
3248 Variable *T = makeReg(Ty); 3246 Variable *T = makeReg(Ty);
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3521 Call->addArg(Instr->getArg(1)); 3519 Call->addArg(Instr->getArg(1));
3522 Call->addArg(Instr->getArg(2)); 3520 Call->addArg(Instr->getArg(2));
3523 lowerCall(Call); 3521 lowerCall(Call);
3524 return; 3522 return;
3525 } 3523 }
3526 case Intrinsics::Memset: { 3524 case Intrinsics::Memset: {
3527 // The value operand needs to be extended to a stack slot size because the 3525 // The value operand needs to be extended to a stack slot size because the
3528 // PNaCl ABI requires arguments to be at least 32 bits wide. 3526 // PNaCl ABI requires arguments to be at least 32 bits wide.
3529 Operand *ValOp = Instr->getArg(1); 3527 Operand *ValOp = Instr->getArg(1);
3530 assert(ValOp->getType() == IceType_i8); 3528 assert(ValOp->getType() == IceType_i8);
3531 Variable *ValExt = Func->template makeVariable(stackSlotType()); 3529 Variable *ValExt = Func->makeVariable(stackSlotType());
3532 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); 3530 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp));
3533 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); 3531 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3);
3534 Call->addArg(Instr->getArg(0)); 3532 Call->addArg(Instr->getArg(0));
3535 Call->addArg(ValExt); 3533 Call->addArg(ValExt);
3536 Call->addArg(Instr->getArg(2)); 3534 Call->addArg(Instr->getArg(2));
3537 lowerCall(Call); 3535 lowerCall(Call);
3538 return; 3536 return;
3539 } 3537 }
3540 case Intrinsics::NaClReadTP: { 3538 case Intrinsics::NaClReadTP: {
3541 if (Ctx->getFlags().getUseSandboxing()) { 3539 if (Ctx->getFlags().getUseSandboxing()) {
3542 Constant *Zero = Ctx->getConstantZero(IceType_i32); 3540 Operand *Src = dispatchToConcrete(&Machine::createNaClReadTPSrcOperand);
3543 Operand *Src = Traits::X86OperandMem::create(
3544 Func, IceType_i32, nullptr, Zero, nullptr, 0,
3545 Traits::X86OperandMem::SegReg_GS);
3546 Variable *Dest = Instr->getDest(); 3541 Variable *Dest = Instr->getDest();
3547 Variable *T = nullptr; 3542 Variable *T = nullptr;
3548 _mov(T, Src); 3543 _mov(T, Src);
3549 _mov(Dest, T); 3544 _mov(Dest, T);
3550 } else { 3545 } else {
3551 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0); 3546 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0);
3552 lowerCall(Call); 3547 lowerCall(Call);
3553 } 3548 }
3554 return; 3549 return;
3555 } 3550 }
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3968 } else { 3963 } else {
3969 _bsr(T_Dest2, SecondVar); 3964 _bsr(T_Dest2, SecondVar);
3970 _xor(T_Dest2, ThirtyOne); 3965 _xor(T_Dest2, ThirtyOne);
3971 } 3966 }
3972 _test(SecondVar, SecondVar); 3967 _test(SecondVar, SecondVar);
3973 _cmov(T_Dest2, T_Dest, Traits::Cond::Br_e); 3968 _cmov(T_Dest2, T_Dest, Traits::Cond::Br_e);
3974 _mov(DestLo, T_Dest2); 3969 _mov(DestLo, T_Dest2);
3975 _mov(DestHi, Ctx->getConstantZero(IceType_i32)); 3970 _mov(DestHi, Ctx->getConstantZero(IceType_i32));
3976 } 3971 }
3977 3972
3978 bool isAdd(const Inst *Inst) { 3973 inline bool isAdd(const Inst *Inst) {
3979 if (const InstArithmetic *Arith = 3974 if (const InstArithmetic *Arith =
3980 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { 3975 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) {
3981 return (Arith->getOp() == InstArithmetic::Add); 3976 return (Arith->getOp() == InstArithmetic::Add);
3982 } 3977 }
3983 return false; 3978 return false;
3984 } 3979 }
3985 3980
3986 void dumpAddressOpt(const Cfg *Func, const Variable *Base, 3981 inline void dumpAddressOpt(const Cfg *Func, const Variable *Base,
3987 const Variable *Index, uint16_t Shift, int32_t Offset, 3982 const Variable *Index, uint16_t Shift,
3988 const Inst *Reason) { 3983 int32_t Offset, const Inst *Reason) {
3989 if (!BuildDefs::dump()) 3984 if (!BuildDefs::dump())
3990 return; 3985 return;
3991 if (!Func->isVerbose(IceV_AddrOpt)) 3986 if (!Func->isVerbose(IceV_AddrOpt))
3992 return; 3987 return;
3993 OstreamLocker L(Func->getContext()); 3988 OstreamLocker L(Func->getContext());
3994 Ostream &Str = Func->getContext()->getStrDump(); 3989 Ostream &Str = Func->getContext()->getStrDump();
3995 Str << "Instruction: "; 3990 Str << "Instruction: ";
3996 Reason->dumpDecorated(Func); 3991 Reason->dumpDecorated(Func);
3997 Str << " results in Base="; 3992 Str << " results in Base=";
3998 if (Base) 3993 if (Base)
3999 Base->dump(Func); 3994 Base->dump(Func);
4000 else 3995 else
4001 Str << "<null>"; 3996 Str << "<null>";
4002 Str << ", Index="; 3997 Str << ", Index=";
4003 if (Index) 3998 if (Index)
4004 Index->dump(Func); 3999 Index->dump(Func);
4005 else 4000 else
4006 Str << "<null>"; 4001 Str << "<null>";
4007 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; 4002 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n";
4008 } 4003 }
4009 4004
4010 bool matchTransitiveAssign(const VariablesMetadata *VMetadata, Variable *&Var, 4005 inline bool matchTransitiveAssign(const VariablesMetadata *VMetadata,
4011 const Inst *&Reason) { 4006 Variable *&Var, const Inst *&Reason) {
4012 // Var originates from Var=SrcVar ==> 4007 // Var originates from Var=SrcVar ==>
4013 // set Var:=SrcVar 4008 // set Var:=SrcVar
4014 if (Var == nullptr) 4009 if (Var == nullptr)
4015 return false; 4010 return false;
4016 if (const Inst *VarAssign = VMetadata->getSingleDefinition(Var)) { 4011 if (const Inst *VarAssign = VMetadata->getSingleDefinition(Var)) {
4017 assert(!VMetadata->isMultiDef(Var)); 4012 assert(!VMetadata->isMultiDef(Var));
4018 if (llvm::isa<InstAssign>(VarAssign)) { 4013 if (llvm::isa<InstAssign>(VarAssign)) {
4019 Operand *SrcOp = VarAssign->getSrc(0); 4014 Operand *SrcOp = VarAssign->getSrc(0);
4020 assert(SrcOp); 4015 assert(SrcOp);
4021 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) { 4016 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) {
4022 if (!VMetadata->isMultiDef(SrcVar) && 4017 if (!VMetadata->isMultiDef(SrcVar) &&
4023 // TODO: ensure SrcVar stays single-BB 4018 // TODO: ensure SrcVar stays single-BB
4024 true) { 4019 true) {
4025 Var = SrcVar; 4020 Var = SrcVar;
4026 Reason = VarAssign; 4021 Reason = VarAssign;
4027 return true; 4022 return true;
4028 } 4023 }
4029 } 4024 }
4030 } 4025 }
4031 } 4026 }
4032 return false; 4027 return false;
4033 } 4028 }
4034 4029
4035 bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata, Variable *&Base, 4030 inline bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata,
4036 Variable *&Index, uint16_t &Shift, 4031 Variable *&Base, Variable *&Index,
4037 const Inst *&Reason) { 4032 uint16_t &Shift, const Inst *&Reason) {
4038 // Index==nullptr && Base is Base=Var1+Var2 ==> 4033 // Index==nullptr && Base is Base=Var1+Var2 ==>
4039 // set Base=Var1, Index=Var2, Shift=0 4034 // set Base=Var1, Index=Var2, Shift=0
4040 if (Base == nullptr) 4035 if (Base == nullptr)
4041 return false; 4036 return false;
4042 if (Index != nullptr) 4037 if (Index != nullptr)
4043 return false; 4038 return false;
4044 const Inst *BaseInst = VMetadata->getSingleDefinition(Base); 4039 const Inst *BaseInst = VMetadata->getSingleDefinition(Base);
4045 if (BaseInst == nullptr) 4040 if (BaseInst == nullptr)
4046 return false; 4041 return false;
4047 assert(!VMetadata->isMultiDef(Base)); 4042 assert(!VMetadata->isMultiDef(Base));
(...skipping 12 matching lines...) Expand all
4060 Index = Var2; 4055 Index = Var2;
4061 Shift = 0; // should already have been 0 4056 Shift = 0; // should already have been 0
4062 Reason = BaseInst; 4057 Reason = BaseInst;
4063 return true; 4058 return true;
4064 } 4059 }
4065 } 4060 }
4066 } 4061 }
4067 return false; 4062 return false;
4068 } 4063 }
4069 4064
4070 bool matchShiftedIndex(const VariablesMetadata *VMetadata, Variable *&Index, 4065 inline bool matchShiftedIndex(const VariablesMetadata *VMetadata,
4071 uint16_t &Shift, const Inst *&Reason) { 4066 Variable *&Index, uint16_t &Shift,
4067 const Inst *&Reason) {
4072 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==> 4068 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==>
4073 // Index=Var, Shift+=log2(Const) 4069 // Index=Var, Shift+=log2(Const)
4074 if (Index == nullptr) 4070 if (Index == nullptr)
4075 return false; 4071 return false;
4076 const Inst *IndexInst = VMetadata->getSingleDefinition(Index); 4072 const Inst *IndexInst = VMetadata->getSingleDefinition(Index);
4077 if (IndexInst == nullptr) 4073 if (IndexInst == nullptr)
4078 return false; 4074 return false;
4079 assert(!VMetadata->isMultiDef(Index)); 4075 assert(!VMetadata->isMultiDef(Index));
4080 if (IndexInst->getSrcSize() < 2) 4076 if (IndexInst->getSrcSize() < 2)
4081 return false; 4077 return false;
(...skipping 28 matching lines...) Expand all
4110 Reason = IndexInst; 4106 Reason = IndexInst;
4111 return true; 4107 return true;
4112 } 4108 }
4113 } 4109 }
4114 } 4110 }
4115 } 4111 }
4116 } 4112 }
4117 return false; 4113 return false;
4118 } 4114 }
4119 4115
4120 bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base, 4116 inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
4121 int32_t &Offset, const Inst *&Reason) { 4117 int32_t &Offset, const Inst *&Reason) {
4122 // Base is Base=Var+Const || Base is Base=Const+Var ==> 4118 // Base is Base=Var+Const || Base is Base=Const+Var ==>
4123 // set Base=Var, Offset+=Const 4119 // set Base=Var, Offset+=Const
4124 // Base is Base=Var-Const ==> 4120 // Base is Base=Var-Const ==>
4125 // set Base=Var, Offset-=Const 4121 // set Base=Var, Offset-=Const
4126 if (Base == nullptr) 4122 if (Base == nullptr)
4127 return false; 4123 return false;
4128 const Inst *BaseInst = VMetadata->getSingleDefinition(Base); 4124 const Inst *BaseInst = VMetadata->getSingleDefinition(Base);
4129 if (BaseInst == nullptr) 4125 if (BaseInst == nullptr)
4130 return false; 4126 return false;
4131 assert(!VMetadata->isMultiDef(Base)); 4127 assert(!VMetadata->isMultiDef(Base));
(...skipping 19 matching lines...) Expand all
4151 if (Utils::WouldOverflowAdd(Offset, MoreOffset)) 4147 if (Utils::WouldOverflowAdd(Offset, MoreOffset))
4152 return false; 4148 return false;
4153 Base = Var; 4149 Base = Var;
4154 Offset += MoreOffset; 4150 Offset += MoreOffset;
4155 Reason = BaseInst; 4151 Reason = BaseInst;
4156 return true; 4152 return true;
4157 } 4153 }
4158 return false; 4154 return false;
4159 } 4155 }
4160 4156
4161 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, 4157 inline void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base,
4162 Variable *&Index, uint16_t &Shift, int32_t &Offset) { 4158 Variable *&Index, uint16_t &Shift,
4159 int32_t &Offset) {
4163 Func->resetCurrentNode(); 4160 Func->resetCurrentNode();
4164 if (Func->isVerbose(IceV_AddrOpt)) { 4161 if (Func->isVerbose(IceV_AddrOpt)) {
4165 OstreamLocker L(Func->getContext()); 4162 OstreamLocker L(Func->getContext());
4166 Ostream &Str = Func->getContext()->getStrDump(); 4163 Ostream &Str = Func->getContext()->getStrDump();
4167 Str << "\nStarting computeAddressOpt for instruction:\n "; 4164 Str << "\nStarting computeAddressOpt for instruction:\n ";
4168 Instr->dumpDecorated(Func); 4165 Instr->dumpDecorated(Func);
4169 } 4166 }
4170 (void)Offset; // TODO: pattern-match for non-zero offsets. 4167 (void)Offset; // TODO: pattern-match for non-zero offsets.
4171 if (Base == nullptr) 4168 if (Base == nullptr)
4172 return; 4169 return;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
4341 } 4338 }
4342 // Lower select without Traits::SSE4.1: 4339 // Lower select without Traits::SSE4.1:
4343 // a=d?b:c ==> 4340 // a=d?b:c ==>
4344 // if elementtype(d) != i1: 4341 // if elementtype(d) != i1:
4345 // d=sext(d); 4342 // d=sext(d);
4346 // a=(b&d)|(c&~d); 4343 // a=(b&d)|(c&~d);
4347 Variable *T2 = makeReg(SrcTy); 4344 Variable *T2 = makeReg(SrcTy);
4348 // Sign extend the condition operand if applicable. 4345 // Sign extend the condition operand if applicable.
4349 if (SrcTy == IceType_v4f32) { 4346 if (SrcTy == IceType_v4f32) {
4350 // The sext operation takes only integer arguments. 4347 // The sext operation takes only integer arguments.
4351 Variable *T3 = Func->template makeVariable(IceType_v4i32); 4348 Variable *T3 = Func->makeVariable(IceType_v4i32);
4352 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition)); 4349 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition));
4353 _movp(T, T3); 4350 _movp(T, T3);
4354 } else if (typeElementType(SrcTy) != IceType_i1) { 4351 } else if (typeElementType(SrcTy) != IceType_i1) {
4355 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition)); 4352 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition));
4356 } else { 4353 } else {
4357 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); 4354 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem);
4358 _movp(T, ConditionRM); 4355 _movp(T, ConditionRM);
4359 } 4356 }
4360 _movp(T2, T); 4357 _movp(T2, T);
4361 _pand(T, SrcTRM); 4358 _pand(T, SrcTRM);
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
4759 assert(isVectorType(Dest->getType())); 4756 assert(isVectorType(Dest->getType()));
4760 Type Ty = Dest->getType(); 4757 Type Ty = Dest->getType();
4761 Type ElementTy = typeElementType(Ty); 4758 Type ElementTy = typeElementType(Ty);
4762 SizeT NumElements = typeNumElements(Ty); 4759 SizeT NumElements = typeNumElements(Ty);
4763 4760
4764 Operand *T = Ctx->getConstantUndef(Ty); 4761 Operand *T = Ctx->getConstantUndef(Ty);
4765 for (SizeT I = 0; I < NumElements; ++I) { 4762 for (SizeT I = 0; I < NumElements; ++I) {
4766 Constant *Index = Ctx->getConstantInt32(I); 4763 Constant *Index = Ctx->getConstantInt32(I);
4767 4764
4768 // Extract the next two inputs. 4765 // Extract the next two inputs.
4769 Variable *Op0 = Func->template makeVariable(ElementTy); 4766 Variable *Op0 = Func->makeVariable(ElementTy);
4770 lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index)); 4767 lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index));
4771 Variable *Op1 = Func->template makeVariable(ElementTy); 4768 Variable *Op1 = Func->makeVariable(ElementTy);
4772 lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index)); 4769 lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index));
4773 4770
4774 // Perform the arithmetic as a scalar operation. 4771 // Perform the arithmetic as a scalar operation.
4775 Variable *Res = Func->template makeVariable(ElementTy); 4772 Variable *Res = Func->makeVariable(ElementTy);
4776 lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1)); 4773 lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1));
4777 4774
4778 // Insert the result into position. 4775 // Insert the result into position.
4779 Variable *DestT = Func->template makeVariable(Ty); 4776 Variable *DestT = Func->makeVariable(Ty);
4780 lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index)); 4777 lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index));
4781 T = DestT; 4778 T = DestT;
4782 } 4779 }
4783 4780
4784 lowerAssign(InstAssign::create(Func, Dest, T)); 4781 lowerAssign(InstAssign::create(Func, Dest, T));
4785 } 4782 }
4786 4783
4787 /// The following pattern occurs often in lowered C and C++ code: 4784 /// The following pattern occurs often in lowered C and C++ code:
4788 /// 4785 ///
4789 /// %cmp = fcmp/icmp pred <n x ty> %src0, %src1 4786 /// %cmp = fcmp/icmp pred <n x ty> %src0, %src1
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
4907 /// turned into zeroes, since loOperand() and hiOperand() don't expect 4904 /// turned into zeroes, since loOperand() and hiOperand() don't expect
4908 /// Undef input. 4905 /// Undef input.
4909 template <class Machine> void TargetX86Base<Machine>::prelowerPhis() { 4906 template <class Machine> void TargetX86Base<Machine>::prelowerPhis() {
4910 // Pause constant blinding or pooling, blinding or pooling will be done later 4907 // Pause constant blinding or pooling, blinding or pooling will be done later
4911 // during phi lowering assignments 4908 // during phi lowering assignments
4912 BoolFlagSaver B(RandomizationPoolingPaused, true); 4909 BoolFlagSaver B(RandomizationPoolingPaused, true);
4913 PhiLowering::prelowerPhis32Bit<TargetX86Base<Machine>>( 4910 PhiLowering::prelowerPhis32Bit<TargetX86Base<Machine>>(
4914 this, Context.getNode(), Func); 4911 this, Context.getNode(), Func);
4915 } 4912 }
4916 4913
4917 bool isMemoryOperand(const Operand *Opnd) { 4914 inline bool isMemoryOperand(const Operand *Opnd) {
4918 if (const auto Var = llvm::dyn_cast<Variable>(Opnd)) 4915 if (const auto Var = llvm::dyn_cast<Variable>(Opnd))
4919 return !Var->hasReg(); 4916 return !Var->hasReg();
4920 // We treat vector undef values the same as a memory operand, 4917 // We treat vector undef values the same as a memory operand,
4921 // because they do in fact need a register to materialize the vector 4918 // because they do in fact need a register to materialize the vector
4922 // of zeroes into. 4919 // of zeroes into.
4923 if (llvm::isa<ConstantUndef>(Opnd)) 4920 if (llvm::isa<ConstantUndef>(Opnd))
4924 return isScalarFloatingType(Opnd->getType()) || 4921 return isScalarFloatingType(Opnd->getType()) ||
4925 isVectorType(Opnd->getType()); 4922 isVectorType(Opnd->getType());
4926 if (llvm::isa<Constant>(Opnd)) 4923 if (llvm::isa<Constant>(Opnd))
4927 return isScalarFloatingType(Opnd->getType()); 4924 return isScalarFloatingType(Opnd->getType());
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
5016 Variable *Preg = nullptr; 5013 Variable *Preg = nullptr;
5017 // TODO(stichnot): Opportunity for register randomization. 5014 // TODO(stichnot): Opportunity for register randomization.
5018 int32_t RegNum = AvailRegsForType.find_first(); 5015 int32_t RegNum = AvailRegsForType.find_first();
5019 bool IsVector = isVectorType(Dest->getType()); 5016 bool IsVector = isVectorType(Dest->getType());
5020 bool NeedSpill = (RegNum == -1); 5017 bool NeedSpill = (RegNum == -1);
5021 if (NeedSpill) { 5018 if (NeedSpill) {
5022 // Pick some register to spill and update RegNum. 5019 // Pick some register to spill and update RegNum.
5023 // TODO(stichnot): Opportunity for register randomization. 5020 // TODO(stichnot): Opportunity for register randomization.
5024 RegNum = RegsForType.find_first(); 5021 RegNum = RegsForType.find_first();
5025 Preg = getPhysicalRegister(RegNum, Dest->getType()); 5022 Preg = getPhysicalRegister(RegNum, Dest->getType());
5026 SpillLoc = Func->template makeVariable(Dest->getType()); 5023 SpillLoc = Func->makeVariable(Dest->getType());
5027 // Create a fake def of the physical register to avoid 5024 // Create a fake def of the physical register to avoid
5028 // liveness inconsistency problems during late-stage liveness 5025 // liveness inconsistency problems during late-stage liveness
5029 // analysis (e.g. asm-verbose mode). 5026 // analysis (e.g. asm-verbose mode).
5030 Context.insert(InstFakeDef::create(Func, Preg)); 5027 Context.insert(InstFakeDef::create(Func, Preg));
5031 if (IsVector) 5028 if (IsVector)
5032 _movp(SpillLoc, Preg); 5029 _movp(SpillLoc, Preg);
5033 else 5030 else
5034 _mov(SpillLoc, Preg); 5031 _mov(SpillLoc, Preg);
5035 } 5032 }
5036 assert(RegNum >= 0); 5033 assert(RegNum >= 0);
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
5358 // Do legalization, which contains randomization/pooling 5355 // Do legalization, which contains randomization/pooling
5359 // or do randomization/pooling. 5356 // or do randomization/pooling.
5360 return llvm::cast<typename Traits::X86OperandMem>( 5357 return llvm::cast<typename Traits::X86OperandMem>(
5361 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem)); 5358 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
5362 } 5359 }
5363 5360
5364 template <class Machine> 5361 template <class Machine>
5365 Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) { 5362 Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) {
5366 // There aren't any 64-bit integer registers for x86-32. 5363 // There aren't any 64-bit integer registers for x86-32.
5367 assert(Type != IceType_i64); 5364 assert(Type != IceType_i64);
5368 Variable *Reg = Func->template makeVariable(Type); 5365 Variable *Reg = Func->makeVariable(Type);
5369 if (RegNum == Variable::NoRegister) 5366 if (RegNum == Variable::NoRegister)
5370 Reg->setWeightInfinite(); 5367 Reg->setWeightInfinite();
5371 else 5368 else
5372 Reg->setRegNum(RegNum); 5369 Reg->setRegNum(RegNum);
5373 return Reg; 5370 return Reg;
5374 } 5371 }
5375 5372
5376 template <class Machine> void TargetX86Base<Machine>::postLower() { 5373 template <class Machine> void TargetX86Base<Machine>::postLower() {
5377 if (Ctx->getFlags().getOptLevel() == Opt_m1) 5374 if (Ctx->getFlags().getOptLevel() == Opt_m1)
5378 return; 5375 return;
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
5619 } 5616 }
5620 // the offset is not eligible for blinding or pooling, return the original 5617 // the offset is not eligible for blinding or pooling, return the original
5621 // mem operand 5618 // mem operand
5622 return MemOperand; 5619 return MemOperand;
5623 } 5620 }
5624 5621
5625 } // end of namespace X86Internal 5622 } // end of namespace X86Internal
5626 } // end of namespace Ice 5623 } // end of namespace Ice
5627 5624
5628 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H 5625 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698