| Index: src/IceCfg.cpp
|
| diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
|
| index 7e915081700eec8a629c7d3f2fdbc61aba98a43c..89ca5054646d2a86a4fe3042fdc5b39ab03ee445 100644
|
| --- a/src/IceCfg.cpp
|
| +++ b/src/IceCfg.cpp
|
| @@ -554,6 +554,39 @@ void Cfg::emitTextHeader(const IceString &MangledName, GlobalContext *Ctx,
|
| Str << MangledName << ":\n";
|
| }
|
|
|
| +void Cfg::deleteJumpTableInsts() {
|
| + for (InstJumpTable *JumpTable : JumpTables)
|
| + JumpTable->setDeleted();
|
| +}
|
| +
|
| +void Cfg::emitJumpTables() {
|
| + switch (Ctx->getFlags().getOutFileType()) {
|
| + case FT_Elf:
|
| + case FT_Iasm: {
|
| + // The emission needs to be delayed until the after the text section so save
|
| + // the offsets in the global context.
|
| + for (const InstJumpTable *JumpTable : JumpTables) {
|
| + SizeT NumTargets = JumpTable->getNumTargets();
|
| + JumpTableData &JT =
|
| + Ctx->addJumpTable(getFunctionName(), JumpTable->getId(), NumTargets);
|
| + for (SizeT I = 0; I < NumTargets; ++I) {
|
| + SizeT Index = JumpTable->getTarget(I)->getIndex();
|
| + JT.pushTarget(
|
| + getAssembler()->getOrCreateCfgNodeLabel(Index)->getPosition());
|
| + }
|
| + }
|
| + } break;
|
| + case FT_Asm: {
|
| + // Emit the assembly directly so we don't need to hang on to all the names
|
| + for (const InstJumpTable *JumpTable : JumpTables)
|
| + getTarget()->emitJumpTable(this, JumpTable);
|
| + } break;
|
| + default:
|
| + llvm::report_fatal_error("Invalid out file type.");
|
| + break;
|
| + }
|
| +}
|
| +
|
| void Cfg::emit() {
|
| if (!BuildDefs::dump())
|
| return;
|
| @@ -568,8 +601,14 @@ void Cfg::emit() {
|
| Ostream &Str = Ctx->getStrEmit();
|
| IceString MangledName = getContext()->mangleName(getFunctionName());
|
| emitTextHeader(MangledName, Ctx, getAssembler<>());
|
| - for (CfgNode *Node : Nodes)
|
| + deleteJumpTableInsts();
|
| + const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
|
| + for (CfgNode *Node : Nodes) {
|
| + if (NeedSandboxing && Node->needsAlignment())
|
| + getAssembler()->alignCfgNode();
|
| Node->emit(this);
|
| + }
|
| + emitJumpTables();
|
| Str << "\n";
|
| }
|
|
|
| @@ -577,8 +616,13 @@ void Cfg::emitIAS() {
|
| TimerMarker T(TimerStack::TT_emit, this);
|
| // The emitIAS() routines emit into the internal assembler buffer,
|
| // so there's no need to lock the streams.
|
| - for (CfgNode *Node : Nodes)
|
| + deleteJumpTableInsts();
|
| + for (CfgNode *Node : Nodes) {
|
| + if (Node->needsAlignment())
|
| + getAssembler()->alignCfgNode();
|
| Node->emitIAS(this);
|
| + }
|
| + emitJumpTables();
|
| }
|
|
|
| // Dumps the IR with an optional introductory message.
|
|
|