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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 680733002: Subzero: Allow delaying Phi lowering until after register allocation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix vector const undef lowering for phis. Created 6 years, 1 month 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/IceTimerTree.def » ('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
11 // consists almost entirely of the lowering sequence for each 11 // consists almost entirely of the lowering sequence for each
12 // high-level instruction. It also implements 12 // high-level instruction. It also implements
13 // TargetX8632Fast::postLower() which does the simplest possible 13 // TargetX8632Fast::postLower() which does the simplest possible
14 // register allocation for the "fast" target. 14 // register allocation for the "fast" target.
15 // 15 //
16 //===----------------------------------------------------------------------===// 16 //===----------------------------------------------------------------------===//
17 17
18 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/Support/CommandLine.h" 19 #include "llvm/Support/CommandLine.h"
20 #include "llvm/Support/MathExtras.h" 20 #include "llvm/Support/MathExtras.h"
21 21
22 #include "IceCfg.h" 22 #include "IceCfg.h"
23 #include "IceCfgNode.h" 23 #include "IceCfgNode.h"
24 #include "IceClFlags.h" 24 #include "IceClFlags.h"
25 #include "IceDefs.h" 25 #include "IceDefs.h"
26 #include "IceGlobalInits.h" 26 #include "IceGlobalInits.h"
27 #include "IceInstX8632.h" 27 #include "IceInstX8632.h"
28 #include "IceLiveness.h"
28 #include "IceOperand.h" 29 #include "IceOperand.h"
29 #include "IceRegistersX8632.h" 30 #include "IceRegistersX8632.h"
30 #include "IceTargetLoweringX8632.def" 31 #include "IceTargetLoweringX8632.def"
31 #include "IceTargetLoweringX8632.h" 32 #include "IceTargetLoweringX8632.h"
32 #include "IceUtils.h" 33 #include "IceUtils.h"
33 34
34 namespace Ice { 35 namespace Ice {
35 36
36 namespace { 37 namespace {
37 38
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); 270 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE");
270 ICETYPE_TABLE; 271 ICETYPE_TABLE;
271 #undef X 272 #undef X
272 } // end of namespace dummy3 273 } // end of namespace dummy3
273 274
274 } // end of anonymous namespace 275 } // end of anonymous namespace
275 276
276 TargetX8632::TargetX8632(Cfg *Func) 277 TargetX8632::TargetX8632(Cfg *Func)
277 : TargetLowering(Func), InstructionSet(CLInstructionSet), 278 : TargetLowering(Func), InstructionSet(CLInstructionSet),
278 IsEbpBasedFrame(false), NeedsStackAlignment(false), FrameSizeLocals(0), 279 IsEbpBasedFrame(false), NeedsStackAlignment(false), FrameSizeLocals(0),
279 SpillAreaSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false), 280 SpillAreaSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false) {
280 PhysicalRegisters(VarList(RegX8632::Reg_NUM)) {
281 // TODO: Don't initialize IntegerRegisters and friends every time. 281 // TODO: Don't initialize IntegerRegisters and friends every time.
282 // Instead, initialize in some sort of static initializer for the 282 // Instead, initialize in some sort of static initializer for the
283 // class. 283 // class.
284 llvm::SmallBitVector IntegerRegisters(RegX8632::Reg_NUM); 284 llvm::SmallBitVector IntegerRegisters(RegX8632::Reg_NUM);
285 llvm::SmallBitVector IntegerRegistersI8(RegX8632::Reg_NUM); 285 llvm::SmallBitVector IntegerRegistersI8(RegX8632::Reg_NUM);
286 llvm::SmallBitVector FloatRegisters(RegX8632::Reg_NUM); 286 llvm::SmallBitVector FloatRegisters(RegX8632::Reg_NUM);
287 llvm::SmallBitVector VectorRegisters(RegX8632::Reg_NUM); 287 llvm::SmallBitVector VectorRegisters(RegX8632::Reg_NUM);
288 llvm::SmallBitVector InvalidRegisters(RegX8632::Reg_NUM); 288 llvm::SmallBitVector InvalidRegisters(RegX8632::Reg_NUM);
289 ScratchRegs.resize(RegX8632::Reg_NUM); 289 ScratchRegs.resize(RegX8632::Reg_NUM);
290 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ 290 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
(...skipping 18 matching lines...) Expand all
309 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; 309 TypeToRegisterSet[IceType_v16i1] = VectorRegisters;
310 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; 310 TypeToRegisterSet[IceType_v16i8] = VectorRegisters;
311 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; 311 TypeToRegisterSet[IceType_v8i16] = VectorRegisters;
312 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; 312 TypeToRegisterSet[IceType_v4i32] = VectorRegisters;
313 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; 313 TypeToRegisterSet[IceType_v4f32] = VectorRegisters;
314 } 314 }
315 315
316 void TargetX8632::translateO2() { 316 void TargetX8632::translateO2() {
317 TimerMarker T(TimerStack::TT_O2, Func); 317 TimerMarker T(TimerStack::TT_O2, Func);
318 318
319 // Lower Phi instructions. 319 if (!Ctx->getFlags().PhiEdgeSplit) {
320 Func->placePhiLoads(); 320 // Lower Phi instructions.
321 if (Func->hasError()) 321 Func->placePhiLoads();
322 return; 322 if (Func->hasError())
323 Func->placePhiStores(); 323 return;
324 if (Func->hasError()) 324 Func->placePhiStores();
325 return; 325 if (Func->hasError())
326 Func->deletePhis(); 326 return;
327 if (Func->hasError()) 327 Func->deletePhis();
328 return; 328 if (Func->hasError())
329 Func->dump("After Phi lowering"); 329 return;
330 Func->dump("After Phi lowering");
331 }
330 332
331 // Address mode optimization. 333 // Address mode optimization.
332 Func->getVMetadata()->init(VMK_SingleDefs); 334 Func->getVMetadata()->init(VMK_SingleDefs);
333 Func->doAddressOpt(); 335 Func->doAddressOpt();
334 336
335 // Argument lowering 337 // Argument lowering
336 Func->doArgLowering(); 338 Func->doArgLowering();
337 339
338 // Target lowering. This requires liveness analysis for some parts 340 // Target lowering. This requires liveness analysis for some parts
339 // of the lowering decisions, such as compare/branch fusing. If 341 // of the lowering decisions, such as compare/branch fusing. If
340 // non-lightweight liveness analysis is used, the instructions need 342 // non-lightweight liveness analysis is used, the instructions need
341 // to be renumbered first. TODO: This renumbering should only be 343 // to be renumbered first. TODO: This renumbering should only be
342 // necessary if we're actually calculating live intervals, which we 344 // necessary if we're actually calculating live intervals, which we
343 // only do for register allocation. 345 // only do for register allocation.
344 Func->renumberInstructions(); 346 Func->renumberInstructions();
345 if (Func->hasError()) 347 if (Func->hasError())
346 return; 348 return;
347 349
348 // TODO: It should be sufficient to use the fastest liveness 350 // TODO: It should be sufficient to use the fastest liveness
349 // calculation, i.e. livenessLightweight(). However, for some 351 // calculation, i.e. livenessLightweight(). However, for some
350 // reason that slows down the rest of the translation. Investigate. 352 // reason that slows down the rest of the translation. Investigate.
351 Func->liveness(Liveness_Basic); 353 Func->liveness(Liveness_Basic);
352 if (Func->hasError()) 354 if (Func->hasError())
353 return; 355 return;
354 Func->dump("After x86 address mode opt"); 356 Func->dump("After x86 address mode opt");
355 357
356 Func->genCode(); 358 Func->genCode();
357 if (Func->hasError()) 359 if (Func->hasError())
358 return; 360 return;
361 Func->dump("After x86 codegen");
359 362
360 // Register allocation. This requires instruction renumbering and 363 // Register allocation. This requires instruction renumbering and
361 // full liveness analysis. 364 // full liveness analysis.
362 Func->renumberInstructions(); 365 Func->renumberInstructions();
363 if (Func->hasError()) 366 if (Func->hasError())
364 return; 367 return;
365 Func->liveness(Liveness_Intervals); 368 Func->liveness(Liveness_Intervals);
366 if (Func->hasError()) 369 if (Func->hasError())
367 return; 370 return;
368 // Validate the live range computations. The expensive validation 371 // Validate the live range computations. The expensive validation
369 // call is deliberately only made when assertions are enabled. 372 // call is deliberately only made when assertions are enabled.
370 assert(Func->validateLiveness()); 373 assert(Func->validateLiveness());
371 ComputedLiveRanges = true; 374 ComputedLiveRanges = true;
372 // The post-codegen dump is done here, after liveness analysis and 375 // The post-codegen dump is done here, after liveness analysis and
373 // associated cleanup, to make the dump cleaner and more useful. 376 // associated cleanup, to make the dump cleaner and more useful.
374 Func->dump("After initial x8632 codegen"); 377 Func->dump("After initial x8632 codegen");
375 Func->getVMetadata()->init(VMK_All); 378 Func->getVMetadata()->init(VMK_All);
376 regAlloc(); 379 regAlloc();
377 if (Func->hasError()) 380 if (Func->hasError())
378 return; 381 return;
379 Func->dump("After linear scan regalloc"); 382 Func->dump("After linear scan regalloc");
380 383
384 if (Ctx->getFlags().PhiEdgeSplit) {
385 Func->advancedPhiLowering();
386 Func->dump("After advanced Phi lowering");
387 }
388
381 // Stack frame mapping. 389 // Stack frame mapping.
382 Func->genFrame(); 390 Func->genFrame();
383 if (Func->hasError()) 391 if (Func->hasError())
384 return; 392 return;
385 Func->dump("After stack frame mapping"); 393 Func->dump("After stack frame mapping");
386 394
387 Func->deleteRedundantAssignments(); 395 Func->deleteRedundantAssignments();
396 Func->contractEmptyNodes();
397 Func->reorderNodes();
388 398
389 // Branch optimization. This needs to be done just before code 399 // Branch optimization. This needs to be done just before code
390 // emission. In particular, no transformations that insert or 400 // emission. In particular, no transformations that insert or
391 // reorder CfgNodes should be done after branch optimization. We go 401 // reorder CfgNodes should be done after branch optimization. We go
392 // ahead and do it before nop insertion to reduce the amount of work 402 // ahead and do it before nop insertion to reduce the amount of work
393 // needed for searching for opportunities. 403 // needed for searching for opportunities.
394 Func->doBranchOpt(); 404 Func->doBranchOpt();
395 Func->dump("After branch optimization"); 405 Func->dump("After branch optimization");
396 406
397 // Nop insertion 407 // Nop insertion
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ 454 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
445 frameptr, isI8, isInt, isFP) \ 455 frameptr, isI8, isInt, isFP) \
446 name, 456 name,
447 REGX8632_TABLE 457 REGX8632_TABLE
448 #undef X 458 #undef X
449 }; 459 };
450 460
451 Variable *TargetX8632::getPhysicalRegister(SizeT RegNum, Type Ty) { 461 Variable *TargetX8632::getPhysicalRegister(SizeT RegNum, Type Ty) {
452 if (Ty == IceType_void) 462 if (Ty == IceType_void)
453 Ty = IceType_i32; 463 Ty = IceType_i32;
454 assert(RegNum < PhysicalRegisters.size()); 464 if (PhysicalRegisters[Ty].empty())
455 Variable *Reg = PhysicalRegisters[RegNum]; 465 PhysicalRegisters[Ty].resize(RegX8632::Reg_NUM);
466 assert(RegNum < PhysicalRegisters[Ty].size());
467 Variable *Reg = PhysicalRegisters[Ty][RegNum];
456 if (Reg == NULL) { 468 if (Reg == NULL) {
457 Reg = Func->makeVariable(Ty); 469 Reg = Func->makeVariable(Ty);
458 Reg->setRegNum(RegNum); 470 Reg->setRegNum(RegNum);
459 PhysicalRegisters[RegNum] = Reg; 471 PhysicalRegisters[Ty][RegNum] = Reg;
460 // Specially mark esp as an "argument" so that it is considered 472 // Specially mark esp as an "argument" so that it is considered
461 // live upon function entry. 473 // live upon function entry.
462 if (RegNum == RegX8632::Reg_esp) { 474 if (RegNum == RegX8632::Reg_esp) {
463 Func->addImplicitArg(Reg); 475 Func->addImplicitArg(Reg);
464 Reg->setIgnoreLiveness(); 476 Reg->setIgnoreLiveness();
465 } 477 }
466 } 478 }
467 return Reg; 479 return Reg;
468 } 480 }
469 481
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 for (Variable *Var : Variables) { 716 for (Variable *Var : Variables) {
705 if (Var->hasReg()) { 717 if (Var->hasReg()) {
706 RegsUsed[Var->getRegNum()] = true; 718 RegsUsed[Var->getRegNum()] = true;
707 continue; 719 continue;
708 } 720 }
709 // An argument either does not need a stack slot (if passed in a 721 // An argument either does not need a stack slot (if passed in a
710 // register) or already has one (if passed on the stack). 722 // register) or already has one (if passed on the stack).
711 if (Var->getIsArg()) 723 if (Var->getIsArg())
712 continue; 724 continue;
713 // An unreferenced variable doesn't need a stack slot. 725 // An unreferenced variable doesn't need a stack slot.
714 if (ComputedLiveRanges && Var->getLiveRange().isEmpty()) 726 if (ComputedLiveRanges && !Var->needsStackSlot())
715 continue; 727 continue;
716 // A spill slot linked to a variable with a stack slot should reuse 728 // A spill slot linked to a variable with a stack slot should reuse
717 // that stack slot. 729 // that stack slot.
718 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) { 730 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) {
719 assert(Var->getWeight() == RegWeight::Zero); 731 assert(Var->getWeight() == RegWeight::Zero);
720 if (!SpillVar->getLinkedTo()->hasReg()) { 732 if (!SpillVar->getLinkedTo()->hasReg()) {
721 VariablesLinkedToSpillSlots.push_back(Var); 733 VariablesLinkedToSpillSlots.push_back(Var);
722 continue; 734 continue;
723 } 735 }
724 } 736 }
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 Operand *Src0Lo = loOperand(Src0); 1700 Operand *Src0Lo = loOperand(Src0);
1689 Operand *Src0Hi = hiOperand(Src0); 1701 Operand *Src0Hi = hiOperand(Src0);
1690 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1702 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1691 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1703 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1692 Variable *T_Lo = NULL, *T_Hi = NULL; 1704 Variable *T_Lo = NULL, *T_Hi = NULL;
1693 _mov(T_Lo, Src0Lo); 1705 _mov(T_Lo, Src0Lo);
1694 _mov(DestLo, T_Lo); 1706 _mov(DestLo, T_Lo);
1695 _mov(T_Hi, Src0Hi); 1707 _mov(T_Hi, Src0Hi);
1696 _mov(DestHi, T_Hi); 1708 _mov(DestHi, T_Hi);
1697 } else { 1709 } else {
1698 // RI is either a physical register or an immediate. 1710 // If Dest is in memory, then RI is either a physical register or
1699 Operand *RI = legalize(Src0, Legal_Reg | Legal_Imm); 1711 // an immediate, otherwise RI can be anything.
1712 Operand *RI =
1713 legalize(Src0, Dest->hasReg() ? Legal_All : Legal_Reg | Legal_Imm);
1700 if (isVectorType(Dest->getType())) 1714 if (isVectorType(Dest->getType()))
1701 _movp(Dest, RI); 1715 _movp(Dest, RI);
1702 else 1716 else
1703 _mov(Dest, RI); 1717 _mov(Dest, RI);
1704 } 1718 }
1705 } 1719 }
1706 1720
1707 void TargetX8632::lowerBr(const InstBr *Inst) { 1721 void TargetX8632::lowerBr(const InstBr *Inst) {
1708 if (Inst->isUnconditional()) { 1722 if (Inst->isUnconditional()) {
1709 _br(Inst->getTargetUnconditional()); 1723 _br(Inst->getTargetUnconditional());
(...skipping 2381 matching lines...) Expand 10 before | Expand all | Expand 10 after
4091 } 4105 }
4092 } 4106 }
4093 4107
4094 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { 4108 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) {
4095 const SizeT MaxSrcs = 0; 4109 const SizeT MaxSrcs = 0;
4096 Variable *Dest = NULL; 4110 Variable *Dest = NULL;
4097 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs); 4111 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs);
4098 lowerCall(Call); 4112 lowerCall(Call);
4099 } 4113 }
4100 4114
4115 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to
4116 // preserve integrity of liveness analysis. Undef values are also
4117 // turned into zeroes, since loOperand() and hiOperand() don't expect
4118 // Undef input.
4119 void TargetX8632::prelowerPhis() {
4120 CfgNode *Node = Context.getNode();
4121 for (InstPhi *Phi : Node->getPhis()) {
4122 if (Phi->isDeleted())
4123 continue;
4124 Variable *Dest = Phi->getDest();
4125 if (Dest->getType() == IceType_i64) {
4126 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
4127 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
4128 InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo);
4129 InstPhi *PhiHi = InstPhi::create(Func, Phi->getSrcSize(), DestHi);
4130 for (SizeT I = 0; I < Phi->getSrcSize(); ++I) {
4131 Operand *Src = Phi->getSrc(I);
4132 CfgNode *Label = Phi->getLabel(I);
4133 if (llvm::isa<ConstantUndef>(Src))
4134 Src = Ctx->getConstantZero(Dest->getType());
4135 PhiLo->addArgument(loOperand(Src), Label);
4136 PhiHi->addArgument(hiOperand(Src), Label);
4137 }
4138 Node->getPhis().push_back(PhiLo);
4139 Node->getPhis().push_back(PhiHi);
4140 Phi->setDeleted();
4141 }
4142 }
4143 }
4144
4145 namespace {
4146
4147 bool isMemoryOperand(const Operand *Opnd) {
4148 if (const auto Var = llvm::dyn_cast<Variable>(Opnd))
4149 return !Var->hasReg();
4150 if (llvm::isa<Constant>(Opnd))
4151 return isScalarFloatingType(Opnd->getType());
4152 return true;
4153 }
4154
4155 } // end of anonymous namespace
4156
4157 // Lower the pre-ordered list of assignments into mov instructions.
4158 // Also has to do some ad-hoc register allocation as necessary.
4159 void TargetX8632::lowerPhiAssignments(CfgNode *Node,
4160 const AssignList &Assignments) {
4161 // Check that this is a properly initialized shell of a node.
4162 assert(Node->getOutEdges().size() == 1);
4163 assert(Node->getInsts().empty());
4164 assert(Node->getPhis().empty());
4165 CfgNode *Succ = Node->getOutEdges()[0];
4166 getContext().init(Node);
4167 // Register set setup similar to regAlloc() and postLower().
4168 RegSetMask RegInclude = RegSet_All;
4169 RegSetMask RegExclude = RegSet_StackPointer;
4170 if (hasFramePointer())
4171 RegExclude |= RegSet_FramePointer;
4172 llvm::SmallBitVector Available = getRegisterSet(RegInclude, RegExclude);
4173 bool NeedsRegs = false;
4174 // Initialize the set of available registers to the set of what is
4175 // available (not live) at the beginning of the successor block,
4176 // minus all registers used as Dest operands in the Assignments. To
4177 // do this, we start off assuming all registers are available, then
4178 // iterate through the Assignments and remove Dest registers.
4179 // During this iteration, we also determine whether we will actually
4180 // need any extra registers for memory-to-memory copies. If so, we
4181 // do the actual work of removing the live-in registers from the
4182 // set. TODO(stichnot): This work is being repeated for every split
4183 // edge to the successor, so consider updating LiveIn just once
4184 // after all the edges are split.
4185 for (InstAssign *Assign : Assignments) {
4186 Variable *Dest = Assign->getDest();
4187 if (Dest->hasReg()) {
4188 Available[Dest->getRegNum()] = false;
4189 } else if (isMemoryOperand(Assign->getSrc(0))) {
4190 NeedsRegs = true; // Src and Dest are both in memory
4191 }
4192 }
4193 if (NeedsRegs) {
4194 LivenessBV &LiveIn = Func->getLiveness()->getLiveIn(Succ);
4195 for (int i = LiveIn.find_first(); i != -1; i = LiveIn.find_next(i)) {
4196 Variable *Var = Func->getLiveness()->getVariable(i, Succ);
4197 if (Var->hasReg())
4198 Available[Var->getRegNum()] = false;
4199 }
4200 }
4201 // Iterate backwards through the Assignments. After lowering each
4202 // assignment, add Dest to the set of available registers, and
4203 // remove Src from the set of available registers. Iteration is
4204 // done backwards to enable incremental updates of the available
4205 // register set, and the lowered instruction numbers may be out of
4206 // order, but that can be worked around by renumbering the block
4207 // afterwards if necessary.
4208 for (auto I = Assignments.rbegin(), E = Assignments.rend(); I != E; ++I) {
4209 Context.rewind();
4210 InstAssign *Assign = *I;
4211 Variable *Dest = Assign->getDest();
4212 Operand *Src = Assign->getSrc(0);
4213 Variable *SrcVar = llvm::dyn_cast<Variable>(Src);
4214 // Use normal assignment lowering, except lower mem=mem specially
4215 // so we can register-allocate at the same time.
4216 if (!isMemoryOperand(Dest) || !isMemoryOperand(Src)) {
4217 lowerAssign(Assign);
4218 } else {
4219 assert(Dest->getType() == Src->getType());
4220 const llvm::SmallBitVector &RegsForType =
4221 getRegisterSetForType(Dest->getType());
4222 llvm::SmallBitVector AvailRegsForType = RegsForType & Available;
4223 Variable *SpillLoc = NULL;
4224 Variable *Preg = NULL;
4225 // TODO(stichnot): Opportunity for register randomization.
4226 int32_t RegNum = AvailRegsForType.find_first();
4227 bool IsVector = isVectorType(Dest->getType());
4228 bool NeedSpill = (RegNum == -1);
4229 if (NeedSpill) {
4230 // Pick some register to spill and update RegNum.
4231 // TODO(stichnot): Opportunity for register randomization.
4232 RegNum = RegsForType.find_first();
4233 Preg = getPhysicalRegister(RegNum, Dest->getType());
4234 SpillLoc = Func->makeVariable(Dest->getType());
4235 SpillLoc->setNeedsStackSlot();
4236 if (IsVector)
4237 _movp(SpillLoc, Preg);
4238 else
4239 _mov(SpillLoc, Preg);
4240 }
4241 assert(RegNum >= 0);
4242 if (llvm::isa<ConstantUndef>(Src))
4243 // Materialize an actual constant instead of undef. RegNum is
4244 // passed in for vector types because undef vectors are
4245 // lowered to vector register of zeroes.
4246 Src =
4247 legalize(Src, Legal_All, IsVector ? RegNum : Variable::NoRegister);
4248 Variable *Tmp = makeReg(Dest->getType(), RegNum);
4249 if (IsVector) {
4250 _movp(Tmp, Src);
4251 _movp(Dest, Tmp);
4252 } else {
4253 _mov(Tmp, Src);
4254 _mov(Dest, Tmp);
4255 }
4256 if (NeedSpill) {
4257 // Restore the spilled register.
4258 if (IsVector)
4259 _movp(Preg, SpillLoc);
4260 else
4261 _mov(Preg, SpillLoc);
4262 }
4263 }
4264 // Update register availability before moving to the previous
4265 // instruction on the Assignments list.
4266 if (Dest->hasReg())
4267 Available[Dest->getRegNum()] = true;
4268 if (SrcVar && SrcVar->hasReg())
4269 Available[SrcVar->getRegNum()] = false;
4270 }
4271
4272 // Add the terminator branch instruction to the end.
4273 Context.setInsertPoint(Context.end());
4274 _br(Succ);
4275 }
4276
4101 // There is no support for loading or emitting vector constants, so the 4277 // There is no support for loading or emitting vector constants, so the
4102 // vector values returned from makeVectorOfZeros, makeVectorOfOnes, 4278 // vector values returned from makeVectorOfZeros, makeVectorOfOnes,
4103 // etc. are initialized with register operations. 4279 // etc. are initialized with register operations.
4104 // 4280 //
4105 // TODO(wala): Add limited support for vector constants so that 4281 // TODO(wala): Add limited support for vector constants so that
4106 // complex initialization in registers is unnecessary. 4282 // complex initialization in registers is unnecessary.
4107 4283
4108 Variable *TargetX8632::makeVectorOfZeros(Type Ty, int32_t RegNum) { 4284 Variable *TargetX8632::makeVectorOfZeros(Type Ty, int32_t RegNum) {
4109 Variable *Reg = makeReg(Ty, RegNum); 4285 Variable *Reg = makeReg(Ty, RegNum);
4110 // Insert a FakeDef, since otherwise the live range of Reg might 4286 // Insert a FakeDef, since otherwise the live range of Reg might
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
4222 // results in less predictable code. 4398 // results in less predictable code.
4223 // 4399 //
4224 // If in the future the implementation is changed to lower undef 4400 // If in the future the implementation is changed to lower undef
4225 // values to uninitialized registers, a FakeDef will be needed: 4401 // values to uninitialized registers, a FakeDef will be needed:
4226 // Context.insert(InstFakeDef::create(Func, Reg)); 4402 // Context.insert(InstFakeDef::create(Func, Reg));
4227 // This is in order to ensure that the live range of Reg is not 4403 // This is in order to ensure that the live range of Reg is not
4228 // overestimated. If the constant being lowered is a 64 bit value, 4404 // overestimated. If the constant being lowered is a 64 bit value,
4229 // then the result should be split and the lo and hi components will 4405 // then the result should be split and the lo and hi components will
4230 // need to go in uninitialized registers. 4406 // need to go in uninitialized registers.
4231 if (isVectorType(From->getType())) 4407 if (isVectorType(From->getType()))
4232 return makeVectorOfZeros(From->getType()); 4408 return makeVectorOfZeros(From->getType(), RegNum);
4233 From = Ctx->getConstantZero(From->getType()); 4409 From = Ctx->getConstantZero(From->getType());
4234 } 4410 }
4235 // There should be no constants of vector type (other than undef). 4411 // There should be no constants of vector type (other than undef).
4236 assert(!isVectorType(From->getType())); 4412 assert(!isVectorType(From->getType()));
4237 bool NeedsReg = false; 4413 bool NeedsReg = false;
4238 if (!(Allowed & Legal_Imm)) 4414 if (!(Allowed & Legal_Imm))
4239 // Immediate specifically not allowed 4415 // Immediate specifically not allowed
4240 NeedsReg = true; 4416 NeedsReg = true;
4241 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper 4417 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper
4242 // emitter is used. 4418 // emitter is used.
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
4535 } else if (IsConstant || IsExternal) 4711 } else if (IsConstant || IsExternal)
4536 Str << "\t.zero\t" << Size << "\n"; 4712 Str << "\t.zero\t" << Size << "\n";
4537 // Size is part of .comm. 4713 // Size is part of .comm.
4538 4714
4539 if (IsConstant || HasNonzeroInitializer || IsExternal) 4715 if (IsConstant || HasNonzeroInitializer || IsExternal)
4540 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; 4716 Str << "\t.size\t" << MangledName << ", " << Size << "\n";
4541 // Size is part of .comm. 4717 // Size is part of .comm.
4542 } 4718 }
4543 4719
4544 } // end of namespace Ice 4720 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/IceTimerTree.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698