Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 assert(Node->getOutEdges().size() == 1); | |
|
jvoung (off chromium)
2014/10/29 13:46:50
Would it help to also also assert that the Node is
Jim Stichnoth
2014/10/30 00:25:25
Done.
| |
| 4162 CfgNode *Succ = Node->getOutEdges()[0]; | |
| 4163 getContext().init(Node); | |
| 4164 // Register set setup similar to regAlloc() and postLower(). | |
| 4165 RegSetMask RegInclude = RegSet_All; | |
| 4166 RegSetMask RegExclude = RegSet_StackPointer; | |
| 4167 if (hasFramePointer()) | |
| 4168 RegExclude |= RegSet_FramePointer; | |
| 4169 llvm::SmallBitVector Available = getRegisterSet(RegInclude, RegExclude); | |
| 4170 bool NeedsRegs = false; | |
| 4171 // Initialize the set of available registers to the set of what is | |
| 4172 // available (not live) at the beginning of the block, minus all | |
|
jvoung (off chromium)
2014/10/29 13:46:50
At the beginning of the successor block?
I guess
Jim Stichnoth
2014/10/30 00:25:25
That's right, the beginning of the successor block
| |
| 4173 // registers used as Dest operands in the Assignments. To do this, | |
| 4174 // we start off assuming all registers are available, then iterate | |
| 4175 // through the Assignments and remove Dest registers. During this | |
| 4176 // iteration, we also determine whether we will actually need any | |
| 4177 // extra registers for memory-to-memory copies. If so, we do the | |
| 4178 // actual work of removing the live-in registers from the set. | |
| 4179 for (InstAssign *Assign : Assignments) { | |
| 4180 Variable *Dest = Assign->getDest(); | |
| 4181 if (Dest->hasReg()) { | |
| 4182 Available[Dest->getRegNum()] = false; | |
| 4183 } else if (isMemoryOperand(Assign->getSrc(0))) { | |
| 4184 NeedsRegs = true; // Src and Dest are both in memory | |
| 4185 } | |
| 4186 } | |
| 4187 if (NeedsRegs) { | |
| 4188 LivenessBV &LiveIn = Func->getLiveness()->getLiveIn(Succ); | |
| 4189 for (int i = LiveIn.find_first(); i != -1; i = LiveIn.find_next(i)) { | |
| 4190 Variable *Var = Func->getLiveness()->getVariable(i, Succ); | |
| 4191 if (Var->hasReg()) | |
| 4192 Available[Var->getRegNum()] = false; | |
| 4193 } | |
| 4194 } | |
| 4195 // Iterate backwards through the Assignments. After lowering each | |
| 4196 // assignment, add Dest to the set of available registers, and | |
| 4197 // remove Src from the set of available registers. Iteration is | |
| 4198 // done backwards to enable incremental updates of the available | |
| 4199 // register set, and the lowered instruction numbers may be out of | |
| 4200 // order, but that can be worked around by renumbering the block | |
| 4201 // afterwards if necessary. | |
| 4202 for (auto I = Assignments.rbegin(), E = Assignments.rend(); I != E; ++I) { | |
| 4203 Context.rewind(); | |
| 4204 InstAssign *Assign = *I; | |
| 4205 Variable *Dest = Assign->getDest(); | |
| 4206 Operand *Src = Assign->getSrc(0); | |
| 4207 Variable *SrcVar = llvm::dyn_cast<Variable>(Src); | |
| 4208 // Use normal assignments lowering, except lower mem=mem specially | |
| 4209 // so we can register-allocate at the same time. | |
| 4210 if (!isMemoryOperand(Dest) || !isMemoryOperand(Src)) { | |
| 4211 lowerAssign(Assign); | |
| 4212 } else { | |
| 4213 assert(Dest->getType() == Src->getType()); | |
| 4214 const llvm::SmallBitVector &RegsForType = | |
| 4215 getRegisterSetForType(Dest->getType()); | |
| 4216 llvm::SmallBitVector AvailRegsForType = RegsForType & Available; | |
| 4217 if (AvailRegsForType.any()) { | |
| 4218 // TODO(stichnot): Opportunity for register randomization. | |
| 4219 int32_t RegNum = AvailRegsForType.find_first(); | |
| 4220 Variable *Temp = NULL; | |
| 4221 Operand *NewSrc = Src; | |
| 4222 if (llvm::isa<ConstantUndef>(Src)) { | |
|
jvoung (off chromium)
2014/10/29 13:46:50
Probably rare, but might be good to add a test for
Jim Stichnoth
2014/10/30 00:25:25
Because of the "(!isMemoryOperand(Dest) || !isMemo
jvoung (off chromium)
2014/10/30 15:55:25
How about legalize() in the later else-case? lower
Jim Stichnoth
2014/10/30 19:10:34
I refactored the mem=mem case to be more uniform b
| |
| 4223 if (isVectorType(Src->getType())) | |
| 4224 NewSrc = makeVectorOfZeros(Src->getType()); | |
| 4225 else | |
| 4226 NewSrc = Ctx->getConstantZero(Src->getType()); | |
| 4227 } | |
| 4228 if (isVectorType(Dest->getType())) { | |
| 4229 Temp = makeReg(Dest->getType(), RegNum); | |
| 4230 _movp(Temp, NewSrc); | |
| 4231 _movp(Dest, Temp); | |
| 4232 } else { | |
| 4233 _mov(Temp, NewSrc, RegNum); | |
| 4234 _mov(Dest, Temp); | |
| 4235 } | |
| 4236 } else { | |
| 4237 // TODO(stichnot): Opportunity for register randomization. | |
| 4238 int32_t RegNum = RegsForType.find_first(); | |
| 4239 assert(RegNum >= 0); | |
| 4240 Variable *Preg = getPhysicalRegister(RegNum, Dest->getType()); | |
| 4241 Variable *Tmp1 = Func->makeVariable(Dest->getType()); | |
| 4242 Tmp1->setNeedsStackSlot(); | |
| 4243 // TODO(stichnot): Don't force Tmp1 to be stack-allocated. If | |
| 4244 // there happens to be a free register, it could be used | |
| 4245 // instead. | |
| 4246 Variable *Tmp2 = NULL; | |
| 4247 if (isVectorType(Dest->getType())) { | |
| 4248 Tmp2 = makeReg(Dest->getType(), RegNum); | |
| 4249 _movp(Tmp1, Preg); | |
| 4250 _movp(Tmp2, Src); | |
| 4251 _movp(Dest, Tmp2); | |
| 4252 _movp(Preg, Tmp1); | |
| 4253 } else { | |
| 4254 _mov(Tmp1, Preg); | |
| 4255 _mov(Tmp2, Src, RegNum); | |
| 4256 _mov(Dest, Tmp2); | |
| 4257 _mov(Preg, Tmp1); | |
| 4258 } | |
| 4259 } | |
| 4260 } | |
| 4261 // Update register availability before moving to the previous | |
| 4262 // instruction on the Assignments list. | |
| 4263 if (Dest->hasReg()) | |
| 4264 Available[Dest->getRegNum()] = true; | |
| 4265 if (SrcVar && SrcVar->hasReg()) | |
| 4266 Available[SrcVar->getRegNum()] = false; | |
| 4267 } | |
| 4268 | |
| 4269 // Add the terminator branch instruction to the end. | |
| 4270 Context.setInsertPoint(Context.end()); | |
| 4271 _br(Succ); | |
| 4272 } | |
| 4273 | |
| 4101 // There is no support for loading or emitting vector constants, so the | 4274 // There is no support for loading or emitting vector constants, so the |
| 4102 // vector values returned from makeVectorOfZeros, makeVectorOfOnes, | 4275 // vector values returned from makeVectorOfZeros, makeVectorOfOnes, |
| 4103 // etc. are initialized with register operations. | 4276 // etc. are initialized with register operations. |
| 4104 // | 4277 // |
| 4105 // TODO(wala): Add limited support for vector constants so that | 4278 // TODO(wala): Add limited support for vector constants so that |
| 4106 // complex initialization in registers is unnecessary. | 4279 // complex initialization in registers is unnecessary. |
| 4107 | 4280 |
| 4108 Variable *TargetX8632::makeVectorOfZeros(Type Ty, int32_t RegNum) { | 4281 Variable *TargetX8632::makeVectorOfZeros(Type Ty, int32_t RegNum) { |
| 4109 Variable *Reg = makeReg(Ty, RegNum); | 4282 Variable *Reg = makeReg(Ty, RegNum); |
| 4110 // Insert a FakeDef, since otherwise the live range of Reg might | 4283 // Insert a FakeDef, since otherwise the live range of Reg might |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4535 } else if (IsConstant || IsExternal) | 4708 } else if (IsConstant || IsExternal) |
| 4536 Str << "\t.zero\t" << Size << "\n"; | 4709 Str << "\t.zero\t" << Size << "\n"; |
| 4537 // Size is part of .comm. | 4710 // Size is part of .comm. |
| 4538 | 4711 |
| 4539 if (IsConstant || HasNonzeroInitializer || IsExternal) | 4712 if (IsConstant || HasNonzeroInitializer || IsExternal) |
| 4540 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4713 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 4541 // Size is part of .comm. | 4714 // Size is part of .comm. |
| 4542 } | 4715 } |
| 4543 | 4716 |
| 4544 } // end of namespace Ice | 4717 } // end of namespace Ice |
| OLD | NEW |