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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1616483003: Merged addProlog and addEpilog on x86. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 11 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
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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 void TargetX8632::_mov_sp(Operand *NewValue) { 134 void TargetX8632::_mov_sp(Operand *NewValue) {
135 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); 135 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp);
136 _redefined(_mov(esp, NewValue)); 136 _redefined(_mov(esp, NewValue));
137 } 137 }
138 138
139 void TargetX8632::_sub_sp(Operand *Adjustment) { 139 void TargetX8632::_sub_sp(Operand *Adjustment) {
140 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); 140 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp);
141 _sub(esp, Adjustment); 141 _sub(esp, Adjustment);
142 } 142 }
143 143
144 void TargetX8632::_link_bp() {
145 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp);
146 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp);
147 _push(ebp);
148 _mov(ebp, esp);
149 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
150 Context.insert<InstFakeUse>(ebp);
151 }
152
153 void TargetX8632::_unlink_bp() {
154 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp);
155 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp);
156 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
157 // use of esp before the assignment of esp=ebp keeps previous esp
158 // adjustments from being dead-code eliminated.
159 Context.insert<InstFakeUse>(esp);
160 _mov(esp, ebp);
161 _pop(ebp);
162 }
163
164 void TargetX8632::_push_reg(Variable *Reg) { _push(Reg); }
165
166 void TargetX8632::emitGetIP(CfgNode *Node) {
167 // If there is a non-deleted InstX86GetIP instruction, we need to move it to
168 // the point after the stack frame has stabilized but before
169 // register-allocated in-args are copied into their home registers. It would
170 // be slightly faster to search for the GetIP instruction before other prolog
171 // instructions are inserted, but it's more clear to do the whole
172 // transformation in a single place.
173 Traits::Insts::GetIP *GetIPInst = nullptr;
174 if (Ctx->getFlags().getUseNonsfi()) {
175 for (Inst &Instr : Node->getInsts()) {
176 if (auto *GetIP = llvm::dyn_cast<Traits::Insts::GetIP>(&Instr)) {
177 if (!Instr.isDeleted())
178 GetIPInst = GetIP;
179 break;
180 }
181 }
182 }
183 // Delete any existing InstX86GetIP instruction and reinsert it here. Also,
184 // insert the call to the helper function and the spill to the stack, to
185 // simplify emission.
186 if (GetIPInst) {
187 GetIPInst->setDeleted();
188 Variable *Dest = GetIPInst->getDest();
189 Variable *CallDest =
190 Dest->hasReg() ? Dest
191 : getPhysicalRegister(Traits::RegisterSet::Reg_eax);
192 // Call the getIP_<reg> helper.
193 IceString RegName = Traits::getRegName(CallDest->getRegNum());
194 Constant *CallTarget = Ctx->getConstantExternSym(H_getIP_prefix + RegName);
195 Context.insert<Traits::Insts::Call>(CallDest, CallTarget);
196 // Insert a new version of InstX86GetIP.
197 Context.insert<Traits::Insts::GetIP>(CallDest);
198 // Spill the register to its home stack location if necessary.
199 if (!Dest->hasReg()) {
200 _mov(Dest, CallDest);
201 }
202 }
203 }
204
144 void TargetX8632::lowerIndirectJump(Variable *JumpTarget) { 205 void TargetX8632::lowerIndirectJump(Variable *JumpTarget) {
145 AutoBundle _(this); 206 AutoBundle _(this);
146 207
147 if (NeedSandboxing) { 208 if (NeedSandboxing) {
148 const SizeT BundleSize = 209 const SizeT BundleSize =
149 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); 210 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
150 _and(JumpTarget, Ctx->getConstantInt32(~(BundleSize - 1))); 211 _and(JumpTarget, Ctx->getConstantInt32(~(BundleSize - 1)));
151 } 212 }
152 213
153 _jmp(JumpTarget); 214 _jmp(JumpTarget);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 Context.insert<InstFakeUse>(edx); 249 Context.insert<InstFakeUse>(edx);
189 return eax; 250 return eax;
190 } else { 251 } else {
191 Variable *Reg = nullptr; 252 Variable *Reg = nullptr;
192 _mov(Reg, Value, Traits::RegisterSet::Reg_eax); 253 _mov(Reg, Value, Traits::RegisterSet::Reg_eax);
193 return Reg; 254 return Reg;
194 } 255 }
195 } 256 }
196 } 257 }
197 258
198 void TargetX8632::addProlog(CfgNode *Node) { 259 void TargetX8632::emitSandboxedReturn() {
199 // Stack frame layout:
200 //
201 // +------------------------+
202 // | 1. return address |
203 // +------------------------+
204 // | 2. preserved registers |
205 // +------------------------+
206 // | 3. padding |
207 // +------------------------+
208 // | 4. global spill area |
209 // +------------------------+
210 // | 5. padding |
211 // +------------------------+
212 // | 6. local spill area |
213 // +------------------------+
214 // | 7. padding |
215 // +------------------------+
216 // | 8. allocas |
217 // +------------------------+
218 // | 9. padding |
219 // +------------------------+
220 // | 10. out args |
221 // +------------------------+ <--- StackPointer
222 //
223 // The following variables record the size in bytes of the given areas:
224 // * X86_RET_IP_SIZE_BYTES: area 1
225 // * PreservedRegsSizeBytes: area 2
226 // * SpillAreaPaddingBytes: area 3
227 // * GlobalsSize: area 4
228 // * GlobalsAndSubsequentPaddingSize: areas 4 - 5
229 // * LocalsSpillAreaSize: area 6
230 // * SpillAreaSizeBytes: areas 3 - 10
231 // * maxOutArgsSizeBytes(): area 10
232
233 // Determine stack frame offsets for each Variable without a register
234 // assignment. This can be done as one variable per stack slot. Or, do
235 // coalescing by running the register allocator again with an infinite set of
236 // registers (as a side effect, this gives variables a second chance at
237 // physical register assignment).
238 //
239 // A middle ground approach is to leverage sparsity and allocate one block of
240 // space on the frame for globals (variables with multi-block lifetime), and
241 // one block to share for locals (single-block lifetime).
242
243 Context.init(Node);
244 Context.setInsertPoint(Context.getCur());
245
246 llvm::SmallBitVector CalleeSaves =
247 getRegisterSet(RegSet_CalleeSave, RegSet_None);
248 RegsUsed = llvm::SmallBitVector(CalleeSaves.size());
249 VarList SortedSpilledVariables, VariablesLinkedToSpillSlots;
250 size_t GlobalsSize = 0;
251 // If there is a separate locals area, this represents that area. Otherwise
252 // it counts any variable not counted by GlobalsSize.
253 SpillAreaSizeBytes = 0;
254 // If there is a separate locals area, this specifies the alignment for it.
255 uint32_t LocalsSlotsAlignmentBytes = 0;
256 // The entire spill locations area gets aligned to largest natural alignment
257 // of the variables that have a spill slot.
258 uint32_t SpillAreaAlignmentBytes = 0;
259 // A spill slot linked to a variable with a stack slot should reuse that
260 // stack slot.
261 std::function<bool(Variable *)> TargetVarHook =
262 [&VariablesLinkedToSpillSlots](Variable *Var) {
263 if (auto *SpillVar =
264 llvm::dyn_cast<typename Traits::SpillVariable>(Var)) {
265 assert(Var->mustNotHaveReg());
266 if (SpillVar->getLinkedTo() && !SpillVar->getLinkedTo()->hasReg()) {
267 VariablesLinkedToSpillSlots.push_back(Var);
268 return true;
269 }
270 }
271 return false;
272 };
273
274 // Compute the list of spilled variables and bounds for GlobalsSize, etc.
275 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize,
276 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes,
277 &LocalsSlotsAlignmentBytes, TargetVarHook);
278 uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes;
279 SpillAreaSizeBytes += GlobalsSize;
280
281 // Add push instructions for preserved registers.
282 uint32_t NumCallee = 0;
283 size_t PreservedRegsSizeBytes = 0;
284 llvm::SmallBitVector Pushed(CalleeSaves.size());
285 for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
286 SizeT Canonical = Traits::getBaseReg(i);
287 if (CalleeSaves[i] && RegsUsed[i]) {
288 Pushed[Canonical] = true;
289 }
290 }
291 for (SizeT i = 0; i < Pushed.size(); ++i) {
292 if (Pushed[i]) {
293 ++NumCallee;
294 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i32);
295 _push(getPhysicalRegister(i));
296 }
297 }
298 Ctx->statsUpdateRegistersSaved(NumCallee);
299
300 // Generate "push ebp; mov ebp, esp"
301 if (IsEbpBasedFrame) {
302 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None))
303 .count() == 0);
304 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i32);
305 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp);
306 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp);
307 _push(ebp);
308 _mov(ebp, esp);
309 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
310 Context.insert<InstFakeUse>(ebp);
311 }
312
313 // Align the variables area. SpillAreaPaddingBytes is the size of the region
314 // after the preserved registers and before the spill areas.
315 // LocalsSlotsPaddingBytes is the amount of padding between the globals and
316 // locals area if they are separate.
317 assert(SpillAreaAlignmentBytes <= Traits::X86_STACK_ALIGNMENT_BYTES);
318 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes);
319 uint32_t SpillAreaPaddingBytes = 0;
320 uint32_t LocalsSlotsPaddingBytes = 0;
321 alignStackSpillAreas(Traits::X86_RET_IP_SIZE_BYTES + PreservedRegsSizeBytes,
322 SpillAreaAlignmentBytes, GlobalsSize,
323 LocalsSlotsAlignmentBytes, &SpillAreaPaddingBytes,
324 &LocalsSlotsPaddingBytes);
325 SpillAreaSizeBytes += SpillAreaPaddingBytes + LocalsSlotsPaddingBytes;
326 uint32_t GlobalsAndSubsequentPaddingSize =
327 GlobalsSize + LocalsSlotsPaddingBytes;
328
329 // Functions returning scalar floating point types may need to convert values
330 // from an in-register xmm value to the top of the x87 floating point stack.
331 // This is done by a movp[sd] and an fld[sd]. Ensure there is enough scratch
332 // space on the stack for this.
333 const Type ReturnType = Func->getReturnType();
334 if (isScalarFloatingType(ReturnType)) {
335 // Avoid misaligned double-precicion load/store.
336 NeedsStackAlignment = true;
337 SpillAreaSizeBytes =
338 std::max(typeWidthInBytesOnStack(ReturnType), SpillAreaSizeBytes);
339 }
340
341 // Align esp if necessary.
342 if (NeedsStackAlignment) {
343 uint32_t StackOffset =
344 Traits::X86_RET_IP_SIZE_BYTES + PreservedRegsSizeBytes;
345 uint32_t StackSize =
346 Traits::applyStackAlignment(StackOffset + SpillAreaSizeBytes);
347 StackSize = Traits::applyStackAlignment(StackSize + maxOutArgsSizeBytes());
348 SpillAreaSizeBytes = StackSize - StackOffset;
349 } else {
350 SpillAreaSizeBytes += maxOutArgsSizeBytes();
351 }
352
353 // Combine fixed allocations into SpillAreaSizeBytes if we are emitting the
354 // fixed allocations in the prolog.
355 if (PrologEmitsFixedAllocas)
356 SpillAreaSizeBytes += FixedAllocaSizeBytes;
357 if (SpillAreaSizeBytes) {
358 // Generate "sub esp, SpillAreaSizeBytes"
359 _sub(getPhysicalRegister(Traits::RegisterSet::Reg_esp),
360 Ctx->getConstantInt32(SpillAreaSizeBytes));
361 // If the fixed allocas are aligned more than the stack frame, align the
362 // stack pointer accordingly.
363 if (PrologEmitsFixedAllocas &&
364 FixedAllocaAlignBytes > Traits::X86_STACK_ALIGNMENT_BYTES) {
365 assert(IsEbpBasedFrame);
366 _and(getPhysicalRegister(Traits::RegisterSet::Reg_esp),
367 Ctx->getConstantInt32(-FixedAllocaAlignBytes));
368 }
369 }
370
371 // Account for known-frame-offset alloca instructions that were not already
372 // combined into the prolog.
373 if (!PrologEmitsFixedAllocas)
374 SpillAreaSizeBytes += FixedAllocaSizeBytes;
375
376 Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes);
377
378 // Fill in stack offsets for stack args, and copy args into registers for
379 // those that were register-allocated. Args are pushed right to left, so
380 // Arg[0] is closest to the stack/frame pointer.
381 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg());
382 size_t BasicFrameOffset =
383 PreservedRegsSizeBytes + Traits::X86_RET_IP_SIZE_BYTES;
384 if (!IsEbpBasedFrame)
385 BasicFrameOffset += SpillAreaSizeBytes;
386
387 // If there is a non-deleted InstX86GetIP instruction, we need to move it to
388 // the point after the stack frame has stabilized but before
389 // register-allocated in-args are copied into their home registers. It would
390 // be slightly faster to search for the GetIP instruction before other prolog
391 // instructions are inserted, but it's more clear to do the whole
392 // transformation in a single place.
393 Traits::Insts::GetIP *GetIPInst = nullptr;
394 if (Ctx->getFlags().getUseNonsfi()) {
395 for (Inst &Instr : Node->getInsts()) {
396 if (auto *GetIP = llvm::dyn_cast<Traits::Insts::GetIP>(&Instr)) {
397 if (!Instr.isDeleted())
398 GetIPInst = GetIP;
399 break;
400 }
401 }
402 }
403 // Delete any existing InstX86GetIP instruction and reinsert it here. Also,
404 // insert the call to the helper function and the spill to the stack, to
405 // simplify emission.
406 if (GetIPInst) {
407 GetIPInst->setDeleted();
408 Variable *Dest = GetIPInst->getDest();
409 Variable *CallDest =
410 Dest->hasReg() ? Dest
411 : getPhysicalRegister(Traits::RegisterSet::Reg_eax);
412 // Call the getIP_<reg> helper.
413 IceString RegName = Traits::getRegName(CallDest->getRegNum());
414 Constant *CallTarget = Ctx->getConstantExternSym(H_getIP_prefix + RegName);
415 Context.insert<Traits::Insts::Call>(CallDest, CallTarget);
416 // Insert a new version of InstX86GetIP.
417 Context.insert<Traits::Insts::GetIP>(CallDest);
418 // Spill the register to its home stack location if necessary.
419 if (!Dest->hasReg()) {
420 _mov(Dest, CallDest);
421 }
422 }
423
424 const VarList &Args = Func->getArgs();
425 size_t InArgsSizeBytes = 0;
426 unsigned NumXmmArgs = 0;
427 for (Variable *Arg : Args) {
428 // Skip arguments passed in registers.
429 if (isVectorType(Arg->getType()) && NumXmmArgs < Traits::X86_MAX_XMM_ARGS) {
430 ++NumXmmArgs;
431 continue;
432 }
433 // For esp-based frames where the allocas are done outside the prolog, the
434 // esp value may not stabilize to its home value until after all the
435 // fixed-size alloca instructions have executed. In this case, a stack
436 // adjustment is needed when accessing in-args in order to copy them into
437 // registers.
438 size_t StackAdjBytes = 0;
439 if (!IsEbpBasedFrame && !PrologEmitsFixedAllocas)
440 StackAdjBytes -= FixedAllocaSizeBytes;
441 finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, StackAdjBytes,
442 InArgsSizeBytes);
443 }
444
445 // Fill in stack offsets for locals.
446 assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes,
447 SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize,
448 IsEbpBasedFrame);
449 // Assign stack offsets to variables that have been linked to spilled
450 // variables.
451 for (Variable *Var : VariablesLinkedToSpillSlots) {
452 Variable *Linked =
453 (llvm::cast<typename Traits::SpillVariable>(Var))->getLinkedTo();
454 Var->setStackOffset(Linked->getStackOffset());
455 }
456 this->HasComputedFrame = true;
457
458 if (BuildDefs::dump() && Func->isVerbose(IceV_Frame)) {
459 OstreamLocker L(Func->getContext());
460 Ostream &Str = Func->getContext()->getStrDump();
461
462 Str << "Stack layout:\n";
463 uint32_t EspAdjustmentPaddingSize =
464 SpillAreaSizeBytes - LocalsSpillAreaSize -
465 GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes -
466 maxOutArgsSizeBytes();
467 Str << " in-args = " << InArgsSizeBytes << " bytes\n"
468 << " return address = " << Traits::X86_RET_IP_SIZE_BYTES << " bytes\n"
469 << " preserved registers = " << PreservedRegsSizeBytes << " bytes\n"
470 << " spill area padding = " << SpillAreaPaddingBytes << " bytes\n"
471 << " globals spill area = " << GlobalsSize << " bytes\n"
472 << " globals-locals spill areas intermediate padding = "
473 << GlobalsAndSubsequentPaddingSize - GlobalsSize << " bytes\n"
474 << " locals spill area = " << LocalsSpillAreaSize << " bytes\n"
475 << " esp alignment padding = " << EspAdjustmentPaddingSize
476 << " bytes\n";
477
478 Str << "Stack details:\n"
479 << " esp adjustment = " << SpillAreaSizeBytes << " bytes\n"
480 << " spill area alignment = " << SpillAreaAlignmentBytes << " bytes\n"
481 << " outgoing args size = " << maxOutArgsSizeBytes() << " bytes\n"
482 << " locals spill area alignment = " << LocalsSlotsAlignmentBytes
483 << " bytes\n"
484 << " is ebp based = " << IsEbpBasedFrame << "\n";
485 }
486 }
487
488 void TargetX8632::addEpilog(CfgNode *Node) {
489 InstList &Insts = Node->getInsts();
490 InstList::reverse_iterator RI, E;
491 for (RI = Insts.rbegin(), E = Insts.rend(); RI != E; ++RI) {
492 if (llvm::isa<typename Traits::Insts::Ret>(*RI))
493 break;
494 }
495 if (RI == E)
496 return;
497
498 // Convert the reverse_iterator position into its corresponding (forward)
499 // iterator position.
500 InstList::iterator InsertPoint = RI.base();
501 --InsertPoint;
502 Context.init(Node);
503 Context.setInsertPoint(InsertPoint);
504
505 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp);
506 if (IsEbpBasedFrame) {
507 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp);
508 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
509 // use of esp before the assignment of esp=ebp keeps previous esp
510 // adjustments from being dead-code eliminated.
511 Context.insert<InstFakeUse>(esp);
512 _mov(esp, ebp);
513 _pop(ebp);
514 } else {
515 // add esp, SpillAreaSizeBytes
516 if (SpillAreaSizeBytes)
517 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes));
518 }
519
520 // Add pop instructions for preserved registers.
521 llvm::SmallBitVector CalleeSaves =
522 getRegisterSet(RegSet_CalleeSave, RegSet_None);
523 llvm::SmallBitVector Popped(CalleeSaves.size());
524 for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
525 SizeT Canonical = Traits::getBaseReg(i);
526 if (CalleeSaves[i] && RegsUsed[i]) {
527 Popped[Canonical] = true;
528 }
529 }
530 for (SizeT i = 0; i < Popped.size(); ++i) {
531 SizeT j = Popped.size() - i - 1;
532 SizeT Canonical = Traits::getBaseReg(j);
533 if (j == Traits::RegisterSet::Reg_ebp && IsEbpBasedFrame)
534 continue;
535 if (Popped[j]) {
536 _pop(getPhysicalRegister(Canonical));
537 }
538 }
539
540 if (!NeedSandboxing) {
541 return;
542 }
543
544 // Change the original ret instruction into a sandboxed return sequence. 260 // Change the original ret instruction into a sandboxed return sequence.
545 // t:ecx = pop 261 // t:ecx = pop
546 // bundle_lock 262 // bundle_lock
547 // and t, ~31 263 // and t, ~31
548 // jmp *t 264 // jmp *t
549 // bundle_unlock 265 // bundle_unlock
550 // FakeUse <original_ret_operand> 266 // FakeUse <original_ret_operand>
551 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx); 267 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
552 _pop(T_ecx); 268 _pop(T_ecx);
553 lowerIndirectJump(T_ecx); 269 lowerIndirectJump(T_ecx);
554 if (RI->getSrcSize()) {
555 auto *RetValue = llvm::cast<Variable>(RI->getSrc(0));
556 Context.insert<InstFakeUse>(RetValue);
557 }
558 RI->setDeleted();
559 } 270 }
560 271
561 void TargetX8632::emitJumpTable(const Cfg *Func, 272 void TargetX8632::emitJumpTable(const Cfg *Func,
562 const InstJumpTable *JumpTable) const { 273 const InstJumpTable *JumpTable) const {
563 if (!BuildDefs::dump()) 274 if (!BuildDefs::dump())
564 return; 275 return;
565 Ostream &Str = Ctx->getStrEmit(); 276 Ostream &Str = Ctx->getStrEmit();
566 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); 277 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi();
567 const IceString MangledName = Ctx->mangleName(Func->getFunctionName()); 278 const IceString MangledName = Ctx->mangleName(Func->getFunctionName());
568 const IceString Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata."; 279 const IceString Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata.";
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 #define X(tag, sizeLog2, align, elts, elty, str) \ 590 #define X(tag, sizeLog2, align, elts, elty, str) \
880 static_assert(_table1_##tag == _table2_##tag, \ 591 static_assert(_table1_##tag == _table2_##tag, \
881 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); 592 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE");
882 ICETYPE_TABLE 593 ICETYPE_TABLE
883 #undef X 594 #undef X
884 } // end of namespace dummy3 595 } // end of namespace dummy3
885 } // end of anonymous namespace 596 } // end of anonymous namespace
886 597
887 } // end of namespace X8632 598 } // end of namespace X8632
888 } // end of namespace Ice 599 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698