SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); SDValue Chain = Op.getOperand(0); const auto *JT = cast<JumpTableSDNode>(Op.getOperand(1)); SDValue Index = Op.getOperand(2); assert(JT->getTargetFlags() == 0 && "WebAssembly doesn't set target flags"); SmallVector<SDValue, 8> Ops; Ops.push_back(Chain); Ops.push_back(Index); MachineJumpTableInfo *MJTI = DAG.getMachineFunction().getJumpTableInfo(); const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs; // TODO: For now, we just pick something arbitrary for a default case for now. // We really want to sniff out the guard and put in the real default case (and // delete the guard). Ops.push_back(DAG.getBasicBlock(MBBs[0])); // Add an operand for each case. for (auto MBB : MBBs) Ops.push_back(DAG.getBasicBlock(MBB)); return DAG.getNode(WebAssemblyISD::SWITCH, DL, MVT::Other, Ops); }
void JITEmitter::startFunction(MachineFunction &F) { uintptr_t ActualSize = 0; if (MemMgr->NeedsExactSize()) { const TargetInstrInfo* TII = F.getTarget().getInstrInfo(); MachineJumpTableInfo *MJTI = F.getJumpTableInfo(); MachineConstantPool *MCP = F.getConstantPool(); // Ensure the constant pool/jump table info is at least 4-byte aligned. ActualSize = RoundUpToAlign(ActualSize, 16); // Add the alignment of the constant pool ActualSize = RoundUpToAlign(ActualSize, 1 << MCP->getConstantPoolAlignment()); // Add the constant pool size ActualSize += GetConstantPoolSizeInBytes(MCP); // Add the aligment of the jump table info ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment()); // Add the jump table size ActualSize += GetJumpTableSizeInBytes(MJTI); // Add the alignment for the function ActualSize = RoundUpToAlign(ActualSize, std::max(F.getFunction()->getAlignment(), 8U)); // Add the function size ActualSize += TII->GetFunctionSizeInBytes(F); } BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), ActualSize); BufferEnd = BufferBegin+ActualSize; // Ensure the constant pool/jump table info is at least 4-byte aligned. emitAlignment(16); emitConstantPool(F.getConstantPool()); initJumpTableInfo(F.getJumpTableInfo()); // About to start emitting the machine code for the function. emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); MBBLocations.clear(); }
void MIRPrinter::convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI, const MachineJumpTableInfo &JTI) { YamlJTI.Kind = JTI.getEntryKind(); unsigned ID = 0; for (const auto &Table : JTI.getJumpTables()) { std::string Str; yaml::MachineJumpTable::Entry Entry; Entry.ID = ID++; for (const auto *MBB : Table.MBBs) { raw_string_ostream StrOS(Str); StrOS << printMBBReference(*MBB); Entry.Blocks.push_back(StrOS.str()); Str.clear(); } YamlJTI.Entries.push_back(Entry); } }
bool MIRParserImpl::initializeJumpTableInfo( MachineFunction &MF, const yaml::MachineJumpTable &YamlJTI, PerFunctionMIParsingState &PFS) { MachineJumpTableInfo *JTI = MF.getOrCreateJumpTableInfo(YamlJTI.Kind); SMDiagnostic Error; for (const auto &Entry : YamlJTI.Entries) { std::vector<MachineBasicBlock *> Blocks; for (const auto &MBBSource : Entry.Blocks) { MachineBasicBlock *MBB = nullptr; if (parseMBBReference(MBB, MBBSource.Value, MF, PFS)) return true; Blocks.push_back(MBB); } unsigned Index = JTI->createJumpTableIndex(Blocks); // TODO: Report an error when the same jump table slot ID is redefined. PFS.JumpTableSlots.insert(std::make_pair(Entry.ID, Index)); } return false; }
bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS, const yaml::MachineJumpTable &YamlJTI) { MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(YamlJTI.Kind); for (const auto &Entry : YamlJTI.Entries) { std::vector<MachineBasicBlock *> Blocks; for (const auto &MBBSource : Entry.Blocks) { MachineBasicBlock *MBB = nullptr; if (parseMBBReference(PFS, MBB, MBBSource.Value)) return true; Blocks.push_back(MBB); } unsigned Index = JTI->createJumpTableIndex(Blocks); if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index)) .second) return error(Entry.ID.SourceRange.Start, Twine("redefinition of jump table entry '%jump-table.") + Twine(Entry.ID.Value) + "'"); } return false; }