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

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: 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 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) {
John 2015/07/08 16:37:40 the lack of "inline" here was causing (as expected
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 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 =
1116 1 << Func->template getAssembler<>()->getBundleAlignLog2Bytes(); 1116 1 << 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>(
2692 IceType_f64); 2692 IceType_f64);
2693 SpillVar->setLinkedTo(Src0Var); 2693 SpillVar->setLinkedTo(Src0Var);
2694 Variable *Spill = SpillVar; 2694 Variable *Spill = SpillVar;
2695 Spill->setWeight(RegWeight::Zero); 2695 Spill->setWeight(RegWeight::Zero);
2696 _movq(Spill, Src0RM); 2696 _movq(Spill, Src0RM);
2697 SpillLo = Traits::VariableSplit::create(Func, Spill, 2697 SpillLo = Traits::VariableSplit::create(Func, Spill,
2698 Traits::VariableSplit::Low); 2698 Traits::VariableSplit::Low);
2699 SpillHi = Traits::VariableSplit::create(Func, Spill, 2699 SpillHi = Traits::VariableSplit::create(Func, Spill,
2700 Traits::VariableSplit::High); 2700 Traits::VariableSplit::High);
2701 } else { 2701 } else {
2702 SpillLo = loOperand(Src0RM); 2702 SpillLo = loOperand(Src0RM);
2703 SpillHi = hiOperand(Src0RM); 2703 SpillHi = hiOperand(Src0RM);
2704 } 2704 }
2705 2705
2706 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2706 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2707 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2707 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2708 Variable *T_Lo = makeReg(IceType_i32); 2708 Variable *T_Lo = makeReg(IceType_i32);
2709 Variable *T_Hi = makeReg(IceType_i32); 2709 Variable *T_Hi = makeReg(IceType_i32);
2710 2710
2711 _mov(T_Lo, SpillLo); 2711 _mov(T_Lo, SpillLo);
2712 _mov(DestLo, T_Lo); 2712 _mov(DestLo, T_Lo);
2713 _mov(T_Hi, SpillHi); 2713 _mov(T_Hi, SpillHi);
2714 _mov(DestHi, T_Hi); 2714 _mov(DestHi, T_Hi);
2715 } break; 2715 } break;
2716 case IceType_f64: { 2716 case IceType_f64: {
2717 Src0 = legalize(Src0); 2717 Src0 = legalize(Src0);
2718 assert(Src0->getType() == IceType_i64); 2718 assert(Src0->getType() == IceType_i64);
2719 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) { 2719 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) {
2720 Variable *T = Func->template makeVariable(Dest->getType()); 2720 Variable *T = Func-> makeVariable(Dest->getType());
2721 _movq(T, Src0); 2721 _movq(T, Src0);
2722 _movq(Dest, T); 2722 _movq(Dest, T);
2723 break; 2723 break;
2724 } 2724 }
2725 // a.f64 = bitcast b.i64 ==> 2725 // a.f64 = bitcast b.i64 ==>
2726 // t_lo.i32 = b_lo.i32 2726 // t_lo.i32 = b_lo.i32
2727 // FakeDef(s.f64) 2727 // FakeDef(s.f64)
2728 // lo(s.f64) = t_lo.i32 2728 // lo(s.f64) = t_lo.i32
2729 // t_hi.i32 = b_hi.i32 2729 // t_hi.i32 = b_hi.i32
2730 // hi(s.f64) = t_hi.i32 2730 // hi(s.f64) = t_hi.i32
2731 // a.f64 = s.f64 2731 // a.f64 = s.f64
2732 typename Traits::SpillVariable *SpillVar = 2732 typename Traits::SpillVariable *SpillVar =
2733 Func->template makeVariable<typename Traits::SpillVariable>( 2733 Func-> makeVariable<typename Traits::SpillVariable>(
2734 IceType_f64); 2734 IceType_f64);
2735 SpillVar->setLinkedTo(Dest); 2735 SpillVar->setLinkedTo(Dest);
2736 Variable *Spill = SpillVar; 2736 Variable *Spill = SpillVar;
2737 Spill->setWeight(RegWeight::Zero); 2737 Spill->setWeight(RegWeight::Zero);
2738 2738
2739 Variable *T_Lo = nullptr, *T_Hi = nullptr; 2739 Variable *T_Lo = nullptr, *T_Hi = nullptr;
2740 typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create( 2740 typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create(
2741 Func, Spill, Traits::VariableSplit::Low); 2741 Func, Spill, Traits::VariableSplit::Low);
2742 typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create( 2742 typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create(
2743 Func, Spill, Traits::VariableSplit::High); 2743 Func, Spill, Traits::VariableSplit::High);
2744 _mov(T_Lo, loOperand(Src0)); 2744 _mov(T_Lo, loOperand(Src0));
2745 // Technically, the Spill is defined after the _store happens, but 2745 // Technically, the Spill is defined after the _store happens, but
2746 // 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
2747 // is used. 2747 // is used.
2748 Context.insert(InstFakeDef::create(Func, Spill)); 2748 Context.insert(InstFakeDef::create(Func, Spill));
2749 _store(T_Lo, SpillLo); 2749 _store(T_Lo, SpillLo);
2750 _mov(T_Hi, hiOperand(Src0)); 2750 _mov(T_Hi, hiOperand(Src0));
2751 _store(T_Hi, SpillHi); 2751 _store(T_Hi, SpillHi);
2752 _movq(Dest, Spill); 2752 _movq(Dest, Spill);
2753 } break; 2753 } break;
2754 case IceType_v8i1: { 2754 case IceType_v8i1: {
2755 assert(Src0->getType() == IceType_i8); 2755 assert(Src0->getType() == IceType_i8);
2756 InstCall *Call = makeHelperCall(H_bitcast_i8_8xi1, Dest, 1); 2756 InstCall *Call = makeHelperCall(H_bitcast_i8_8xi1, Dest, 1);
2757 Variable *Src0AsI32 = Func->template makeVariable(stackSlotType()); 2757 Variable *Src0AsI32 = Func-> makeVariable(stackSlotType());
2758 // 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.
2759 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2759 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2760 Call->addArg(Src0AsI32); 2760 Call->addArg(Src0AsI32);
2761 lowerCall(Call); 2761 lowerCall(Call);
2762 } break; 2762 } break;
2763 case IceType_v16i1: { 2763 case IceType_v16i1: {
2764 assert(Src0->getType() == IceType_i16); 2764 assert(Src0->getType() == IceType_i16);
2765 InstCall *Call = makeHelperCall(H_bitcast_i16_16xi1, Dest, 1); 2765 InstCall *Call = makeHelperCall(H_bitcast_i16_16xi1, Dest, 1);
2766 Variable *Src0AsI32 = Func->template makeVariable(stackSlotType()); 2766 Variable *Src0AsI32 = Func-> makeVariable(stackSlotType());
2767 // 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.
2768 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2768 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2769 Call->addArg(Src0AsI32); 2769 Call->addArg(Src0AsI32);
2770 lowerCall(Call); 2770 lowerCall(Call);
2771 } break; 2771 } break;
2772 case IceType_v8i16: 2772 case IceType_v8i16:
2773 case IceType_v16i8: 2773 case IceType_v16i8:
2774 case IceType_v4i32: 2774 case IceType_v4i32:
2775 case IceType_v4f32: { 2775 case IceType_v4f32: {
2776 _movp(Dest, legalizeToVar(Src0)); 2776 _movp(Dest, legalizeToVar(Src0));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2827 // keep the live range analysis consistent. 2827 // keep the live range analysis consistent.
2828 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); 2828 Context.insert(InstFakeDef::create(Func, ExtractedElementR));
2829 _movss(ExtractedElementR, T); 2829 _movss(ExtractedElementR, T);
2830 } 2830 }
2831 } else { 2831 } else {
2832 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 2832 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
2833 // 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.
2834 // 2834 //
2835 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when 2835 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
2836 // support for legalizing to mem is implemented. 2836 // support for legalizing to mem is implemented.
2837 Variable *Slot = Func->template makeVariable(Ty); 2837 Variable *Slot = Func-> makeVariable(Ty);
2838 Slot->setWeight(RegWeight::Zero); 2838 Slot->setWeight(RegWeight::Zero);
2839 _movp(Slot, legalizeToVar(SourceVectNotLegalized)); 2839 _movp(Slot, legalizeToVar(SourceVectNotLegalized));
2840 2840
2841 // Compute the location of the element in memory. 2841 // Compute the location of the element in memory.
2842 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 2842 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
2843 typename Traits::X86OperandMem *Loc = 2843 typename Traits::X86OperandMem *Loc =
2844 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 2844 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
2845 _mov(ExtractedElementR, Loc); 2845 _mov(ExtractedElementR, Loc);
2846 } 2846 }
2847 2847
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 case IceType_v4i1: 2992 case IceType_v4i1:
2993 NewTy = IceType_v4i32; 2993 NewTy = IceType_v4i32;
2994 break; 2994 break;
2995 case IceType_v8i1: 2995 case IceType_v8i1:
2996 NewTy = IceType_v8i16; 2996 NewTy = IceType_v8i16;
2997 break; 2997 break;
2998 case IceType_v16i1: 2998 case IceType_v16i1:
2999 NewTy = IceType_v16i8; 2999 NewTy = IceType_v16i8;
3000 break; 3000 break;
3001 } 3001 }
3002 Variable *NewSrc0 = Func->template makeVariable(NewTy); 3002 Variable *NewSrc0 = Func-> makeVariable(NewTy);
3003 Variable *NewSrc1 = Func->template makeVariable(NewTy); 3003 Variable *NewSrc1 = Func-> makeVariable(NewTy);
3004 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0)); 3004 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0));
3005 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1)); 3005 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1));
3006 Src0 = NewSrc0; 3006 Src0 = NewSrc0;
3007 Src1 = NewSrc1; 3007 Src1 = NewSrc1;
3008 Ty = NewTy; 3008 Ty = NewTy;
3009 } 3009 }
3010 3010
3011 InstIcmp::ICond Condition = Inst->getCondition(); 3011 InstIcmp::ICond Condition = Inst->getCondition();
3012 3012
3013 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
3135 unsigned Index = ElementIndex->getValue(); 3135 unsigned Index = ElementIndex->getValue();
3136 assert(Index < typeNumElements(SourceVectNotLegalized->getType())); 3136 assert(Index < typeNumElements(SourceVectNotLegalized->getType()));
3137 3137
3138 Type Ty = SourceVectNotLegalized->getType(); 3138 Type Ty = SourceVectNotLegalized->getType();
3139 Type ElementTy = typeElementType(Ty); 3139 Type ElementTy = typeElementType(Ty);
3140 Type InVectorElementTy = Traits::getInVectorElementType(Ty); 3140 Type InVectorElementTy = Traits::getInVectorElementType(Ty);
3141 3141
3142 if (ElementTy == IceType_i1) { 3142 if (ElementTy == IceType_i1) {
3143 // 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
3144 // in the vector. 3144 // in the vector.
3145 Variable *Expanded = Func->template makeVariable(InVectorElementTy); 3145 Variable *Expanded = Func-> makeVariable(InVectorElementTy);
3146 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded, 3146 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded,
3147 ElementToInsertNotLegalized); 3147 ElementToInsertNotLegalized);
3148 lowerCast(Cast); 3148 lowerCast(Cast);
3149 ElementToInsertNotLegalized = Expanded; 3149 ElementToInsertNotLegalized = Expanded;
3150 } 3150 }
3151 3151
3152 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 || 3152 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 ||
3153 InstructionSet >= Traits::SSE4_1) { 3153 InstructionSet >= Traits::SSE4_1) {
3154 // Use insertps, pinsrb, pinsrw, or pinsrd. 3154 // Use insertps, pinsrb, pinsrw, or pinsrd.
3155 Operand *ElementRM = 3155 Operand *ElementRM =
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3226 _shufps(T, ElementR, Mask2Constant); 3226 _shufps(T, ElementR, Mask2Constant);
3227 _movp(Inst->getDest(), T); 3227 _movp(Inst->getDest(), T);
3228 } 3228 }
3229 } else { 3229 } else {
3230 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 3230 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
3231 // 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
3232 // memory. 3232 // memory.
3233 // 3233 //
3234 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when 3234 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
3235 // support for legalizing to mem is implemented. 3235 // support for legalizing to mem is implemented.
3236 Variable *Slot = Func->template makeVariable(Ty); 3236 Variable *Slot = Func-> makeVariable(Ty);
3237 Slot->setWeight(RegWeight::Zero); 3237 Slot->setWeight(RegWeight::Zero);
3238 _movp(Slot, legalizeToVar(SourceVectNotLegalized)); 3238 _movp(Slot, legalizeToVar(SourceVectNotLegalized));
3239 3239
3240 // Compute the location of the position to insert in memory. 3240 // Compute the location of the position to insert in memory.
3241 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 3241 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
3242 typename Traits::X86OperandMem *Loc = 3242 typename Traits::X86OperandMem *Loc =
3243 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 3243 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
3244 _store(legalizeToVar(ElementToInsertNotLegalized), Loc); 3244 _store(legalizeToVar(ElementToInsertNotLegalized), Loc);
3245 3245
3246 Variable *T = makeReg(Ty); 3246 Variable *T = makeReg(Ty);
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3519 Call->addArg(Instr->getArg(2)); 3519 Call->addArg(Instr->getArg(2));
3520 lowerCall(Call); 3520 lowerCall(Call);
3521 return; 3521 return;
3522 } 3522 }
3523 case Intrinsics::Memset: { 3523 case Intrinsics::Memset: {
3524 // The value operand needs to be extended to a stack slot size 3524 // 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 3525 // because the PNaCl ABI requires arguments to be at least 32 bits
3526 // wide. 3526 // wide.
3527 Operand *ValOp = Instr->getArg(1); 3527 Operand *ValOp = Instr->getArg(1);
3528 assert(ValOp->getType() == IceType_i8); 3528 assert(ValOp->getType() == IceType_i8);
3529 Variable *ValExt = Func->template makeVariable(stackSlotType()); 3529 Variable *ValExt = Func->makeVariable(stackSlotType());
3530 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); 3530 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp));
3531 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); 3531 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3);
3532 Call->addArg(Instr->getArg(0)); 3532 Call->addArg(Instr->getArg(0));
3533 Call->addArg(ValExt); 3533 Call->addArg(ValExt);
3534 Call->addArg(Instr->getArg(2)); 3534 Call->addArg(Instr->getArg(2));
3535 lowerCall(Call); 3535 lowerCall(Call);
3536 return; 3536 return;
3537 } 3537 }
3538 case Intrinsics::NaClReadTP: { 3538 case Intrinsics::NaClReadTP: {
3539 if (Ctx->getFlags().getUseSandboxing()) { 3539 if (Ctx->getFlags().getUseSandboxing()) {
3540 Constant *Zero = Ctx->getConstantZero(IceType_i32); 3540 Operand *Src = dispatchToConcrete(&Machine::createNaClReadTPSrcOperand);
John 2015/07/08 16:37:40 And here is the "proof of concept" for using dispa
3541 Operand *Src = Traits::X86OperandMem::create(
3542 Func, IceType_i32, nullptr, Zero, nullptr, 0,
3543 Traits::X86OperandMem::SegReg_GS);
3544 Variable *Dest = Instr->getDest(); 3541 Variable *Dest = Instr->getDest();
3545 Variable *T = nullptr; 3542 Variable *T = nullptr;
3546 _mov(T, Src); 3543 _mov(T, Src);
3547 _mov(Dest, T); 3544 _mov(Dest, T);
3548 } else { 3545 } else {
3549 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0); 3546 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0);
3550 lowerCall(Call); 3547 lowerCall(Call);
3551 } 3548 }
3552 return; 3549 return;
3553 } 3550 }
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3966 } else { 3963 } else {
3967 _bsr(T_Dest2, SecondVar); 3964 _bsr(T_Dest2, SecondVar);
3968 _xor(T_Dest2, ThirtyOne); 3965 _xor(T_Dest2, ThirtyOne);
3969 } 3966 }
3970 _test(SecondVar, SecondVar); 3967 _test(SecondVar, SecondVar);
3971 _cmov(T_Dest2, T_Dest, Traits::Cond::Br_e); 3968 _cmov(T_Dest2, T_Dest, Traits::Cond::Br_e);
3972 _mov(DestLo, T_Dest2); 3969 _mov(DestLo, T_Dest2);
3973 _mov(DestHi, Ctx->getConstantZero(IceType_i32)); 3970 _mov(DestHi, Ctx->getConstantZero(IceType_i32));
3974 } 3971 }
3975 3972
3976 bool isAdd(const Inst *Inst) { 3973 inline bool isAdd(const Inst *Inst) {
3977 if (const InstArithmetic *Arith = 3974 if (const InstArithmetic *Arith =
3978 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { 3975 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) {
3979 return (Arith->getOp() == InstArithmetic::Add); 3976 return (Arith->getOp() == InstArithmetic::Add);
3980 } 3977 }
3981 return false; 3978 return false;
3982 } 3979 }
3983 3980
3984 void dumpAddressOpt(const Cfg *Func, const Variable *Base, 3981 inline void dumpAddressOpt(const Cfg *Func, const Variable *Base,
3985 const Variable *Index, uint16_t Shift, int32_t Offset, 3982 const Variable *Index, uint16_t Shift,
3986 const Inst *Reason) { 3983 int32_t Offset, const Inst *Reason) {
3987 if (!BuildDefs::dump()) 3984 if (!BuildDefs::dump())
3988 return; 3985 return;
3989 if (!Func->isVerbose(IceV_AddrOpt)) 3986 if (!Func->isVerbose(IceV_AddrOpt))
3990 return; 3987 return;
3991 OstreamLocker L(Func->getContext()); 3988 OstreamLocker L(Func->getContext());
3992 Ostream &Str = Func->getContext()->getStrDump(); 3989 Ostream &Str = Func->getContext()->getStrDump();
3993 Str << "Instruction: "; 3990 Str << "Instruction: ";
3994 Reason->dumpDecorated(Func); 3991 Reason->dumpDecorated(Func);
3995 Str << " results in Base="; 3992 Str << " results in Base=";
3996 if (Base) 3993 if (Base)
3997 Base->dump(Func); 3994 Base->dump(Func);
3998 else 3995 else
3999 Str << "<null>"; 3996 Str << "<null>";
4000 Str << ", Index="; 3997 Str << ", Index=";
4001 if (Index) 3998 if (Index)
4002 Index->dump(Func); 3999 Index->dump(Func);
4003 else 4000 else
4004 Str << "<null>"; 4001 Str << "<null>";
4005 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; 4002 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n";
4006 } 4003 }
4007 4004
4008 bool matchTransitiveAssign(const VariablesMetadata *VMetadata, Variable *&Var, 4005 inline bool matchTransitiveAssign(const VariablesMetadata *VMetadata,
4009 const Inst *&Reason) { 4006 Variable *&Var, const Inst *&Reason) {
4010 // Var originates from Var=SrcVar ==> 4007 // Var originates from Var=SrcVar ==>
4011 // set Var:=SrcVar 4008 // set Var:=SrcVar
4012 if (Var == nullptr) 4009 if (Var == nullptr)
4013 return false; 4010 return false;
4014 if (const Inst *VarAssign = VMetadata->getSingleDefinition(Var)) { 4011 if (const Inst *VarAssign = VMetadata->getSingleDefinition(Var)) {
4015 assert(!VMetadata->isMultiDef(Var)); 4012 assert(!VMetadata->isMultiDef(Var));
4016 if (llvm::isa<InstAssign>(VarAssign)) { 4013 if (llvm::isa<InstAssign>(VarAssign)) {
4017 Operand *SrcOp = VarAssign->getSrc(0); 4014 Operand *SrcOp = VarAssign->getSrc(0);
4018 assert(SrcOp); 4015 assert(SrcOp);
4019 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) { 4016 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) {
4020 if (!VMetadata->isMultiDef(SrcVar) && 4017 if (!VMetadata->isMultiDef(SrcVar) &&
4021 // TODO: ensure SrcVar stays single-BB 4018 // TODO: ensure SrcVar stays single-BB
4022 true) { 4019 true) {
4023 Var = SrcVar; 4020 Var = SrcVar;
4024 Reason = VarAssign; 4021 Reason = VarAssign;
4025 return true; 4022 return true;
4026 } 4023 }
4027 } 4024 }
4028 } 4025 }
4029 } 4026 }
4030 return false; 4027 return false;
4031 } 4028 }
4032 4029
4033 bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata, Variable *&Base, 4030 inline bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata,
4034 Variable *&Index, uint16_t &Shift, 4031 Variable *&Base, Variable *&Index,
4035 const Inst *&Reason) { 4032 uint16_t &Shift, const Inst *&Reason) {
4036 // Index==nullptr && Base is Base=Var1+Var2 ==> 4033 // Index==nullptr && Base is Base=Var1+Var2 ==>
4037 // set Base=Var1, Index=Var2, Shift=0 4034 // set Base=Var1, Index=Var2, Shift=0
4038 if (Base == nullptr) 4035 if (Base == nullptr)
4039 return false; 4036 return false;
4040 if (Index != nullptr) 4037 if (Index != nullptr)
4041 return false; 4038 return false;
4042 const Inst *BaseInst = VMetadata->getSingleDefinition(Base); 4039 const Inst *BaseInst = VMetadata->getSingleDefinition(Base);
4043 if (BaseInst == nullptr) 4040 if (BaseInst == nullptr)
4044 return false; 4041 return false;
4045 assert(!VMetadata->isMultiDef(Base)); 4042 assert(!VMetadata->isMultiDef(Base));
(...skipping 12 matching lines...) Expand all
4058 Index = Var2; 4055 Index = Var2;
4059 Shift = 0; // should already have been 0 4056 Shift = 0; // should already have been 0
4060 Reason = BaseInst; 4057 Reason = BaseInst;
4061 return true; 4058 return true;
4062 } 4059 }
4063 } 4060 }
4064 } 4061 }
4065 return false; 4062 return false;
4066 } 4063 }
4067 4064
4068 bool matchShiftedIndex(const VariablesMetadata *VMetadata, Variable *&Index, 4065 inline bool matchShiftedIndex(const VariablesMetadata *VMetadata,
4069 uint16_t &Shift, const Inst *&Reason) { 4066 Variable *&Index, uint16_t &Shift,
4067 const Inst *&Reason) {
4070 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==> 4068 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==>
4071 // Index=Var, Shift+=log2(Const) 4069 // Index=Var, Shift+=log2(Const)
4072 if (Index == nullptr) 4070 if (Index == nullptr)
4073 return false; 4071 return false;
4074 const Inst *IndexInst = VMetadata->getSingleDefinition(Index); 4072 const Inst *IndexInst = VMetadata->getSingleDefinition(Index);
4075 if (IndexInst == nullptr) 4073 if (IndexInst == nullptr)
4076 return false; 4074 return false;
4077 assert(!VMetadata->isMultiDef(Index)); 4075 assert(!VMetadata->isMultiDef(Index));
4078 if (IndexInst->getSrcSize() < 2) 4076 if (IndexInst->getSrcSize() < 2)
4079 return false; 4077 return false;
(...skipping 28 matching lines...) Expand all
4108 Reason = IndexInst; 4106 Reason = IndexInst;
4109 return true; 4107 return true;
4110 } 4108 }
4111 } 4109 }
4112 } 4110 }
4113 } 4111 }
4114 } 4112 }
4115 return false; 4113 return false;
4116 } 4114 }
4117 4115
4118 bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base, 4116 inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
4119 int32_t &Offset, const Inst *&Reason) { 4117 int32_t &Offset, const Inst *&Reason) {
4120 // Base is Base=Var+Const || Base is Base=Const+Var ==> 4118 // Base is Base=Var+Const || Base is Base=Const+Var ==>
4121 // set Base=Var, Offset+=Const 4119 // set Base=Var, Offset+=Const
4122 // Base is Base=Var-Const ==> 4120 // Base is Base=Var-Const ==>
4123 // set Base=Var, Offset-=Const 4121 // set Base=Var, Offset-=Const
4124 if (Base == nullptr) 4122 if (Base == nullptr)
4125 return false; 4123 return false;
4126 const Inst *BaseInst = VMetadata->getSingleDefinition(Base); 4124 const Inst *BaseInst = VMetadata->getSingleDefinition(Base);
4127 if (BaseInst == nullptr) 4125 if (BaseInst == nullptr)
4128 return false; 4126 return false;
4129 assert(!VMetadata->isMultiDef(Base)); 4127 assert(!VMetadata->isMultiDef(Base));
(...skipping 19 matching lines...) Expand all
4149 if (Utils::WouldOverflowAdd(Offset, MoreOffset)) 4147 if (Utils::WouldOverflowAdd(Offset, MoreOffset))
4150 return false; 4148 return false;
4151 Base = Var; 4149 Base = Var;
4152 Offset += MoreOffset; 4150 Offset += MoreOffset;
4153 Reason = BaseInst; 4151 Reason = BaseInst;
4154 return true; 4152 return true;
4155 } 4153 }
4156 return false; 4154 return false;
4157 } 4155 }
4158 4156
4159 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, 4157 inline void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base,
4160 Variable *&Index, uint16_t &Shift, int32_t &Offset) { 4158 Variable *&Index, uint16_t &Shift,
4159 int32_t &Offset) {
4161 Func->resetCurrentNode(); 4160 Func->resetCurrentNode();
4162 if (Func->isVerbose(IceV_AddrOpt)) { 4161 if (Func->isVerbose(IceV_AddrOpt)) {
4163 OstreamLocker L(Func->getContext()); 4162 OstreamLocker L(Func->getContext());
4164 Ostream &Str = Func->getContext()->getStrDump(); 4163 Ostream &Str = Func->getContext()->getStrDump();
4165 Str << "\nStarting computeAddressOpt for instruction:\n "; 4164 Str << "\nStarting computeAddressOpt for instruction:\n ";
4166 Instr->dumpDecorated(Func); 4165 Instr->dumpDecorated(Func);
4167 } 4166 }
4168 (void)Offset; // TODO: pattern-match for non-zero offsets. 4167 (void)Offset; // TODO: pattern-match for non-zero offsets.
4169 if (Base == nullptr) 4168 if (Base == nullptr)
4170 return; 4169 return;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
4339 } 4338 }
4340 // Lower select without Traits::SSE4.1: 4339 // Lower select without Traits::SSE4.1:
4341 // a=d?b:c ==> 4340 // a=d?b:c ==>
4342 // if elementtype(d) != i1: 4341 // if elementtype(d) != i1:
4343 // d=sext(d); 4342 // d=sext(d);
4344 // a=(b&d)|(c&~d); 4343 // a=(b&d)|(c&~d);
4345 Variable *T2 = makeReg(SrcTy); 4344 Variable *T2 = makeReg(SrcTy);
4346 // Sign extend the condition operand if applicable. 4345 // Sign extend the condition operand if applicable.
4347 if (SrcTy == IceType_v4f32) { 4346 if (SrcTy == IceType_v4f32) {
4348 // The sext operation takes only integer arguments. 4347 // The sext operation takes only integer arguments.
4349 Variable *T3 = Func->template makeVariable(IceType_v4i32); 4348 Variable *T3 = Func-> makeVariable(IceType_v4i32);
4350 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition)); 4349 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition));
4351 _movp(T, T3); 4350 _movp(T, T3);
4352 } else if (typeElementType(SrcTy) != IceType_i1) { 4351 } else if (typeElementType(SrcTy) != IceType_i1) {
4353 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition)); 4352 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition));
4354 } else { 4353 } else {
4355 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); 4354 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem);
4356 _movp(T, ConditionRM); 4355 _movp(T, ConditionRM);
4357 } 4356 }
4358 _movp(T2, T); 4357 _movp(T2, T);
4359 _pand(T, SrcTRM); 4358 _pand(T, SrcTRM);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 assert(isVectorType(Dest->getType())); 4543 assert(isVectorType(Dest->getType()));
4545 Type Ty = Dest->getType(); 4544 Type Ty = Dest->getType();
4546 Type ElementTy = typeElementType(Ty); 4545 Type ElementTy = typeElementType(Ty);
4547 SizeT NumElements = typeNumElements(Ty); 4546 SizeT NumElements = typeNumElements(Ty);
4548 4547
4549 Operand *T = Ctx->getConstantUndef(Ty); 4548 Operand *T = Ctx->getConstantUndef(Ty);
4550 for (SizeT I = 0; I < NumElements; ++I) { 4549 for (SizeT I = 0; I < NumElements; ++I) {
4551 Constant *Index = Ctx->getConstantInt32(I); 4550 Constant *Index = Ctx->getConstantInt32(I);
4552 4551
4553 // Extract the next two inputs. 4552 // Extract the next two inputs.
4554 Variable *Op0 = Func->template makeVariable(ElementTy); 4553 Variable *Op0 = Func-> makeVariable(ElementTy);
4555 lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index)); 4554 lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index));
4556 Variable *Op1 = Func->template makeVariable(ElementTy); 4555 Variable *Op1 = Func-> makeVariable(ElementTy);
4557 lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index)); 4556 lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index));
4558 4557
4559 // Perform the arithmetic as a scalar operation. 4558 // Perform the arithmetic as a scalar operation.
4560 Variable *Res = Func->template makeVariable(ElementTy); 4559 Variable *Res = Func-> makeVariable(ElementTy);
4561 lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1)); 4560 lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1));
4562 4561
4563 // Insert the result into position. 4562 // Insert the result into position.
4564 Variable *DestT = Func->template makeVariable(Ty); 4563 Variable *DestT = Func-> makeVariable(Ty);
4565 lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index)); 4564 lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index));
4566 T = DestT; 4565 T = DestT;
4567 } 4566 }
4568 4567
4569 lowerAssign(InstAssign::create(Func, Dest, T)); 4568 lowerAssign(InstAssign::create(Func, Dest, T));
4570 } 4569 }
4571 4570
4572 /// The following pattern occurs often in lowered C and C++ code: 4571 /// The following pattern occurs often in lowered C and C++ code:
4573 /// 4572 ///
4574 /// %cmp = fcmp/icmp pred <n x ty> %src0, %src1 4573 /// %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); 4713 PhiLo->addArgument(loOperand(Src), Label);
4715 PhiHi->addArgument(hiOperand(Src), Label); 4714 PhiHi->addArgument(hiOperand(Src), Label);
4716 } 4715 }
4717 Node->getPhis().push_back(PhiLo); 4716 Node->getPhis().push_back(PhiLo);
4718 Node->getPhis().push_back(PhiHi); 4717 Node->getPhis().push_back(PhiHi);
4719 Phi->setDeleted(); 4718 Phi->setDeleted();
4720 } 4719 }
4721 } 4720 }
4722 } 4721 }
4723 4722
4724 bool isMemoryOperand(const Operand *Opnd) { 4723 inline bool isMemoryOperand(const Operand *Opnd) {
4725 if (const auto Var = llvm::dyn_cast<Variable>(Opnd)) 4724 if (const auto Var = llvm::dyn_cast<Variable>(Opnd))
4726 return !Var->hasReg(); 4725 return !Var->hasReg();
4727 // We treat vector undef values the same as a memory operand, 4726 // We treat vector undef values the same as a memory operand,
4728 // because they do in fact need a register to materialize the vector 4727 // because they do in fact need a register to materialize the vector
4729 // of zeroes into. 4728 // of zeroes into.
4730 if (llvm::isa<ConstantUndef>(Opnd)) 4729 if (llvm::isa<ConstantUndef>(Opnd))
4731 return isScalarFloatingType(Opnd->getType()) || 4730 return isScalarFloatingType(Opnd->getType()) ||
4732 isVectorType(Opnd->getType()); 4731 isVectorType(Opnd->getType());
4733 if (llvm::isa<Constant>(Opnd)) 4732 if (llvm::isa<Constant>(Opnd))
4734 return isScalarFloatingType(Opnd->getType()); 4733 return isScalarFloatingType(Opnd->getType());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
4827 Variable *Preg = nullptr; 4826 Variable *Preg = nullptr;
4828 // TODO(stichnot): Opportunity for register randomization. 4827 // TODO(stichnot): Opportunity for register randomization.
4829 int32_t RegNum = AvailRegsForType.find_first(); 4828 int32_t RegNum = AvailRegsForType.find_first();
4830 bool IsVector = isVectorType(Dest->getType()); 4829 bool IsVector = isVectorType(Dest->getType());
4831 bool NeedSpill = (RegNum == -1); 4830 bool NeedSpill = (RegNum == -1);
4832 if (NeedSpill) { 4831 if (NeedSpill) {
4833 // Pick some register to spill and update RegNum. 4832 // Pick some register to spill and update RegNum.
4834 // TODO(stichnot): Opportunity for register randomization. 4833 // TODO(stichnot): Opportunity for register randomization.
4835 RegNum = RegsForType.find_first(); 4834 RegNum = RegsForType.find_first();
4836 Preg = getPhysicalRegister(RegNum, Dest->getType()); 4835 Preg = getPhysicalRegister(RegNum, Dest->getType());
4837 SpillLoc = Func->template makeVariable(Dest->getType()); 4836 SpillLoc = Func-> makeVariable(Dest->getType());
4838 // Create a fake def of the physical register to avoid 4837 // Create a fake def of the physical register to avoid
4839 // liveness inconsistency problems during late-stage liveness 4838 // liveness inconsistency problems during late-stage liveness
4840 // analysis (e.g. asm-verbose mode). 4839 // analysis (e.g. asm-verbose mode).
4841 Context.insert(InstFakeDef::create(Func, Preg)); 4840 Context.insert(InstFakeDef::create(Func, Preg));
4842 if (IsVector) 4841 if (IsVector)
4843 _movp(SpillLoc, Preg); 4842 _movp(SpillLoc, Preg);
4844 else 4843 else
4845 _mov(SpillLoc, Preg); 4844 _mov(SpillLoc, Preg);
4846 } 4845 }
4847 assert(RegNum >= 0); 4846 assert(RegNum >= 0);
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
5157 // Do legalization, which contains randomization/pooling 5156 // Do legalization, which contains randomization/pooling
5158 // or do randomization/pooling. 5157 // or do randomization/pooling.
5159 return llvm::cast<typename Traits::X86OperandMem>( 5158 return llvm::cast<typename Traits::X86OperandMem>(
5160 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem)); 5159 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
5161 } 5160 }
5162 5161
5163 template <class Machine> 5162 template <class Machine>
5164 Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) { 5163 Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) {
5165 // There aren't any 64-bit integer registers for x86-32. 5164 // There aren't any 64-bit integer registers for x86-32.
5166 assert(Type != IceType_i64); 5165 assert(Type != IceType_i64);
5167 Variable *Reg = Func->template makeVariable(Type); 5166 Variable *Reg = Func-> makeVariable(Type);
5168 if (RegNum == Variable::NoRegister) 5167 if (RegNum == Variable::NoRegister)
5169 Reg->setWeightInfinite(); 5168 Reg->setWeightInfinite();
5170 else 5169 else
5171 Reg->setRegNum(RegNum); 5170 Reg->setRegNum(RegNum);
5172 return Reg; 5171 return Reg;
5173 } 5172 }
5174 5173
5175 template <class Machine> void TargetX86Base<Machine>::postLower() { 5174 template <class Machine> void TargetX86Base<Machine>::postLower() {
5176 if (Ctx->getFlags().getOptLevel() == Opt_m1) 5175 if (Ctx->getFlags().getOptLevel() == Opt_m1)
5177 return; 5176 return;
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
5419 } 5418 }
5420 // the offset is not eligible for blinding or pooling, return the original 5419 // the offset is not eligible for blinding or pooling, return the original
5421 // mem operand 5420 // mem operand
5422 return MemOperand; 5421 return MemOperand;
5423 } 5422 }
5424 5423
5425 } // end of namespace X86Internal 5424 } // end of namespace X86Internal
5426 } // end of namespace Ice 5425 } // end of namespace Ice
5427 5426
5428 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H 5427 #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