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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 589003002: Subzero: Refactor tracking of Defs and block-local Variables. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: "Mark args as being used in the entry node" was unnecessary. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/PNaClTranslator.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the TargetLoweringX8632 class, which 10 // This file implements the TargetLoweringX8632 class, which
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 T_placePhiStores.printElapsedUs(Context, "placePhiStores()"); 315 T_placePhiStores.printElapsedUs(Context, "placePhiStores()");
316 Timer T_deletePhis; 316 Timer T_deletePhis;
317 Func->deletePhis(); 317 Func->deletePhis();
318 if (Func->hasError()) 318 if (Func->hasError())
319 return; 319 return;
320 T_deletePhis.printElapsedUs(Context, "deletePhis()"); 320 T_deletePhis.printElapsedUs(Context, "deletePhis()");
321 Func->dump("After Phi lowering"); 321 Func->dump("After Phi lowering");
322 322
323 // Address mode optimization. 323 // Address mode optimization.
324 Timer T_doAddressOpt; 324 Timer T_doAddressOpt;
325 Func->getVMetadata()->init();
325 Func->doAddressOpt(); 326 Func->doAddressOpt();
326 T_doAddressOpt.printElapsedUs(Context, "doAddressOpt()"); 327 T_doAddressOpt.printElapsedUs(Context, "doAddressOpt()");
327 328
328 // Argument lowering 329 // Argument lowering
329 Timer T_argLowering; 330 Timer T_argLowering;
330 Func->doArgLowering(); 331 Func->doArgLowering();
331 T_argLowering.printElapsedUs(Context, "lowerArguments()"); 332 T_argLowering.printElapsedUs(Context, "lowerArguments()");
332 333
333 // Target lowering. This requires liveness analysis for some parts 334 // Target lowering. This requires liveness analysis for some parts
334 // of the lowering decisions, such as compare/branch fusing. If 335 // of the lowering decisions, such as compare/branch fusing. If
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 frameptr, isI8, isInt, isFP) \ 464 frameptr, isI8, isInt, isFP) \
464 name, 465 name,
465 REGX8632_TABLE 466 REGX8632_TABLE
466 #undef X 467 #undef X
467 }; 468 };
468 469
469 Variable *TargetX8632::getPhysicalRegister(SizeT RegNum) { 470 Variable *TargetX8632::getPhysicalRegister(SizeT RegNum) {
470 assert(RegNum < PhysicalRegisters.size()); 471 assert(RegNum < PhysicalRegisters.size());
471 Variable *Reg = PhysicalRegisters[RegNum]; 472 Variable *Reg = PhysicalRegisters[RegNum];
472 if (Reg == NULL) { 473 if (Reg == NULL) {
473 CfgNode *Node = NULL; // NULL means multi-block lifetime 474 Reg = Func->makeVariable(IceType_i32);
474 Reg = Func->makeVariable(IceType_i32, Node);
475 Reg->setRegNum(RegNum); 475 Reg->setRegNum(RegNum);
476 PhysicalRegisters[RegNum] = Reg; 476 PhysicalRegisters[RegNum] = Reg;
477 // Specially mark esp as an "argument" so that it is considered
478 // live upon function entry.
479 if (RegNum == RegX8632::Reg_esp)
480 Func->addImplicitArg(Reg);
477 } 481 }
478 return Reg; 482 return Reg;
479 } 483 }
480 484
481 IceString TargetX8632::getRegName(SizeT RegNum, Type Ty) const { 485 IceString TargetX8632::getRegName(SizeT RegNum, Type Ty) const {
482 assert(RegNum < RegX8632::Reg_NUM); 486 assert(RegNum < RegX8632::Reg_NUM);
483 static IceString RegNames8[] = { 487 static IceString RegNames8[] = {
484 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ 488 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
485 frameptr, isI8, isInt, isFP) \ 489 frameptr, isI8, isInt, isFP) \
486 name8, 490 name8,
(...skipping 11 matching lines...) Expand all
498 case IceType_i1: 502 case IceType_i1:
499 case IceType_i8: 503 case IceType_i8:
500 return RegNames8[RegNum]; 504 return RegNames8[RegNum];
501 case IceType_i16: 505 case IceType_i16:
502 return RegNames16[RegNum]; 506 return RegNames16[RegNum];
503 default: 507 default:
504 return RegNames[RegNum]; 508 return RegNames[RegNum];
505 } 509 }
506 } 510 }
507 511
508 void TargetX8632::emitVariable(const Variable *Var, const Cfg *Func) const { 512 void TargetX8632::emitVariable(const Variable *Var) const {
509 Ostream &Str = Ctx->getStrEmit(); 513 Ostream &Str = Ctx->getStrEmit();
510 assert(Var->getLocalUseNode() == NULL ||
511 Var->getLocalUseNode() == Func->getCurrentNode());
512 if (Var->hasReg()) { 514 if (Var->hasReg()) {
513 Str << getRegName(Var->getRegNum(), Var->getType()); 515 Str << getRegName(Var->getRegNum(), Var->getType());
514 return; 516 return;
515 } 517 }
516 Str << InstX8632::getWidthString(Var->getType()); 518 Str << InstX8632::getWidthString(Var->getType());
517 Str << " [" << getRegName(getFrameOrStackReg(), IceType_i32); 519 Str << " [" << getRegName(getFrameOrStackReg(), IceType_i32);
518 int32_t Offset = Var->getStackOffset(); 520 int32_t Offset = Var->getStackOffset();
519 if (!hasFramePointer()) 521 if (!hasFramePointer())
520 Offset += getStackAdjustment(); 522 Offset += getStackAdjustment();
521 if (Offset) { 523 if (Offset) {
(...skipping 19 matching lines...) Expand all
541 Variable *Arg = Args[I]; 543 Variable *Arg = Args[I];
542 Type Ty = Arg->getType(); 544 Type Ty = Arg->getType();
543 if (!isVectorType(Ty)) 545 if (!isVectorType(Ty))
544 continue; 546 continue;
545 // Replace Arg in the argument list with the home register. Then 547 // Replace Arg in the argument list with the home register. Then
546 // generate an instruction in the prolog to copy the home register 548 // generate an instruction in the prolog to copy the home register
547 // to the assigned location of Arg. 549 // to the assigned location of Arg.
548 int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs; 550 int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs;
549 ++NumXmmArgs; 551 ++NumXmmArgs;
550 IceString Name = "home_reg:" + Arg->getName(); 552 IceString Name = "home_reg:" + Arg->getName();
551 const CfgNode *DefNode = NULL; 553 Variable *RegisterArg = Func->makeVariable(Ty, Name);
552 Variable *RegisterArg = Func->makeVariable(Ty, DefNode, Name);
553 RegisterArg->setRegNum(RegNum); 554 RegisterArg->setRegNum(RegNum);
554 RegisterArg->setIsArg(Func); 555 RegisterArg->setIsArg();
555 Arg->setIsArg(Func, false); 556 Arg->setIsArg(false);
556 557
557 Args[I] = RegisterArg; 558 Args[I] = RegisterArg;
558 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); 559 Context.insert(InstAssign::create(Func, Arg, RegisterArg));
559 } 560 }
560 } 561 }
561 562
562 void TargetX8632::sortByAlignment(VarList &Dest, const VarList &Source) const { 563 void TargetX8632::sortByAlignment(VarList &Dest, const VarList &Source) const {
563 // Sort the variables into buckets according to the log of their width 564 // Sort the variables into buckets according to the log of their width
564 // in bytes. 565 // in bytes.
565 const SizeT NumBuckets = 566 const SizeT NumBuckets =
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // block 1 and C is local to block 2, then C may share a slot with A or B. 669 // block 1 and C is local to block 2, then C may share a slot with A or B.
669 // 670 //
670 // We cannot coalesce stack slots if this function calls a "returns twice" 671 // We cannot coalesce stack slots if this function calls a "returns twice"
671 // function. In that case, basic blocks may be revisited, and variables 672 // function. In that case, basic blocks may be revisited, and variables
672 // local to those basic blocks are actually live until after the 673 // local to those basic blocks are actually live until after the
673 // called function returns a second time. 674 // called function returns a second time.
674 const bool SimpleCoalescing = !callsReturnsTwice(); 675 const bool SimpleCoalescing = !callsReturnsTwice();
675 size_t InArgsSizeBytes = 0; 676 size_t InArgsSizeBytes = 0;
676 size_t PreservedRegsSizeBytes = 0; 677 size_t PreservedRegsSizeBytes = 0;
677 SpillAreaSizeBytes = 0; 678 SpillAreaSizeBytes = 0;
679 const VariablesMetadata *VMetadata = Func->getVMetadata();
678 Context.init(Node); 680 Context.init(Node);
679 Context.setInsertPoint(Context.getCur()); 681 Context.setInsertPoint(Context.getCur());
680 682
681 // Determine stack frame offsets for each Variable without a 683 // Determine stack frame offsets for each Variable without a
682 // register assignment. This can be done as one variable per stack 684 // register assignment. This can be done as one variable per stack
683 // slot. Or, do coalescing by running the register allocator again 685 // slot. Or, do coalescing by running the register allocator again
684 // with an infinite set of registers (as a side effect, this gives 686 // with an infinite set of registers (as a side effect, this gives
685 // variables a second chance at physical register assignment). 687 // variables a second chance at physical register assignment).
686 // 688 //
687 // A middle ground approach is to leverage sparsity and allocate one 689 // A middle ground approach is to leverage sparsity and allocate one
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 738
737 SortedSpilledVariables.reserve(SpilledVariables.size()); 739 SortedSpilledVariables.reserve(SpilledVariables.size());
738 sortByAlignment(SortedSpilledVariables, SpilledVariables); 740 sortByAlignment(SortedSpilledVariables, SpilledVariables);
739 for (VarList::const_iterator I = SortedSpilledVariables.begin(), 741 for (VarList::const_iterator I = SortedSpilledVariables.begin(),
740 E = SortedSpilledVariables.end(); 742 E = SortedSpilledVariables.end();
741 I != E; ++I) { 743 I != E; ++I) {
742 Variable *Var = *I; 744 Variable *Var = *I;
743 size_t Increment = typeWidthInBytesOnStack(Var->getType()); 745 size_t Increment = typeWidthInBytesOnStack(Var->getType());
744 if (!SpillAreaAlignmentBytes) 746 if (!SpillAreaAlignmentBytes)
745 SpillAreaAlignmentBytes = Increment; 747 SpillAreaAlignmentBytes = Increment;
746 if (SimpleCoalescing) { 748 if (SimpleCoalescing && VMetadata->isTracked(Var)) {
747 if (Var->isMultiblockLife()) { 749 if (VMetadata->isMultiBlock(Var)) {
748 GlobalsSize += Increment; 750 GlobalsSize += Increment;
749 } else { 751 } else {
750 SizeT NodeIndex = Var->getLocalUseNode()->getIndex(); 752 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex();
751 LocalsSize[NodeIndex] += Increment; 753 LocalsSize[NodeIndex] += Increment;
752 if (LocalsSize[NodeIndex] > SpillAreaSizeBytes) 754 if (LocalsSize[NodeIndex] > SpillAreaSizeBytes)
753 SpillAreaSizeBytes = LocalsSize[NodeIndex]; 755 SpillAreaSizeBytes = LocalsSize[NodeIndex];
754 if (!LocalsSlotsAlignmentBytes) 756 if (!LocalsSlotsAlignmentBytes)
755 LocalsSlotsAlignmentBytes = Increment; 757 LocalsSlotsAlignmentBytes = Increment;
756 } 758 }
757 } else { 759 } else {
758 SpillAreaSizeBytes += Increment; 760 SpillAreaSizeBytes += Increment;
759 } 761 }
760 } 762 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 847
846 // Fill in stack offsets for locals. 848 // Fill in stack offsets for locals.
847 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; 849 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes;
848 LocalsSize.assign(LocalsSize.size(), 0); 850 LocalsSize.assign(LocalsSize.size(), 0);
849 size_t NextStackOffset = GlobalsSpaceUsed; 851 size_t NextStackOffset = GlobalsSpaceUsed;
850 for (VarList::const_iterator I = SortedSpilledVariables.begin(), 852 for (VarList::const_iterator I = SortedSpilledVariables.begin(),
851 E = SortedSpilledVariables.end(); 853 E = SortedSpilledVariables.end();
852 I != E; ++I) { 854 I != E; ++I) {
853 Variable *Var = *I; 855 Variable *Var = *I;
854 size_t Increment = typeWidthInBytesOnStack(Var->getType()); 856 size_t Increment = typeWidthInBytesOnStack(Var->getType());
855 if (SimpleCoalescing) { 857 if (SimpleCoalescing && VMetadata->isTracked(Var)) {
856 if (Var->isMultiblockLife()) { 858 if (VMetadata->isMultiBlock(Var)) {
857 GlobalsSpaceUsed += Increment; 859 GlobalsSpaceUsed += Increment;
858 NextStackOffset = GlobalsSpaceUsed; 860 NextStackOffset = GlobalsSpaceUsed;
859 } else { 861 } else {
860 SizeT NodeIndex = Var->getLocalUseNode()->getIndex(); 862 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex();
861 LocalsSize[NodeIndex] += Increment; 863 LocalsSize[NodeIndex] += Increment;
862 NextStackOffset = SpillAreaPaddingBytes + 864 NextStackOffset = SpillAreaPaddingBytes +
863 GlobalsAndSubsequentPaddingSize + 865 GlobalsAndSubsequentPaddingSize +
864 LocalsSize[NodeIndex]; 866 LocalsSize[NodeIndex];
865 } 867 }
866 } else { 868 } else {
867 NextStackOffset += Increment; 869 NextStackOffset += Increment;
868 } 870 }
869 if (IsEbpBasedFrame) 871 if (IsEbpBasedFrame)
870 Var->setStackOffset(-NextStackOffset); 872 Var->setStackOffset(-NextStackOffset);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 case IceType_f64: 1030 case IceType_f64:
1029 break; 1031 break;
1030 } 1032 }
1031 Variable *Lo = Var->getLo(); 1033 Variable *Lo = Var->getLo();
1032 Variable *Hi = Var->getHi(); 1034 Variable *Hi = Var->getHi();
1033 if (Lo) { 1035 if (Lo) {
1034 assert(Hi); 1036 assert(Hi);
1035 return; 1037 return;
1036 } 1038 }
1037 assert(Hi == NULL); 1039 assert(Hi == NULL);
1038 Lo = Func->makeVariable(IceType_i32, Context.getNode(), 1040 Lo = Func->makeVariable(IceType_i32, Var->getName() + "__lo");
1039 Var->getName() + "__lo"); 1041 Hi = Func->makeVariable(IceType_i32, Var->getName() + "__hi");
1040 Hi = Func->makeVariable(IceType_i32, Context.getNode(),
1041 Var->getName() + "__hi");
1042 Var->setLoHi(Lo, Hi); 1042 Var->setLoHi(Lo, Hi);
1043 if (Var->getIsArg()) { 1043 if (Var->getIsArg()) {
1044 Lo->setIsArg(Func); 1044 Lo->setIsArg();
1045 Hi->setIsArg(Func); 1045 Hi->setIsArg();
1046 } 1046 }
1047 } 1047 }
1048 1048
1049 Operand *TargetX8632::loOperand(Operand *Operand) { 1049 Operand *TargetX8632::loOperand(Operand *Operand) {
1050 assert(Operand->getType() == IceType_i64); 1050 assert(Operand->getType() == IceType_i64);
1051 if (Operand->getType() != IceType_i64) 1051 if (Operand->getType() != IceType_i64)
1052 return Operand; 1052 return Operand;
1053 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1053 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1054 split64(Var); 1054 split64(Var);
1055 return Var->getLo(); 1055 return Var->getLo();
(...skipping 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 (void)DestType; 2269 (void)DestType;
2270 assert((DestType == IceType_i32 && SrcType == IceType_f32) || 2270 assert((DestType == IceType_i32 && SrcType == IceType_f32) ||
2271 (DestType == IceType_f32 && SrcType == IceType_i32)); 2271 (DestType == IceType_f32 && SrcType == IceType_i32));
2272 // a.i32 = bitcast b.f32 ==> 2272 // a.i32 = bitcast b.f32 ==>
2273 // t.f32 = b.f32 2273 // t.f32 = b.f32
2274 // s.f32 = spill t.f32 2274 // s.f32 = spill t.f32
2275 // a.i32 = s.f32 2275 // a.i32 = s.f32
2276 Variable *T = NULL; 2276 Variable *T = NULL;
2277 // TODO: Should be able to force a spill setup by calling legalize() with 2277 // TODO: Should be able to force a spill setup by calling legalize() with
2278 // Legal_Mem and not Legal_Reg or Legal_Imm. 2278 // Legal_Mem and not Legal_Reg or Legal_Imm.
2279 SpillVariable *SpillVar = 2279 SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(SrcType);
2280 Func->makeVariable<SpillVariable>(SrcType, Context.getNode());
2281 SpillVar->setLinkedTo(Dest); 2280 SpillVar->setLinkedTo(Dest);
2282 Variable *Spill = SpillVar; 2281 Variable *Spill = SpillVar;
2283 Spill->setWeight(RegWeight::Zero); 2282 Spill->setWeight(RegWeight::Zero);
2284 _mov(T, Src0RM); 2283 _mov(T, Src0RM);
2285 _mov(Spill, T); 2284 _mov(Spill, T);
2286 _mov(Dest, Spill); 2285 _mov(Dest, Spill);
2287 } break; 2286 } break;
2288 case IceType_i64: { 2287 case IceType_i64: {
2289 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2288 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2290 assert(Src0RM->getType() == IceType_f64); 2289 assert(Src0RM->getType() == IceType_f64);
2291 // a.i64 = bitcast b.f64 ==> 2290 // a.i64 = bitcast b.f64 ==>
2292 // s.f64 = spill b.f64 2291 // s.f64 = spill b.f64
2293 // t_lo.i32 = lo(s.f64) 2292 // t_lo.i32 = lo(s.f64)
2294 // a_lo.i32 = t_lo.i32 2293 // a_lo.i32 = t_lo.i32
2295 // t_hi.i32 = hi(s.f64) 2294 // t_hi.i32 = hi(s.f64)
2296 // a_hi.i32 = t_hi.i32 2295 // a_hi.i32 = t_hi.i32
2297 SpillVariable *SpillVar = 2296 SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(IceType_f64);
2298 Func->makeVariable<SpillVariable>(IceType_f64, Context.getNode());
2299 SpillVar->setLinkedTo(llvm::dyn_cast<Variable>(Src0RM)); 2297 SpillVar->setLinkedTo(llvm::dyn_cast<Variable>(Src0RM));
2300 Variable *Spill = SpillVar; 2298 Variable *Spill = SpillVar;
2301 Spill->setWeight(RegWeight::Zero); 2299 Spill->setWeight(RegWeight::Zero);
2302 _movq(Spill, Src0RM); 2300 _movq(Spill, Src0RM);
2303 2301
2304 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2302 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2305 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2303 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2306 Variable *T_Lo = makeReg(IceType_i32); 2304 Variable *T_Lo = makeReg(IceType_i32);
2307 Variable *T_Hi = makeReg(IceType_i32); 2305 Variable *T_Hi = makeReg(IceType_i32);
2308 VariableSplit *SpillLo = 2306 VariableSplit *SpillLo =
2309 VariableSplit::create(Func, Spill, VariableSplit::Low); 2307 VariableSplit::create(Func, Spill, VariableSplit::Low);
2310 VariableSplit *SpillHi = 2308 VariableSplit *SpillHi =
2311 VariableSplit::create(Func, Spill, VariableSplit::High); 2309 VariableSplit::create(Func, Spill, VariableSplit::High);
2312 2310
2313 _mov(T_Lo, SpillLo); 2311 _mov(T_Lo, SpillLo);
2314 _mov(DestLo, T_Lo); 2312 _mov(DestLo, T_Lo);
2315 _mov(T_Hi, SpillHi); 2313 _mov(T_Hi, SpillHi);
2316 _mov(DestHi, T_Hi); 2314 _mov(DestHi, T_Hi);
2317 } break; 2315 } break;
2318 case IceType_f64: { 2316 case IceType_f64: {
2319 Src0 = legalize(Src0); 2317 Src0 = legalize(Src0);
2320 assert(Src0->getType() == IceType_i64); 2318 assert(Src0->getType() == IceType_i64);
2321 // a.f64 = bitcast b.i64 ==> 2319 // a.f64 = bitcast b.i64 ==>
2322 // t_lo.i32 = b_lo.i32 2320 // t_lo.i32 = b_lo.i32
2323 // FakeDef(s.f64) 2321 // FakeDef(s.f64)
2324 // lo(s.f64) = t_lo.i32 2322 // lo(s.f64) = t_lo.i32
2325 // t_hi.i32 = b_hi.i32 2323 // t_hi.i32 = b_hi.i32
2326 // hi(s.f64) = t_hi.i32 2324 // hi(s.f64) = t_hi.i32
2327 // a.f64 = s.f64 2325 // a.f64 = s.f64
2328 SpillVariable *SpillVar = 2326 SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(IceType_f64);
2329 Func->makeVariable<SpillVariable>(IceType_f64, Context.getNode());
2330 SpillVar->setLinkedTo(Dest); 2327 SpillVar->setLinkedTo(Dest);
2331 Variable *Spill = SpillVar; 2328 Variable *Spill = SpillVar;
2332 Spill->setWeight(RegWeight::Zero); 2329 Spill->setWeight(RegWeight::Zero);
2333 2330
2334 Variable *T_Lo = NULL, *T_Hi = NULL; 2331 Variable *T_Lo = NULL, *T_Hi = NULL;
2335 VariableSplit *SpillLo = 2332 VariableSplit *SpillLo =
2336 VariableSplit::create(Func, Spill, VariableSplit::Low); 2333 VariableSplit::create(Func, Spill, VariableSplit::Low);
2337 VariableSplit *SpillHi = 2334 VariableSplit *SpillHi =
2338 VariableSplit::create(Func, Spill, VariableSplit::High); 2335 VariableSplit::create(Func, Spill, VariableSplit::High);
2339 _mov(T_Lo, loOperand(Src0)); 2336 _mov(T_Lo, loOperand(Src0));
2340 // Technically, the Spill is defined after the _store happens, but 2337 // Technically, the Spill is defined after the _store happens, but
2341 // SpillLo is considered a "use" of Spill so define Spill before it 2338 // SpillLo is considered a "use" of Spill so define Spill before it
2342 // is used. 2339 // is used.
2343 Context.insert(InstFakeDef::create(Func, Spill)); 2340 Context.insert(InstFakeDef::create(Func, Spill));
2344 _store(T_Lo, SpillLo); 2341 _store(T_Lo, SpillLo);
2345 _mov(T_Hi, hiOperand(Src0)); 2342 _mov(T_Hi, hiOperand(Src0));
2346 _store(T_Hi, SpillHi); 2343 _store(T_Hi, SpillHi);
2347 _movq(Dest, Spill); 2344 _movq(Dest, Spill);
2348 } break; 2345 } break;
2349 case IceType_v8i1: { 2346 case IceType_v8i1: {
2350 assert(Src0->getType() == IceType_i8); 2347 assert(Src0->getType() == IceType_i8);
2351 InstCall *Call = makeHelperCall("Sz_bitcast_i8_to_v8i1", Dest, 1); 2348 InstCall *Call = makeHelperCall("Sz_bitcast_i8_to_v8i1", Dest, 1);
2352 Variable *Src0AsI32 = Func->makeVariable(stackSlotType(), 2349 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
2353 Context.getNode());
2354 // Arguments to functions are required to be at least 32 bits wide. 2350 // Arguments to functions are required to be at least 32 bits wide.
2355 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2351 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2356 Call->addArg(Src0AsI32); 2352 Call->addArg(Src0AsI32);
2357 lowerCall(Call); 2353 lowerCall(Call);
2358 } break; 2354 } break;
2359 case IceType_v16i1: { 2355 case IceType_v16i1: {
2360 assert(Src0->getType() == IceType_i16); 2356 assert(Src0->getType() == IceType_i16);
2361 InstCall *Call = makeHelperCall("Sz_bitcast_i16_to_v16i1", Dest, 1); 2357 InstCall *Call = makeHelperCall("Sz_bitcast_i16_to_v16i1", Dest, 1);
2362 Variable *Src0AsI32 = Func->makeVariable(stackSlotType(), 2358 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
2363 Context.getNode());
2364 // Arguments to functions are required to be at least 32 bits wide. 2359 // Arguments to functions are required to be at least 32 bits wide.
2365 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2360 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2366 Call->addArg(Src0AsI32); 2361 Call->addArg(Src0AsI32);
2367 lowerCall(Call); 2362 lowerCall(Call);
2368 } break; 2363 } break;
2369 case IceType_v8i16: 2364 case IceType_v8i16:
2370 case IceType_v16i8: 2365 case IceType_v16i8:
2371 case IceType_v4i32: 2366 case IceType_v4i32:
2372 case IceType_v4f32: { 2367 case IceType_v4f32: {
2373 _movp(Dest, legalizeToVar(Src0)); 2368 _movp(Dest, legalizeToVar(Src0));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2422 // keep the live range analysis consistent. 2417 // keep the live range analysis consistent.
2423 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); 2418 Context.insert(InstFakeDef::create(Func, ExtractedElementR));
2424 _movss(ExtractedElementR, T); 2419 _movss(ExtractedElementR, T);
2425 } 2420 }
2426 } else { 2421 } else {
2427 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 2422 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
2428 // Spill the value to a stack slot and do the extraction in memory. 2423 // Spill the value to a stack slot and do the extraction in memory.
2429 // 2424 //
2430 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when 2425 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
2431 // support for legalizing to mem is implemented. 2426 // support for legalizing to mem is implemented.
2432 Variable *Slot = Func->makeVariable(Ty, Context.getNode()); 2427 Variable *Slot = Func->makeVariable(Ty);
2433 Slot->setWeight(RegWeight::Zero); 2428 Slot->setWeight(RegWeight::Zero);
2434 _movp(Slot, legalizeToVar(SourceVectNotLegalized)); 2429 _movp(Slot, legalizeToVar(SourceVectNotLegalized));
2435 2430
2436 // Compute the location of the element in memory. 2431 // Compute the location of the element in memory.
2437 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 2432 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
2438 OperandX8632Mem *Loc = 2433 OperandX8632Mem *Loc =
2439 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 2434 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
2440 _mov(ExtractedElementR, Loc); 2435 _mov(ExtractedElementR, Loc);
2441 } 2436 }
2442 2437
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 case IceType_v4i1: 2572 case IceType_v4i1:
2578 NewTy = IceType_v4i32; 2573 NewTy = IceType_v4i32;
2579 break; 2574 break;
2580 case IceType_v8i1: 2575 case IceType_v8i1:
2581 NewTy = IceType_v8i16; 2576 NewTy = IceType_v8i16;
2582 break; 2577 break;
2583 case IceType_v16i1: 2578 case IceType_v16i1:
2584 NewTy = IceType_v16i8; 2579 NewTy = IceType_v16i8;
2585 break; 2580 break;
2586 } 2581 }
2587 Variable *NewSrc0 = Func->makeVariable(NewTy, Context.getNode()); 2582 Variable *NewSrc0 = Func->makeVariable(NewTy);
2588 Variable *NewSrc1 = Func->makeVariable(NewTy, Context.getNode()); 2583 Variable *NewSrc1 = Func->makeVariable(NewTy);
2589 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0)); 2584 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0));
2590 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1)); 2585 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1));
2591 Src0 = NewSrc0; 2586 Src0 = NewSrc0;
2592 Src1 = NewSrc1; 2587 Src1 = NewSrc1;
2593 Ty = NewTy; 2588 Ty = NewTy;
2594 } 2589 }
2595 2590
2596 InstIcmp::ICond Condition = Inst->getCondition(); 2591 InstIcmp::ICond Condition = Inst->getCondition();
2597 2592
2598 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2593 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2753 unsigned Index = ElementIndex->getValue(); 2748 unsigned Index = ElementIndex->getValue();
2754 assert(Index < typeNumElements(SourceVectNotLegalized->getType())); 2749 assert(Index < typeNumElements(SourceVectNotLegalized->getType()));
2755 2750
2756 Type Ty = SourceVectNotLegalized->getType(); 2751 Type Ty = SourceVectNotLegalized->getType();
2757 Type ElementTy = typeElementType(Ty); 2752 Type ElementTy = typeElementType(Ty);
2758 Type InVectorElementTy = getInVectorElementType(Ty); 2753 Type InVectorElementTy = getInVectorElementType(Ty);
2759 2754
2760 if (ElementTy == IceType_i1) { 2755 if (ElementTy == IceType_i1) {
2761 // Expand the element to the appropriate size for it to be inserted 2756 // Expand the element to the appropriate size for it to be inserted
2762 // in the vector. 2757 // in the vector.
2763 Variable *Expanded = 2758 Variable *Expanded = Func->makeVariable(InVectorElementTy);
2764 Func->makeVariable(InVectorElementTy, Context.getNode());
2765 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded, 2759 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded,
2766 ElementToInsertNotLegalized); 2760 ElementToInsertNotLegalized);
2767 lowerCast(Cast); 2761 lowerCast(Cast);
2768 ElementToInsertNotLegalized = Expanded; 2762 ElementToInsertNotLegalized = Expanded;
2769 } 2763 }
2770 2764
2771 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 || InstructionSet >= SSE4_1) { 2765 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 || InstructionSet >= SSE4_1) {
2772 // Use insertps, pinsrb, pinsrw, or pinsrd. 2766 // Use insertps, pinsrb, pinsrw, or pinsrd.
2773 Operand *ElementRM = 2767 Operand *ElementRM =
2774 legalize(ElementToInsertNotLegalized, Legal_Reg | Legal_Mem); 2768 legalize(ElementToInsertNotLegalized, Legal_Reg | Legal_Mem);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2846 _shufps(T, ElementR, Mask2Constant); 2840 _shufps(T, ElementR, Mask2Constant);
2847 _movp(Inst->getDest(), T); 2841 _movp(Inst->getDest(), T);
2848 } 2842 }
2849 } else { 2843 } else {
2850 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 2844 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
2851 // Spill the value to a stack slot and perform the insertion in 2845 // Spill the value to a stack slot and perform the insertion in
2852 // memory. 2846 // memory.
2853 // 2847 //
2854 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when 2848 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
2855 // support for legalizing to mem is implemented. 2849 // support for legalizing to mem is implemented.
2856 Variable *Slot = Func->makeVariable(Ty, Context.getNode()); 2850 Variable *Slot = Func->makeVariable(Ty);
2857 Slot->setWeight(RegWeight::Zero); 2851 Slot->setWeight(RegWeight::Zero);
2858 _movp(Slot, legalizeToVar(SourceVectNotLegalized)); 2852 _movp(Slot, legalizeToVar(SourceVectNotLegalized));
2859 2853
2860 // Compute the location of the position to insert in memory. 2854 // Compute the location of the position to insert in memory.
2861 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 2855 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
2862 OperandX8632Mem *Loc = 2856 OperandX8632Mem *Loc =
2863 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 2857 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
2864 _store(legalizeToVar(ElementToInsertNotLegalized), Loc); 2858 _store(legalizeToVar(ElementToInsertNotLegalized), Loc);
2865 2859
2866 Variable *T = makeReg(Ty); 2860 Variable *T = makeReg(Ty);
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
3116 Call->addArg(Instr->getArg(2)); 3110 Call->addArg(Instr->getArg(2));
3117 lowerCall(Call); 3111 lowerCall(Call);
3118 return; 3112 return;
3119 } 3113 }
3120 case Intrinsics::Memset: { 3114 case Intrinsics::Memset: {
3121 // The value operand needs to be extended to a stack slot size 3115 // The value operand needs to be extended to a stack slot size
3122 // because the PNaCl ABI requires arguments to be at least 32 bits 3116 // because the PNaCl ABI requires arguments to be at least 32 bits
3123 // wide. 3117 // wide.
3124 Operand *ValOp = Instr->getArg(1); 3118 Operand *ValOp = Instr->getArg(1);
3125 assert(ValOp->getType() == IceType_i8); 3119 assert(ValOp->getType() == IceType_i8);
3126 Variable *ValExt = Func->makeVariable(stackSlotType(), Context.getNode()); 3120 Variable *ValExt = Func->makeVariable(stackSlotType());
3127 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); 3121 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp));
3128 InstCall *Call = makeHelperCall("memset", NULL, 3); 3122 InstCall *Call = makeHelperCall("memset", NULL, 3);
3129 Call->addArg(Instr->getArg(0)); 3123 Call->addArg(Instr->getArg(0));
3130 Call->addArg(ValExt); 3124 Call->addArg(ValExt);
3131 Call->addArg(Instr->getArg(2)); 3125 Call->addArg(Instr->getArg(2));
3132 lowerCall(Call); 3126 lowerCall(Call);
3133 return; 3127 return;
3134 } 3128 }
3135 case Intrinsics::NaClReadTP: { 3129 case Intrinsics::NaClReadTP: {
3136 if (Ctx->getFlags().UseSandboxing) { 3130 if (Ctx->getFlags().UseSandboxing) {
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
3572 else 3566 else
3573 Str << "<null>"; 3567 Str << "<null>";
3574 Str << ", Index="; 3568 Str << ", Index=";
3575 if (Index) 3569 if (Index)
3576 Index->dump(Func); 3570 Index->dump(Func);
3577 else 3571 else
3578 Str << "<null>"; 3572 Str << "<null>";
3579 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; 3573 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n";
3580 } 3574 }
3581 3575
3582 bool matchTransitiveAssign(Variable *&Var, const Inst *&Reason) { 3576 bool matchTransitiveAssign(const VariablesMetadata *VMetadata, Variable *&Var,
3577 const Inst *&Reason) {
3583 // Var originates from Var=SrcVar ==> 3578 // Var originates from Var=SrcVar ==>
3584 // set Var:=SrcVar 3579 // set Var:=SrcVar
3585 if (Var == NULL) 3580 if (Var == NULL)
3586 return false; 3581 return false;
3587 if (const Inst *VarAssign = Var->getDefinition()) { 3582 if (const Inst *VarAssign = VMetadata->getDefinition(Var)) {
3588 if (llvm::isa<InstAssign>(VarAssign)) { 3583 if (llvm::isa<InstAssign>(VarAssign)) {
3589 Operand *SrcOp = VarAssign->getSrc(0); 3584 Operand *SrcOp = VarAssign->getSrc(0);
3590 assert(SrcOp); 3585 assert(SrcOp);
3591 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) { 3586 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) {
3592 if (!SrcVar->getIsMultidef() && 3587 if (!VMetadata->isMultiDef(SrcVar) &&
3593 // TODO: ensure SrcVar stays single-BB 3588 // TODO: ensure SrcVar stays single-BB
3594 true) { 3589 true) {
3595 Var = SrcVar; 3590 Var = SrcVar;
3596 Reason = VarAssign; 3591 Reason = VarAssign;
3597 return true; 3592 return true;
3598 } 3593 }
3599 } 3594 }
3600 } 3595 }
3601 } 3596 }
3602 return false; 3597 return false;
3603 } 3598 }
3604 3599
3605 bool matchCombinedBaseIndex(Variable *&Base, Variable *&Index, uint16_t &Shift, 3600 bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata, Variable *&Base,
3601 Variable *&Index, uint16_t &Shift,
3606 const Inst *&Reason) { 3602 const Inst *&Reason) {
3607 // Index==NULL && Base is Base=Var1+Var2 ==> 3603 // Index==NULL && Base is Base=Var1+Var2 ==>
3608 // set Base=Var1, Index=Var2, Shift=0 3604 // set Base=Var1, Index=Var2, Shift=0
3609 if (Base == NULL) 3605 if (Base == NULL)
3610 return false; 3606 return false;
3611 if (Index != NULL) 3607 if (Index != NULL)
3612 return false; 3608 return false;
3613 const Inst *BaseInst = Base->getDefinition(); 3609 const Inst *BaseInst = VMetadata->getDefinition(Base);
3614 if (BaseInst == NULL) 3610 if (BaseInst == NULL)
3615 return false; 3611 return false;
3616 if (BaseInst->getSrcSize() < 2) 3612 if (BaseInst->getSrcSize() < 2)
3617 return false; 3613 return false;
3618 if (Variable *Var1 = llvm::dyn_cast<Variable>(BaseInst->getSrc(0))) { 3614 if (Variable *Var1 = llvm::dyn_cast<Variable>(BaseInst->getSrc(0))) {
3619 if (Var1->getIsMultidef()) 3615 if (VMetadata->isMultiDef(Var1))
3620 return false; 3616 return false;
3621 if (Variable *Var2 = llvm::dyn_cast<Variable>(BaseInst->getSrc(1))) { 3617 if (Variable *Var2 = llvm::dyn_cast<Variable>(BaseInst->getSrc(1))) {
3622 if (Var2->getIsMultidef()) 3618 if (VMetadata->isMultiDef(Var2))
3623 return false; 3619 return false;
3624 if (isAdd(BaseInst) && 3620 if (isAdd(BaseInst) &&
3625 // TODO: ensure Var1 and Var2 stay single-BB 3621 // TODO: ensure Var1 and Var2 stay single-BB
3626 true) { 3622 true) {
3627 Base = Var1; 3623 Base = Var1;
3628 Index = Var2; 3624 Index = Var2;
3629 Shift = 0; // should already have been 0 3625 Shift = 0; // should already have been 0
3630 Reason = BaseInst; 3626 Reason = BaseInst;
3631 return true; 3627 return true;
3632 } 3628 }
3633 } 3629 }
3634 } 3630 }
3635 return false; 3631 return false;
3636 } 3632 }
3637 3633
3638 bool matchShiftedIndex(Variable *&Index, uint16_t &Shift, const Inst *&Reason) { 3634 bool matchShiftedIndex(const VariablesMetadata *VMetadata, Variable *&Index,
3635 uint16_t &Shift, const Inst *&Reason) {
3639 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==> 3636 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==>
3640 // Index=Var, Shift+=log2(Const) 3637 // Index=Var, Shift+=log2(Const)
3641 if (Index == NULL) 3638 if (Index == NULL)
3642 return false; 3639 return false;
3643 const Inst *IndexInst = Index->getDefinition(); 3640 const Inst *IndexInst = VMetadata->getDefinition(Index);
3644 if (IndexInst == NULL) 3641 if (IndexInst == NULL)
3645 return false; 3642 return false;
3646 if (IndexInst->getSrcSize() < 2) 3643 if (IndexInst->getSrcSize() < 2)
3647 return false; 3644 return false;
3648 if (const InstArithmetic *ArithInst = 3645 if (const InstArithmetic *ArithInst =
3649 llvm::dyn_cast<InstArithmetic>(IndexInst)) { 3646 llvm::dyn_cast<InstArithmetic>(IndexInst)) {
3650 if (Variable *Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) { 3647 if (Variable *Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) {
3651 if (ConstantInteger32 *Const = 3648 if (ConstantInteger32 *Const =
3652 llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1))) { 3649 llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1))) {
3653 if (ArithInst->getOp() == InstArithmetic::Mul && 3650 if (ArithInst->getOp() == InstArithmetic::Mul &&
3654 !Var->getIsMultidef() && Const->getType() == IceType_i32) { 3651 !VMetadata->isMultiDef(Var) && Const->getType() == IceType_i32) {
3655 uint64_t Mult = Const->getValue(); 3652 uint64_t Mult = Const->getValue();
3656 uint32_t LogMult; 3653 uint32_t LogMult;
3657 switch (Mult) { 3654 switch (Mult) {
3658 case 1: 3655 case 1:
3659 LogMult = 0; 3656 LogMult = 0;
3660 break; 3657 break;
3661 case 2: 3658 case 2:
3662 LogMult = 1; 3659 LogMult = 1;
3663 break; 3660 break;
3664 case 4: 3661 case 4:
(...skipping 11 matching lines...) Expand all
3676 Reason = IndexInst; 3673 Reason = IndexInst;
3677 return true; 3674 return true;
3678 } 3675 }
3679 } 3676 }
3680 } 3677 }
3681 } 3678 }
3682 } 3679 }
3683 return false; 3680 return false;
3684 } 3681 }
3685 3682
3686 bool matchOffsetBase(Variable *&Base, int32_t &Offset, const Inst *&Reason) { 3683 bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
3684 int32_t &Offset, const Inst *&Reason) {
3687 // Base is Base=Var+Const || Base is Base=Const+Var ==> 3685 // Base is Base=Var+Const || Base is Base=Const+Var ==>
3688 // set Base=Var, Offset+=Const 3686 // set Base=Var, Offset+=Const
3689 // Base is Base=Var-Const ==> 3687 // Base is Base=Var-Const ==>
3690 // set Base=Var, Offset-=Const 3688 // set Base=Var, Offset-=Const
3691 if (Base == NULL) 3689 if (Base == NULL)
3692 return false; 3690 return false;
3693 const Inst *BaseInst = Base->getDefinition(); 3691 const Inst *BaseInst = VMetadata->getDefinition(Base);
3694 if (BaseInst == NULL) 3692 if (BaseInst == NULL)
3695 return false; 3693 return false;
3696 if (const InstArithmetic *ArithInst = 3694 if (const InstArithmetic *ArithInst =
3697 llvm::dyn_cast<const InstArithmetic>(BaseInst)) { 3695 llvm::dyn_cast<const InstArithmetic>(BaseInst)) {
3698 if (ArithInst->getOp() != InstArithmetic::Add && 3696 if (ArithInst->getOp() != InstArithmetic::Add &&
3699 ArithInst->getOp() != InstArithmetic::Sub) 3697 ArithInst->getOp() != InstArithmetic::Sub)
3700 return false; 3698 return false;
3701 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; 3699 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add;
3702 Variable *Var = NULL; 3700 Variable *Var = NULL;
3703 ConstantInteger32 *Const = NULL; 3701 ConstantInteger32 *Const = NULL;
3704 if (Variable *VariableOperand = 3702 if (Variable *VariableOperand =
3705 llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) { 3703 llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) {
3706 Var = VariableOperand; 3704 Var = VariableOperand;
3707 Const = llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1)); 3705 Const = llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1));
3708 } else if (IsAdd) { 3706 } else if (IsAdd) {
3709 Const = llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(0)); 3707 Const = llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(0));
3710 Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1)); 3708 Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1));
3711 } 3709 }
3712 if (Var == NULL || Const == NULL || Var->getIsMultidef()) 3710 if (Var == NULL || Const == NULL || VMetadata->isMultiDef(Var))
3713 return false; 3711 return false;
3714 int32_t MoreOffset = IsAdd ? Const->getValue() : -Const->getValue(); 3712 int32_t MoreOffset = IsAdd ? Const->getValue() : -Const->getValue();
3715 if (WouldOverflowAdd(Offset, MoreOffset)) 3713 if (WouldOverflowAdd(Offset, MoreOffset))
3716 return false; 3714 return false;
3717 Base = Var; 3715 Base = Var;
3718 Offset += MoreOffset; 3716 Offset += MoreOffset;
3719 Reason = BaseInst; 3717 Reason = BaseInst;
3720 return true; 3718 return true;
3721 } 3719 }
3722 return false; 3720 return false;
3723 } 3721 }
3724 3722
3725 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, 3723 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base,
3726 Variable *&Index, uint16_t &Shift, int32_t &Offset) { 3724 Variable *&Index, uint16_t &Shift, int32_t &Offset) {
3727 Func->resetCurrentNode(); 3725 Func->resetCurrentNode();
3728 if (Func->getContext()->isVerbose(IceV_AddrOpt)) { 3726 if (Func->getContext()->isVerbose(IceV_AddrOpt)) {
3729 Ostream &Str = Func->getContext()->getStrDump(); 3727 Ostream &Str = Func->getContext()->getStrDump();
3730 Str << "\nStarting computeAddressOpt for instruction:\n "; 3728 Str << "\nStarting computeAddressOpt for instruction:\n ";
3731 Instr->dumpDecorated(Func); 3729 Instr->dumpDecorated(Func);
3732 } 3730 }
3733 (void)Offset; // TODO: pattern-match for non-zero offsets. 3731 (void)Offset; // TODO: pattern-match for non-zero offsets.
3734 if (Base == NULL) 3732 if (Base == NULL)
3735 return; 3733 return;
3736 // If the Base has more than one use or is live across multiple 3734 // If the Base has more than one use or is live across multiple
3737 // blocks, then don't go further. Alternatively (?), never consider 3735 // blocks, then don't go further. Alternatively (?), never consider
3738 // a transformation that would change a variable that is currently 3736 // a transformation that would change a variable that is currently
3739 // *not* live across basic block boundaries into one that *is*. 3737 // *not* live across basic block boundaries into one that *is*.
3740 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) 3738 if (Func->getVMetadata()->isMultiBlock(Base) /* || Base->getUseCount() > 1*/)
3741 return; 3739 return;
3742 3740
3741 const VariablesMetadata *VMetadata = Func->getVMetadata();
3743 bool Continue = true; 3742 bool Continue = true;
3744 while (Continue) { 3743 while (Continue) {
3745 const Inst *Reason = NULL; 3744 const Inst *Reason = NULL;
3746 if (matchTransitiveAssign(Base, Reason) || 3745 if (matchTransitiveAssign(VMetadata, Base, Reason) ||
3747 matchTransitiveAssign(Index, Reason) || 3746 matchTransitiveAssign(VMetadata, Index, Reason) ||
3748 matchCombinedBaseIndex(Base, Index, Shift, Reason) || 3747 matchCombinedBaseIndex(VMetadata, Base, Index, Shift, Reason) ||
3749 matchShiftedIndex(Index, Shift, Reason) || 3748 matchShiftedIndex(VMetadata, Index, Shift, Reason) ||
3750 matchOffsetBase(Base, Offset, Reason)) { 3749 matchOffsetBase(VMetadata, Base, Offset, Reason)) {
3751 dumpAddressOpt(Func, Base, Index, Shift, Offset, Reason); 3750 dumpAddressOpt(Func, Base, Index, Shift, Offset, Reason);
3752 } else { 3751 } else {
3753 Continue = false; 3752 Continue = false;
3754 } 3753 }
3755 3754
3756 // Index is Index=Var<<Const && Const+Shift<=3 ==> 3755 // Index is Index=Var<<Const && Const+Shift<=3 ==>
3757 // Index=Var, Shift+=Const 3756 // Index=Var, Shift+=Const
3758 3757
3759 // Index is Index=Const*Var && log2(Const)+Shift<=3 ==> 3758 // Index is Index=Const*Var && log2(Const)+Shift<=3 ==>
3760 // Index=Var, Shift+=log2(Const) 3759 // Index=Var, Shift+=log2(Const)
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3932 } 3931 }
3933 // Lower select without SSE4.1: 3932 // Lower select without SSE4.1:
3934 // a=d?b:c ==> 3933 // a=d?b:c ==>
3935 // if elementtype(d) != i1: 3934 // if elementtype(d) != i1:
3936 // d=sext(d); 3935 // d=sext(d);
3937 // a=(b&d)|(c&~d); 3936 // a=(b&d)|(c&~d);
3938 Variable *T2 = makeReg(SrcTy); 3937 Variable *T2 = makeReg(SrcTy);
3939 // Sign extend the condition operand if applicable. 3938 // Sign extend the condition operand if applicable.
3940 if (SrcTy == IceType_v4f32) { 3939 if (SrcTy == IceType_v4f32) {
3941 // The sext operation takes only integer arguments. 3940 // The sext operation takes only integer arguments.
3942 Variable *T3 = Func->makeVariable(IceType_v4i32, Context.getNode()); 3941 Variable *T3 = Func->makeVariable(IceType_v4i32);
3943 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition)); 3942 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition));
3944 _movp(T, T3); 3943 _movp(T, T3);
3945 } else if (typeElementType(SrcTy) != IceType_i1) { 3944 } else if (typeElementType(SrcTy) != IceType_i1) {
3946 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition)); 3945 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition));
3947 } else { 3946 } else {
3948 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); 3947 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem);
3949 _movp(T, ConditionRM); 3948 _movp(T, ConditionRM);
3950 } 3949 }
3951 _movp(T2, T); 3950 _movp(T2, T);
3952 _pand(T, SrcTRM); 3951 _pand(T, SrcTRM);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
4063 assert(isVectorType(Dest->getType())); 4062 assert(isVectorType(Dest->getType()));
4064 Type Ty = Dest->getType(); 4063 Type Ty = Dest->getType();
4065 Type ElementTy = typeElementType(Ty); 4064 Type ElementTy = typeElementType(Ty);
4066 SizeT NumElements = typeNumElements(Ty); 4065 SizeT NumElements = typeNumElements(Ty);
4067 4066
4068 Operand *T = Ctx->getConstantUndef(Ty); 4067 Operand *T = Ctx->getConstantUndef(Ty);
4069 for (SizeT I = 0; I < NumElements; ++I) { 4068 for (SizeT I = 0; I < NumElements; ++I) {
4070 Constant *Index = Ctx->getConstantInt32(IceType_i32, I); 4069 Constant *Index = Ctx->getConstantInt32(IceType_i32, I);
4071 4070
4072 // Extract the next two inputs. 4071 // Extract the next two inputs.
4073 Variable *Op0 = Func->makeVariable(ElementTy, Context.getNode()); 4072 Variable *Op0 = Func->makeVariable(ElementTy);
4074 lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index)); 4073 lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index));
4075 Variable *Op1 = Func->makeVariable(ElementTy, Context.getNode()); 4074 Variable *Op1 = Func->makeVariable(ElementTy);
4076 lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index)); 4075 lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index));
4077 4076
4078 // Perform the arithmetic as a scalar operation. 4077 // Perform the arithmetic as a scalar operation.
4079 Variable *Res = Func->makeVariable(ElementTy, Context.getNode()); 4078 Variable *Res = Func->makeVariable(ElementTy);
4080 lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1)); 4079 lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1));
4081 4080
4082 // Insert the result into position. 4081 // Insert the result into position.
4083 Variable *DestT = Func->makeVariable(Ty, Context.getNode()); 4082 Variable *DestT = Func->makeVariable(Ty);
4084 lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index)); 4083 lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index));
4085 T = DestT; 4084 T = DestT;
4086 // TODO(stichnot): Use postLower() in -Om1 mode to avoid buildup of 4085 // TODO(stichnot): Use postLower() in -Om1 mode to avoid buildup of
4087 // infinite weight temporaries. 4086 // infinite weight temporaries.
4088 } 4087 }
4089 4088
4090 lowerAssign(InstAssign::create(Func, Dest, T)); 4089 lowerAssign(InstAssign::create(Func, Dest, T));
4091 } 4090 }
4092 4091
4093 // The following pattern occurs often in lowered C and C++ code: 4092 // The following pattern occurs often in lowered C and C++ code:
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
4317 llvm::isa<ConstantRelocatable>(Offset)); 4316 llvm::isa<ConstantRelocatable>(Offset));
4318 } 4317 }
4319 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset); 4318 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
4320 } 4319 }
4321 return llvm::cast<OperandX8632Mem>(legalize(Mem)); 4320 return llvm::cast<OperandX8632Mem>(legalize(Mem));
4322 } 4321 }
4323 4322
4324 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { 4323 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
4325 // There aren't any 64-bit integer registers for x86-32. 4324 // There aren't any 64-bit integer registers for x86-32.
4326 assert(Type != IceType_i64); 4325 assert(Type != IceType_i64);
4327 Variable *Reg = Func->makeVariable(Type, Context.getNode()); 4326 Variable *Reg = Func->makeVariable(Type);
4328 if (RegNum == Variable::NoRegister) 4327 if (RegNum == Variable::NoRegister)
4329 Reg->setWeightInfinite(); 4328 Reg->setWeightInfinite();
4330 else 4329 else
4331 Reg->setRegNum(RegNum); 4330 Reg->setRegNum(RegNum);
4332 return Reg; 4331 return Reg;
4333 } 4332 }
4334 4333
4335 void TargetX8632::postLower() { 4334 void TargetX8632::postLower() {
4336 if (Ctx->getOptLevel() != Opt_m1) 4335 if (Ctx->getOptLevel() != Opt_m1)
4337 return; 4336 return;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
4552 Str << "\t.align\t" << Align << "\n"; 4551 Str << "\t.align\t" << Align << "\n";
4553 Str << MangledName << ":\n"; 4552 Str << MangledName << ":\n";
4554 for (SizeT i = 0; i < Size; ++i) { 4553 for (SizeT i = 0; i < Size; ++i) {
4555 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; 4554 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
4556 } 4555 }
4557 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; 4556 Str << "\t.size\t" << MangledName << ", " << Size << "\n";
4558 } 4557 }
4559 } 4558 }
4560 4559
4561 } // end of namespace Ice 4560 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/PNaClTranslator.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698