bool IRTranslator::translateCall(const CallInst &CI) { auto TII = MIRBuilder.getMF().getTarget().getIntrinsicInfo(); const Function &F = *CI.getCalledFunction(); Intrinsic::ID ID = F.getIntrinsicID(); if (TII && ID == Intrinsic::not_intrinsic) ID = static_cast<Intrinsic::ID>(TII->getIntrinsicID(&F)); assert(ID != Intrinsic::not_intrinsic && "FIXME: support real calls"); // Need types (starting with return) & args. SmallVector<LLT, 4> Tys; Tys.emplace_back(*CI.getType()); for (auto &Arg : CI.arg_operands()) Tys.emplace_back(*Arg->getType()); unsigned Res = CI.getType()->isVoidTy() ? 0 : getOrCreateVReg(CI); MachineInstrBuilder MIB = MIRBuilder.buildIntrinsic(Tys, ID, Res, !CI.doesNotAccessMemory()); for (auto &Arg : CI.arg_operands()) { if (ConstantInt *CI = dyn_cast<ConstantInt>(Arg)) MIB.addImm(CI->getSExtValue()); else MIB.addUse(getOrCreateVReg(*Arg)); } return true; }
MachineInstrBuilder MachineIRBuilder::buildSequence(unsigned Res, ArrayRef<unsigned> Ops, ArrayRef<uint64_t> Indices) { #ifndef NDEBUG assert(Ops.size() == Indices.size() && "incompatible args"); assert(!Ops.empty() && "invalid trivial sequence"); assert(std::is_sorted(Indices.begin(), Indices.end()) && "sequence offsets must be in ascending order"); assert(MRI->getType(Res).isValid() && "invalid operand type"); for (auto Op : Ops) assert(MRI->getType(Op).isValid() && "invalid operand type"); #endif MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_SEQUENCE); MIB.addDef(Res); for (unsigned i = 0; i < Ops.size(); ++i) { MIB.addUse(Ops[i]); MIB.addImm(Indices[i]); } return MIB; }
bool IRTranslator::translateCall(const User &U) { const CallInst &CI = cast<CallInst>(U); auto TII = MIRBuilder.getMF().getTarget().getIntrinsicInfo(); const Function *F = CI.getCalledFunction(); if (!F || !F->isIntrinsic()) { unsigned Res = CI.getType()->isVoidTy() ? 0 : getOrCreateVReg(CI); SmallVector<unsigned, 8> Args; for (auto &Arg: CI.arg_operands()) Args.push_back(getOrCreateVReg(*Arg)); return CLI->lowerCall(MIRBuilder, CI, Res, Args, [&]() { return getOrCreateVReg(*CI.getCalledValue()); }); } Intrinsic::ID ID = F->getIntrinsicID(); if (TII && ID == Intrinsic::not_intrinsic) ID = static_cast<Intrinsic::ID>(TII->getIntrinsicID(F)); assert(ID != Intrinsic::not_intrinsic && "unknown intrinsic"); if (translateKnownIntrinsic(CI, ID)) return true; unsigned Res = CI.getType()->isVoidTy() ? 0 : getOrCreateVReg(CI); MachineInstrBuilder MIB = MIRBuilder.buildIntrinsic(ID, Res, !CI.doesNotAccessMemory()); for (auto &Arg : CI.arg_operands()) { if (ConstantInt *CI = dyn_cast<ConstantInt>(Arg)) MIB.addImm(CI->getSExtValue()); else MIB.addUse(getOrCreateVReg(*Arg)); } return true; }