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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1527143003: Subzero. Introduces a new LoweringContext::insert() method. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: More changes Created 5 years 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/IceTargetLoweringMIPS32.cpp ('k') | src/IceTargetLoweringX8664.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 /// \file 10 /// \file
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 // pressure. On the other hand, lowering register arguments first (before 183 // pressure. On the other hand, lowering register arguments first (before
184 // stack arguments) may result in more compact code, as the memory operand 184 // stack arguments) may result in more compact code, as the memory operand
185 // displacements may end up being smaller before any stack adjustment is 185 // displacements may end up being smaller before any stack adjustment is
186 // done. 186 // done.
187 for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) { 187 for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) {
188 Variable *Reg = 188 Variable *Reg =
189 legalizeToReg(XmmArgs[i], Traits::RegisterSet::Reg_xmm0 + i); 189 legalizeToReg(XmmArgs[i], Traits::RegisterSet::Reg_xmm0 + i);
190 // Generate a FakeUse of register arguments so that they do not get dead 190 // Generate a FakeUse of register arguments so that they do not get dead
191 // code eliminated as a result of the FakeKill of scratch registers after 191 // code eliminated as a result of the FakeKill of scratch registers after
192 // the call. 192 // the call.
193 Context.insert(InstFakeUse::create(Func, Reg)); 193 Context.insert<InstFakeUse>(Reg);
194 } 194 }
195 // Generate the call instruction. Assign its result to a temporary with high 195 // Generate the call instruction. Assign its result to a temporary with high
196 // register allocation weight. 196 // register allocation weight.
197 // ReturnReg doubles as ReturnRegLo as necessary. 197 // ReturnReg doubles as ReturnRegLo as necessary.
198 Variable *ReturnReg = nullptr; 198 Variable *ReturnReg = nullptr;
199 Variable *ReturnRegHi = nullptr; 199 Variable *ReturnRegHi = nullptr;
200 if (Dest) { 200 if (Dest) {
201 switch (Dest->getType()) { 201 switch (Dest->getType()) {
202 case IceType_NUM: 202 case IceType_NUM:
203 case IceType_void: 203 case IceType_void:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 } else { 237 } else {
238 Variable *CallTargetVar = nullptr; 238 Variable *CallTargetVar = nullptr;
239 _mov(CallTargetVar, CallTarget); 239 _mov(CallTargetVar, CallTarget);
240 _bundle_lock(InstBundleLock::Opt_AlignToEnd); 240 _bundle_lock(InstBundleLock::Opt_AlignToEnd);
241 const SizeT BundleSize = 241 const SizeT BundleSize =
242 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); 242 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
243 _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1))); 243 _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1)));
244 CallTarget = CallTargetVar; 244 CallTarget = CallTargetVar;
245 } 245 }
246 } 246 }
247 Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget); 247 auto *NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget);
248 Context.insert(NewCall);
249 if (NeedSandboxing) 248 if (NeedSandboxing)
250 _bundle_unlock(); 249 _bundle_unlock();
251 if (ReturnRegHi) 250 if (ReturnRegHi)
252 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); 251 Context.insert<InstFakeDef>(ReturnRegHi);
253 252
254 // Insert a register-kill pseudo instruction. 253 // Insert a register-kill pseudo instruction.
255 Context.insert(InstFakeKill::create(Func, NewCall)); 254 Context.insert<InstFakeKill>(NewCall);
256 255
257 if (Dest != nullptr && isScalarFloatingType(Dest->getType())) { 256 if (Dest != nullptr && isScalarFloatingType(Dest->getType())) {
258 // Special treatment for an FP function which returns its result in st(0). 257 // Special treatment for an FP function which returns its result in st(0).
259 // If Dest ends up being a physical xmm register, the fstp emit code will 258 // If Dest ends up being a physical xmm register, the fstp emit code will
260 // route st(0) through the space reserved in the function argument area 259 // route st(0) through the space reserved in the function argument area
261 // we allocated. 260 // we allocated.
262 _fstp(Dest); 261 _fstp(Dest);
263 // Create a fake use of Dest in case it actually isn't used, because st(0) 262 // Create a fake use of Dest in case it actually isn't used, because st(0)
264 // still needs to be popped. 263 // still needs to be popped.
265 Context.insert(InstFakeUse::create(Func, Dest)); 264 Context.insert<InstFakeUse>(Dest);
266 } 265 }
267 266
268 // Generate a FakeUse to keep the call live if necessary. 267 // Generate a FakeUse to keep the call live if necessary.
269 if (Instr->hasSideEffects() && ReturnReg) { 268 if (Instr->hasSideEffects() && ReturnReg) {
270 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); 269 Context.insert<InstFakeUse>(ReturnReg);
271 Context.insert(FakeUse);
272 } 270 }
273 271
274 if (!Dest) 272 if (!Dest)
275 return; 273 return;
276 274
277 // Assign the result of the call to Dest. 275 // Assign the result of the call to Dest.
278 if (ReturnReg) { 276 if (ReturnReg) {
279 if (ReturnRegHi) { 277 if (ReturnRegHi) {
280 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); 278 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
281 Variable *DestLo = Dest64On32->getLo(); 279 Variable *DestLo = Dest64On32->getLo();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 int32_t RegNum = Traits::RegisterSet::Reg_xmm0 + NumXmmArgs; 315 int32_t RegNum = Traits::RegisterSet::Reg_xmm0 + NumXmmArgs;
318 ++NumXmmArgs; 316 ++NumXmmArgs;
319 Variable *RegisterArg = Func->makeVariable(Ty); 317 Variable *RegisterArg = Func->makeVariable(Ty);
320 if (BuildDefs::dump()) 318 if (BuildDefs::dump())
321 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); 319 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
322 RegisterArg->setRegNum(RegNum); 320 RegisterArg->setRegNum(RegNum);
323 RegisterArg->setIsArg(); 321 RegisterArg->setIsArg();
324 Arg->setIsArg(false); 322 Arg->setIsArg(false);
325 323
326 Args[I] = RegisterArg; 324 Args[I] = RegisterArg;
327 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); 325 Context.insert<InstAssign>(Arg, RegisterArg);
328 } 326 }
329 } 327 }
330 328
331 void TargetX8632::lowerRet(const InstRet *Inst) { 329 void TargetX8632::lowerRet(const InstRet *Inst) {
332 Variable *Reg = nullptr; 330 Variable *Reg = nullptr;
333 if (Inst->hasRetValue()) { 331 if (Inst->hasRetValue()) {
334 Operand *Src0 = legalize(Inst->getRetValue()); 332 Operand *Src0 = legalize(Inst->getRetValue());
335 // TODO(jpp): this is not needed. 333 // TODO(jpp): this is not needed.
336 if (Src0->getType() == IceType_i64) { 334 if (Src0->getType() == IceType_i64) {
337 Variable *eax = 335 Variable *eax =
338 legalizeToReg(loOperand(Src0), Traits::RegisterSet::Reg_eax); 336 legalizeToReg(loOperand(Src0), Traits::RegisterSet::Reg_eax);
339 Variable *edx = 337 Variable *edx =
340 legalizeToReg(hiOperand(Src0), Traits::RegisterSet::Reg_edx); 338 legalizeToReg(hiOperand(Src0), Traits::RegisterSet::Reg_edx);
341 Reg = eax; 339 Reg = eax;
342 Context.insert(InstFakeUse::create(Func, edx)); 340 Context.insert<InstFakeUse>(edx);
343 } else if (isScalarFloatingType(Src0->getType())) { 341 } else if (isScalarFloatingType(Src0->getType())) {
344 _fld(Src0); 342 _fld(Src0);
345 } else if (isVectorType(Src0->getType())) { 343 } else if (isVectorType(Src0->getType())) {
346 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0); 344 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0);
347 } else { 345 } else {
348 _mov(Reg, Src0, Traits::RegisterSet::Reg_eax); 346 _mov(Reg, Src0, Traits::RegisterSet::Reg_eax);
349 } 347 }
350 } 348 }
351 // Add a ret instruction even if sandboxing is enabled, because addEpilog 349 // Add a ret instruction even if sandboxing is enabled, because addEpilog
352 // explicitly looks for a ret instruction as a marker for where to insert the 350 // explicitly looks for a ret instruction as a marker for where to insert the
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 // Generate "push ebp; mov ebp, esp" 460 // Generate "push ebp; mov ebp, esp"
463 if (IsEbpBasedFrame) { 461 if (IsEbpBasedFrame) {
464 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None)) 462 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None))
465 .count() == 0); 463 .count() == 0);
466 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i32); 464 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i32);
467 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp); 465 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp);
468 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); 466 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp);
469 _push(ebp); 467 _push(ebp);
470 _mov(ebp, esp); 468 _mov(ebp, esp);
471 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode). 469 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
472 Context.insert(InstFakeUse::create(Func, ebp)); 470 Context.insert<InstFakeUse>(ebp);
473 } 471 }
474 472
475 // Align the variables area. SpillAreaPaddingBytes is the size of the region 473 // Align the variables area. SpillAreaPaddingBytes is the size of the region
476 // after the preserved registers and before the spill areas. 474 // after the preserved registers and before the spill areas.
477 // LocalsSlotsPaddingBytes is the amount of padding between the globals and 475 // LocalsSlotsPaddingBytes is the amount of padding between the globals and
478 // locals area if they are separate. 476 // locals area if they are separate.
479 assert(SpillAreaAlignmentBytes <= Traits::X86_STACK_ALIGNMENT_BYTES); 477 assert(SpillAreaAlignmentBytes <= Traits::X86_STACK_ALIGNMENT_BYTES);
480 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes); 478 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes);
481 uint32_t SpillAreaPaddingBytes = 0; 479 uint32_t SpillAreaPaddingBytes = 0;
482 uint32_t LocalsSlotsPaddingBytes = 0; 480 uint32_t LocalsSlotsPaddingBytes = 0;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 --InsertPoint; 624 --InsertPoint;
627 Context.init(Node); 625 Context.init(Node);
628 Context.setInsertPoint(InsertPoint); 626 Context.setInsertPoint(InsertPoint);
629 627
630 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); 628 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp);
631 if (IsEbpBasedFrame) { 629 if (IsEbpBasedFrame) {
632 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp); 630 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp);
633 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake 631 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
634 // use of esp before the assignment of esp=ebp keeps previous esp 632 // use of esp before the assignment of esp=ebp keeps previous esp
635 // adjustments from being dead-code eliminated. 633 // adjustments from being dead-code eliminated.
636 Context.insert(InstFakeUse::create(Func, esp)); 634 Context.insert<InstFakeUse>(esp);
637 _mov(esp, ebp); 635 _mov(esp, ebp);
638 _pop(ebp); 636 _pop(ebp);
639 } else { 637 } else {
640 // add esp, SpillAreaSizeBytes 638 // add esp, SpillAreaSizeBytes
641 if (SpillAreaSizeBytes) 639 if (SpillAreaSizeBytes)
642 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes)); 640 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes));
643 } 641 }
644 642
645 // Add pop instructions for preserved registers. 643 // Add pop instructions for preserved registers.
646 llvm::SmallBitVector CalleeSaves = 644 llvm::SmallBitVector CalleeSaves =
(...skipping 22 matching lines...) Expand all
669 // bundle_lock 667 // bundle_lock
670 // and t, ~31 668 // and t, ~31
671 // jmp *t 669 // jmp *t
672 // bundle_unlock 670 // bundle_unlock
673 // FakeUse <original_ret_operand> 671 // FakeUse <original_ret_operand>
674 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx); 672 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
675 _pop(T_ecx); 673 _pop(T_ecx);
676 lowerIndirectJump(T_ecx); 674 lowerIndirectJump(T_ecx);
677 if (RI->getSrcSize()) { 675 if (RI->getSrcSize()) {
678 auto *RetValue = llvm::cast<Variable>(RI->getSrc(0)); 676 auto *RetValue = llvm::cast<Variable>(RI->getSrc(0));
679 Context.insert(InstFakeUse::create(Func, RetValue)); 677 Context.insert<InstFakeUse>(RetValue);
680 } 678 }
681 RI->setDeleted(); 679 RI->setDeleted();
682 } 680 }
683 681
684 void TargetX8632::emitJumpTable(const Cfg *Func, 682 void TargetX8632::emitJumpTable(const Cfg *Func,
685 const InstJumpTable *JumpTable) const { 683 const InstJumpTable *JumpTable) const {
686 if (!BuildDefs::dump()) 684 if (!BuildDefs::dump())
687 return; 685 return;
688 Ostream &Str = Ctx->getStrEmit(); 686 Ostream &Str = Ctx->getStrEmit();
689 IceString MangledName = Ctx->mangleName(Func->getFunctionName()); 687 IceString MangledName = Ctx->mangleName(Func->getFunctionName());
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 // case the high-level table has extra entries. 994 // case the high-level table has extra entries.
997 #define X(tag, sizeLog2, align, elts, elty, str) \ 995 #define X(tag, sizeLog2, align, elts, elty, str) \
998 static_assert(_table1_##tag == _table2_##tag, \ 996 static_assert(_table1_##tag == _table2_##tag, \
999 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); 997 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE");
1000 ICETYPE_TABLE 998 ICETYPE_TABLE
1001 #undef X 999 #undef X
1002 } // end of namespace dummy3 1000 } // end of namespace dummy3
1003 } // end of anonymous namespace 1001 } // end of anonymous namespace
1004 1002
1005 } // end of namespace Ice 1003 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringMIPS32.cpp ('k') | src/IceTargetLoweringX8664.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698