blob: 65d02611d5703d002c121fffd454927fb2681f8c [file] [log] [blame]
Karl Schimpfe1e013c2014-06-27 09:15:29 -07001//===- subzero/src/IceConverter.cpp - Converts LLVM to Ice ---------------===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Implements the LLVM to ICE converter.
Andrew Scull9612d322015-07-06 14:53:25 -070012///
Karl Schimpfe1e013c2014-06-27 09:15:29 -070013//===----------------------------------------------------------------------===//
14
John Porto67f8de92015-06-25 10:14:17 -070015#include "IceConverter.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070016
Karl Schimpfe1e013c2014-06-27 09:15:29 -070017#include "IceCfg.h"
18#include "IceCfgNode.h"
Karl Schimpf8d7abae2014-07-07 14:50:30 -070019#include "IceClFlags.h"
Karl Schimpfe1e013c2014-06-27 09:15:29 -070020#include "IceDefs.h"
21#include "IceGlobalContext.h"
Karl Schimpfe3f64d02014-10-07 10:38:22 -070022#include "IceGlobalInits.h"
Karl Schimpfe1e013c2014-06-27 09:15:29 -070023#include "IceInst.h"
Jim Stichnoth98ba0062016-03-07 09:26:22 -080024#include "IceMangling.h"
Karl Schimpfe1e013c2014-06-27 09:15:29 -070025#include "IceOperand.h"
Karl Schimpfb164d202014-07-11 10:26:34 -070026#include "IceTargetLowering.h"
Karl Schimpfd6064a12014-08-27 15:34:58 -070027#include "IceTypeConverter.h"
Antonio Maioranodebdfa22020-11-10 16:28:34 -050028#include "IceTypes.h"
Jim Stichnoth98da9662015-06-27 06:38:08 -070029
Jim Stichnothb0051df2016-01-13 11:39:15 -080030#ifdef __clang__
Jim Stichnoth98da9662015-06-27 06:38:08 -070031#pragma clang diagnostic push
32#pragma clang diagnostic ignored "-Wunused-parameter"
Jim Stichnothb0051df2016-01-13 11:39:15 -080033#endif // __clang__
34
John Porto67f8de92015-06-25 10:14:17 -070035#include "llvm/IR/Constant.h"
36#include "llvm/IR/Constants.h"
37#include "llvm/IR/DataLayout.h"
38#include "llvm/IR/Instruction.h"
39#include "llvm/IR/Instructions.h"
40#include "llvm/IR/LLVMContext.h"
41#include "llvm/IR/Module.h"
Jim Stichnothb0051df2016-01-13 11:39:15 -080042
43#ifdef __clang__
Jim Stichnoth98da9662015-06-27 06:38:08 -070044#pragma clang diagnostic pop
Jim Stichnothb0051df2016-01-13 11:39:15 -080045#endif // __clang__
John Porto67f8de92015-06-25 10:14:17 -070046
Karl Schimpf9d98d792014-10-13 15:01:08 -070047// TODO(kschimpf): Remove two namespaces being visible at once.
Karl Schimpfe1e013c2014-06-27 09:15:29 -070048using namespace llvm;
49
50namespace {
51
52// Debugging helper
53template <typename T> static std::string LLVMObjectAsString(const T *O) {
54 std::string Dump;
55 raw_string_ostream Stream(Dump);
56 O->print(Stream);
57 return Stream.str();
58}
59
Karl Schimpfe3f64d02014-10-07 10:38:22 -070060// Base class for converting LLVM to ICE.
Jim Stichnoth8e928382015-02-02 17:03:08 -080061// TODO(stichnot): Redesign Converter, LLVM2ICEConverter,
Andrew Scull57e12682015-09-16 11:30:19 -070062// LLVM2ICEFunctionConverter, and LLVM2ICEGlobalsConverter with respect to
63// Translator. In particular, the unique_ptr ownership rules in
64// LLVM2ICEFunctionConverter.
Karl Schimpfe1e013c2014-06-27 09:15:29 -070065class LLVM2ICEConverter {
Jim Stichnothc6ead202015-02-24 09:30:30 -080066 LLVM2ICEConverter() = delete;
Karl Schimpfe3f64d02014-10-07 10:38:22 -070067 LLVM2ICEConverter(const LLVM2ICEConverter &) = delete;
68 LLVM2ICEConverter &operator=(const LLVM2ICEConverter &) = delete;
69
Karl Schimpfe1e013c2014-06-27 09:15:29 -070070public:
Jim Stichnothc6ead202015-02-24 09:30:30 -080071 explicit LLVM2ICEConverter(Ice::Converter &Converter)
Karl Schimpf9d98d792014-10-13 15:01:08 -070072 : Converter(Converter), Ctx(Converter.getContext()),
73 TypeConverter(Converter.getModule()->getContext()) {}
74
75 Ice::Converter &getConverter() const { return Converter; }
Karl Schimpfe3f64d02014-10-07 10:38:22 -070076
77protected:
Karl Schimpf9d98d792014-10-13 15:01:08 -070078 Ice::Converter &Converter;
Karl Schimpfe3f64d02014-10-07 10:38:22 -070079 Ice::GlobalContext *Ctx;
80 const Ice::TypeConverter TypeConverter;
81};
82
Andrew Scull57e12682015-09-16 11:30:19 -070083// Converter from LLVM functions to ICE. The entry point is the convertFunction
84// method.
Karl Schimpfe3f64d02014-10-07 10:38:22 -070085//
Andrew Scull57e12682015-09-16 11:30:19 -070086// Note: this currently assumes that the given IR was verified to be valid
87// PNaCl bitcode. Otherwise, the behavior is undefined.
Karl Schimpfe3f64d02014-10-07 10:38:22 -070088class LLVM2ICEFunctionConverter : LLVM2ICEConverter {
Jim Stichnothc6ead202015-02-24 09:30:30 -080089 LLVM2ICEFunctionConverter() = delete;
Karl Schimpfe3f64d02014-10-07 10:38:22 -070090 LLVM2ICEFunctionConverter(const LLVM2ICEFunctionConverter &) = delete;
91 LLVM2ICEFunctionConverter &
92 operator=(const LLVM2ICEFunctionConverter &) = delete;
93
94public:
Jim Stichnothc6ead202015-02-24 09:30:30 -080095 explicit LLVM2ICEFunctionConverter(Ice::Converter &Converter)
Karl Schimpf9d98d792014-10-13 15:01:08 -070096 : LLVM2ICEConverter(Converter), Func(nullptr) {}
Karl Schimpfe1e013c2014-06-27 09:15:29 -070097
Jim Stichnoth8e928382015-02-02 17:03:08 -080098 void convertFunction(const Function *F) {
Jim Stichnothbbca7542015-02-11 16:08:31 -080099 Func = Ice::Cfg::create(Ctx, Converter.getNextSequenceNumber());
John Portoe82b5602016-02-24 15:58:55 -0800100 {
101 Ice::CfgLocalAllocatorScope _(Func.get());
Jim Stichnoth8e928382015-02-02 17:03:08 -0800102
John Portoe82b5602016-02-24 15:58:55 -0800103 VarMap.clear();
104 NodeMap.clear();
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700105 Func->setFunctionName(
106 Ctx->getGlobalString(Ice::mangleName(F->getName())));
John Portoe82b5602016-02-24 15:58:55 -0800107 Func->setReturnType(convertToIceType(F->getReturnType()));
108 Func->setInternal(F->hasInternalLinkage());
109 Ice::TimerMarker T(Ice::TimerStack::TT_llvmConvert, Func.get());
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700110
John Portoe82b5602016-02-24 15:58:55 -0800111 // The initial definition/use of each arg is the entry node.
112 for (auto ArgI = F->arg_begin(), ArgE = F->arg_end(); ArgI != ArgE;
113 ++ArgI) {
Jim Stichnothf5fdd232016-05-09 12:24:36 -0700114 Func->addArg(mapValueToIceVar(&*ArgI));
John Portoe82b5602016-02-24 15:58:55 -0800115 }
116
117 // Make an initial pass through the block list just to resolve the blocks
118 // in the original linearized order. Otherwise the ICE linearized order
119 // will be affected by branch targets in terminator instructions.
120 for (const BasicBlock &BBI : *F)
121 mapBasicBlockToNode(&BBI);
122 for (const BasicBlock &BBI : *F)
123 convertBasicBlock(&BBI);
124 Func->setEntryNode(mapBasicBlockToNode(&F->getEntryBlock()));
125 Func->computeInOutEdges();
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700126 }
Jim Stichnoth8e928382015-02-02 17:03:08 -0800127 Converter.translateFcn(std::move(Func));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700128 }
129
Andrew Scull57e12682015-09-16 11:30:19 -0700130 // convertConstant() does not use Func or require it to be a valid Ice::Cfg
131 // pointer. As such, it's suitable for e.g. constructing global initializers.
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700132 Ice::Constant *convertConstant(const Constant *Const) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700133 if (const auto GV = dyn_cast<GlobalValue>(Const)) {
Karl Schimpfdf6f9d12014-10-20 14:09:00 -0700134 Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV);
Jan Voung77973cc2015-02-03 12:48:38 -0800135 bool IsUndefined = false;
136 if (const auto *Func = llvm::dyn_cast<Ice::FunctionDeclaration>(Decl))
137 IsUndefined = Func->isProto();
138 else if (const auto *Var = llvm::dyn_cast<Ice::VariableDeclaration>(Decl))
139 IsUndefined = !Var->hasInitializer();
140 else
141 report_fatal_error("Unhandled GlobalDeclaration type");
142 if (IsUndefined)
143 return Ctx->getConstantExternSym(Decl->getName());
144 else {
145 const Ice::RelocOffsetT Offset = 0;
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700146 return Ctx->getConstantSym(
147 Offset, Ctx->getGlobalString(Decl->getName().toString()));
Jan Voung77973cc2015-02-03 12:48:38 -0800148 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700149 } else if (const auto CI = dyn_cast<ConstantInt>(Const)) {
Jan Voungbc004632014-09-16 15:09:10 -0700150 Ice::Type Ty = convertToIceType(CI->getType());
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800151 return Ctx->getConstantInt(Ty, CI->getSExtValue());
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700152 } else if (const auto CFP = dyn_cast<ConstantFP>(Const)) {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700153 Ice::Type Type = convertToIceType(CFP->getType());
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700154 if (Type == Ice::IceType_f32)
155 return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat());
156 else if (Type == Ice::IceType_f64)
157 return Ctx->getConstantDouble(CFP->getValueAPF().convertToDouble());
158 llvm_unreachable("Unexpected floating point type");
Karl Schimpf9d98d792014-10-13 15:01:08 -0700159 return nullptr;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700160 } else if (const auto CU = dyn_cast<UndefValue>(Const)) {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700161 return Ctx->getConstantUndef(convertToIceType(CU->getType()));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700162 } else {
163 llvm_unreachable("Unhandled constant type");
Karl Schimpf9d98d792014-10-13 15:01:08 -0700164 return nullptr;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700165 }
166 }
167
168private:
169 // LLVM values (instructions, etc.) are mapped directly to ICE variables.
170 // mapValueToIceVar has a version that forces an ICE type on the variable,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700171 // and a version that just uses convertToIceType on V.
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700172 Ice::Variable *mapValueToIceVar(const Value *V, Ice::Type IceTy) {
173 if (IceTy == Ice::IceType_void)
Karl Schimpf9d98d792014-10-13 15:01:08 -0700174 return nullptr;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700175 if (VarMap.find(V) == VarMap.end()) {
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800176 VarMap[V] = Func->makeVariable(IceTy);
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700177 if (Ice::BuildDefs::dump())
Jim Stichnoth8e928382015-02-02 17:03:08 -0800178 VarMap[V]->setName(Func.get(), V->getName());
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700179 }
180 return VarMap[V];
181 }
182
183 Ice::Variable *mapValueToIceVar(const Value *V) {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700184 return mapValueToIceVar(V, convertToIceType(V->getType()));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700185 }
186
187 Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) {
188 if (NodeMap.find(BB) == NodeMap.end()) {
Jim Stichnoth668a7a32014-12-10 15:32:25 -0800189 NodeMap[BB] = Func->makeNode();
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700190 if (Ice::BuildDefs::dump())
Jim Stichnoth668a7a32014-12-10 15:32:25 -0800191 NodeMap[BB]->setName(BB->getName());
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700192 }
193 return NodeMap[BB];
194 }
195
Karl Schimpfd6064a12014-08-27 15:34:58 -0700196 Ice::Type convertToIceType(Type *LLVMTy) const {
197 Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy);
198 if (IceTy == Ice::IceType_NUM)
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700199 report_fatal_error(std::string("Invalid PNaCl type ") +
200 LLVMObjectAsString(LLVMTy));
Karl Schimpfd6064a12014-08-27 15:34:58 -0700201 return IceTy;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700202 }
203
Andrew Scull57e12682015-09-16 11:30:19 -0700204 // Given an LLVM instruction and an operand number, produce the Ice::Operand
205 // this refers to. If there's no such operand, return nullptr.
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800206 Ice::Operand *convertOperand(const Instruction *Instr, unsigned OpNum) {
207 if (OpNum >= Instr->getNumOperands()) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700208 return nullptr;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700209 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800210 const Value *Op = Instr->getOperand(OpNum);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700211 return convertValue(Op);
212 }
213
214 Ice::Operand *convertValue(const Value *Op) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700215 if (const auto Const = dyn_cast<Constant>(Op)) {
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700216 return convertConstant(Const);
217 } else {
218 return mapValueToIceVar(Op);
219 }
220 }
221
222 // Note: this currently assumes a 1x1 mapping between LLVM IR and Ice
223 // instructions.
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800224 Ice::Inst *convertInstruction(const Instruction *Instr) {
225 switch (Instr->getOpcode()) {
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700226 case Instruction::PHI:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800227 return convertPHINodeInstruction(cast<PHINode>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700228 case Instruction::Br:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800229 return convertBrInstruction(cast<BranchInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700230 case Instruction::Ret:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800231 return convertRetInstruction(cast<ReturnInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700232 case Instruction::IntToPtr:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800233 return convertIntToPtrInstruction(cast<IntToPtrInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700234 case Instruction::PtrToInt:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800235 return convertPtrToIntInstruction(cast<PtrToIntInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700236 case Instruction::ICmp:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800237 return convertICmpInstruction(cast<ICmpInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700238 case Instruction::FCmp:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800239 return convertFCmpInstruction(cast<FCmpInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700240 case Instruction::Select:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800241 return convertSelectInstruction(cast<SelectInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700242 case Instruction::Switch:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800243 return convertSwitchInstruction(cast<SwitchInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700244 case Instruction::Load:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800245 return convertLoadInstruction(cast<LoadInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700246 case Instruction::Store:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800247 return convertStoreInstruction(cast<StoreInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700248 case Instruction::ZExt:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800249 return convertCastInstruction(cast<ZExtInst>(Instr), Ice::InstCast::Zext);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700250 case Instruction::SExt:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800251 return convertCastInstruction(cast<SExtInst>(Instr), Ice::InstCast::Sext);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700252 case Instruction::Trunc:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800253 return convertCastInstruction(cast<TruncInst>(Instr),
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700254 Ice::InstCast::Trunc);
255 case Instruction::FPTrunc:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800256 return convertCastInstruction(cast<FPTruncInst>(Instr),
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700257 Ice::InstCast::Fptrunc);
258 case Instruction::FPExt:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800259 return convertCastInstruction(cast<FPExtInst>(Instr),
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700260 Ice::InstCast::Fpext);
261 case Instruction::FPToSI:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800262 return convertCastInstruction(cast<FPToSIInst>(Instr),
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700263 Ice::InstCast::Fptosi);
264 case Instruction::FPToUI:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800265 return convertCastInstruction(cast<FPToUIInst>(Instr),
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700266 Ice::InstCast::Fptoui);
267 case Instruction::SIToFP:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800268 return convertCastInstruction(cast<SIToFPInst>(Instr),
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700269 Ice::InstCast::Sitofp);
270 case Instruction::UIToFP:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800271 return convertCastInstruction(cast<UIToFPInst>(Instr),
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700272 Ice::InstCast::Uitofp);
273 case Instruction::BitCast:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800274 return convertCastInstruction(cast<BitCastInst>(Instr),
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700275 Ice::InstCast::Bitcast);
276 case Instruction::Add:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800277 return convertArithInstruction(Instr, Ice::InstArithmetic::Add);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700278 case Instruction::Sub:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800279 return convertArithInstruction(Instr, Ice::InstArithmetic::Sub);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700280 case Instruction::Mul:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800281 return convertArithInstruction(Instr, Ice::InstArithmetic::Mul);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700282 case Instruction::UDiv:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800283 return convertArithInstruction(Instr, Ice::InstArithmetic::Udiv);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700284 case Instruction::SDiv:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800285 return convertArithInstruction(Instr, Ice::InstArithmetic::Sdiv);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700286 case Instruction::URem:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800287 return convertArithInstruction(Instr, Ice::InstArithmetic::Urem);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700288 case Instruction::SRem:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800289 return convertArithInstruction(Instr, Ice::InstArithmetic::Srem);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700290 case Instruction::Shl:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800291 return convertArithInstruction(Instr, Ice::InstArithmetic::Shl);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700292 case Instruction::LShr:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800293 return convertArithInstruction(Instr, Ice::InstArithmetic::Lshr);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700294 case Instruction::AShr:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800295 return convertArithInstruction(Instr, Ice::InstArithmetic::Ashr);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700296 case Instruction::FAdd:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800297 return convertArithInstruction(Instr, Ice::InstArithmetic::Fadd);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700298 case Instruction::FSub:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800299 return convertArithInstruction(Instr, Ice::InstArithmetic::Fsub);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700300 case Instruction::FMul:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800301 return convertArithInstruction(Instr, Ice::InstArithmetic::Fmul);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700302 case Instruction::FDiv:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800303 return convertArithInstruction(Instr, Ice::InstArithmetic::Fdiv);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700304 case Instruction::FRem:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800305 return convertArithInstruction(Instr, Ice::InstArithmetic::Frem);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700306 case Instruction::And:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800307 return convertArithInstruction(Instr, Ice::InstArithmetic::And);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700308 case Instruction::Or:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800309 return convertArithInstruction(Instr, Ice::InstArithmetic::Or);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700310 case Instruction::Xor:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800311 return convertArithInstruction(Instr, Ice::InstArithmetic::Xor);
Matt Wala49889232014-07-18 12:45:09 -0700312 case Instruction::ExtractElement:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800313 return convertExtractElementInstruction(cast<ExtractElementInst>(Instr));
Matt Wala49889232014-07-18 12:45:09 -0700314 case Instruction::InsertElement:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800315 return convertInsertElementInstruction(cast<InsertElementInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700316 case Instruction::Call:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800317 return convertCallInstruction(cast<CallInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700318 case Instruction::Alloca:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800319 return convertAllocaInstruction(cast<AllocaInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700320 case Instruction::Unreachable:
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800321 return convertUnreachableInstruction(cast<UnreachableInst>(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700322 default:
323 report_fatal_error(std::string("Invalid PNaCl instruction: ") +
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800324 LLVMObjectAsString(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700325 }
326
327 llvm_unreachable("convertInstruction");
Karl Schimpf9d98d792014-10-13 15:01:08 -0700328 return nullptr;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700329 }
330
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800331 Ice::Inst *convertLoadInstruction(const LoadInst *Instr) {
332 Ice::Operand *Src = convertOperand(Instr, 0);
333 Ice::Variable *Dest = mapValueToIceVar(Instr);
Jim Stichnoth8e928382015-02-02 17:03:08 -0800334 return Ice::InstLoad::create(Func.get(), Dest, Src);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700335 }
336
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800337 Ice::Inst *convertStoreInstruction(const StoreInst *Instr) {
338 Ice::Operand *Addr = convertOperand(Instr, 1);
339 Ice::Operand *Val = convertOperand(Instr, 0);
Jim Stichnoth8e928382015-02-02 17:03:08 -0800340 return Ice::InstStore::create(Func.get(), Val, Addr);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700341 }
342
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800343 Ice::Inst *convertArithInstruction(const Instruction *Instr,
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700344 Ice::InstArithmetic::OpKind Opcode) {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800345 const auto BinOp = cast<BinaryOperator>(Instr);
346 Ice::Operand *Src0 = convertOperand(Instr, 0);
347 Ice::Operand *Src1 = convertOperand(Instr, 1);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700348 Ice::Variable *Dest = mapValueToIceVar(BinOp);
Jim Stichnoth8e928382015-02-02 17:03:08 -0800349 return Ice::InstArithmetic::create(Func.get(), Opcode, Dest, Src0, Src1);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700350 }
351
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800352 Ice::Inst *convertPHINodeInstruction(const PHINode *Instr) {
353 unsigned NumValues = Instr->getNumIncomingValues();
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700354 Ice::InstPhi *IcePhi =
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800355 Ice::InstPhi::create(Func.get(), NumValues, mapValueToIceVar(Instr));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700356 for (unsigned N = 0, E = NumValues; N != E; ++N) {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800357 IcePhi->addArgument(convertOperand(Instr, N),
358 mapBasicBlockToNode(Instr->getIncomingBlock(N)));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700359 }
360 return IcePhi;
361 }
362
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800363 Ice::Inst *convertBrInstruction(const BranchInst *Instr) {
364 if (Instr->isConditional()) {
365 Ice::Operand *Src = convertOperand(Instr, 0);
366 BasicBlock *BBThen = Instr->getSuccessor(0);
367 BasicBlock *BBElse = Instr->getSuccessor(1);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700368 Ice::CfgNode *NodeThen = mapBasicBlockToNode(BBThen);
369 Ice::CfgNode *NodeElse = mapBasicBlockToNode(BBElse);
Jim Stichnoth8e928382015-02-02 17:03:08 -0800370 return Ice::InstBr::create(Func.get(), Src, NodeThen, NodeElse);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700371 } else {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800372 BasicBlock *BBSucc = Instr->getSuccessor(0);
Jim Stichnoth8e928382015-02-02 17:03:08 -0800373 return Ice::InstBr::create(Func.get(), mapBasicBlockToNode(BBSucc));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700374 }
375 }
376
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800377 Ice::Inst *convertIntToPtrInstruction(const IntToPtrInst *Instr) {
378 Ice::Operand *Src = convertOperand(Instr, 0);
379 Ice::Variable *Dest = mapValueToIceVar(Instr, Ice::getPointerType());
Jim Stichnoth8e928382015-02-02 17:03:08 -0800380 return Ice::InstAssign::create(Func.get(), Dest, Src);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700381 }
382
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800383 Ice::Inst *convertPtrToIntInstruction(const PtrToIntInst *Instr) {
384 Ice::Operand *Src = convertOperand(Instr, 0);
385 Ice::Variable *Dest = mapValueToIceVar(Instr);
Jim Stichnoth8e928382015-02-02 17:03:08 -0800386 return Ice::InstAssign::create(Func.get(), Dest, Src);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700387 }
388
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800389 Ice::Inst *convertRetInstruction(const ReturnInst *Instr) {
390 Ice::Operand *RetOperand = convertOperand(Instr, 0);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700391 if (RetOperand) {
Jim Stichnoth8e928382015-02-02 17:03:08 -0800392 return Ice::InstRet::create(Func.get(), RetOperand);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700393 } else {
Jim Stichnoth8e928382015-02-02 17:03:08 -0800394 return Ice::InstRet::create(Func.get());
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700395 }
396 }
397
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800398 Ice::Inst *convertCastInstruction(const Instruction *Instr,
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700399 Ice::InstCast::OpKind CastKind) {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800400 Ice::Operand *Src = convertOperand(Instr, 0);
401 Ice::Variable *Dest = mapValueToIceVar(Instr);
Jim Stichnoth8e928382015-02-02 17:03:08 -0800402 return Ice::InstCast::create(Func.get(), CastKind, Dest, Src);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700403 }
404
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800405 Ice::Inst *convertICmpInstruction(const ICmpInst *Instr) {
406 Ice::Operand *Src0 = convertOperand(Instr, 0);
407 Ice::Operand *Src1 = convertOperand(Instr, 1);
408 Ice::Variable *Dest = mapValueToIceVar(Instr);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700409
410 Ice::InstIcmp::ICond Cond;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800411 switch (Instr->getPredicate()) {
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700412 default:
413 llvm_unreachable("ICmpInst predicate");
414 case CmpInst::ICMP_EQ:
415 Cond = Ice::InstIcmp::Eq;
416 break;
417 case CmpInst::ICMP_NE:
418 Cond = Ice::InstIcmp::Ne;
419 break;
420 case CmpInst::ICMP_UGT:
421 Cond = Ice::InstIcmp::Ugt;
422 break;
423 case CmpInst::ICMP_UGE:
424 Cond = Ice::InstIcmp::Uge;
425 break;
426 case CmpInst::ICMP_ULT:
427 Cond = Ice::InstIcmp::Ult;
428 break;
429 case CmpInst::ICMP_ULE:
430 Cond = Ice::InstIcmp::Ule;
431 break;
432 case CmpInst::ICMP_SGT:
433 Cond = Ice::InstIcmp::Sgt;
434 break;
435 case CmpInst::ICMP_SGE:
436 Cond = Ice::InstIcmp::Sge;
437 break;
438 case CmpInst::ICMP_SLT:
439 Cond = Ice::InstIcmp::Slt;
440 break;
441 case CmpInst::ICMP_SLE:
442 Cond = Ice::InstIcmp::Sle;
443 break;
444 }
445
Jim Stichnoth8e928382015-02-02 17:03:08 -0800446 return Ice::InstIcmp::create(Func.get(), Cond, Dest, Src0, Src1);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700447 }
448
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800449 Ice::Inst *convertFCmpInstruction(const FCmpInst *Instr) {
450 Ice::Operand *Src0 = convertOperand(Instr, 0);
451 Ice::Operand *Src1 = convertOperand(Instr, 1);
452 Ice::Variable *Dest = mapValueToIceVar(Instr);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700453
454 Ice::InstFcmp::FCond Cond;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800455 switch (Instr->getPredicate()) {
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700456
457 default:
458 llvm_unreachable("FCmpInst predicate");
459
460 case CmpInst::FCMP_FALSE:
461 Cond = Ice::InstFcmp::False;
462 break;
463 case CmpInst::FCMP_OEQ:
464 Cond = Ice::InstFcmp::Oeq;
465 break;
466 case CmpInst::FCMP_OGT:
467 Cond = Ice::InstFcmp::Ogt;
468 break;
469 case CmpInst::FCMP_OGE:
470 Cond = Ice::InstFcmp::Oge;
471 break;
472 case CmpInst::FCMP_OLT:
473 Cond = Ice::InstFcmp::Olt;
474 break;
475 case CmpInst::FCMP_OLE:
476 Cond = Ice::InstFcmp::Ole;
477 break;
478 case CmpInst::FCMP_ONE:
479 Cond = Ice::InstFcmp::One;
480 break;
481 case CmpInst::FCMP_ORD:
482 Cond = Ice::InstFcmp::Ord;
483 break;
484 case CmpInst::FCMP_UEQ:
485 Cond = Ice::InstFcmp::Ueq;
486 break;
487 case CmpInst::FCMP_UGT:
488 Cond = Ice::InstFcmp::Ugt;
489 break;
490 case CmpInst::FCMP_UGE:
491 Cond = Ice::InstFcmp::Uge;
492 break;
493 case CmpInst::FCMP_ULT:
494 Cond = Ice::InstFcmp::Ult;
495 break;
496 case CmpInst::FCMP_ULE:
497 Cond = Ice::InstFcmp::Ule;
498 break;
499 case CmpInst::FCMP_UNE:
500 Cond = Ice::InstFcmp::Une;
501 break;
502 case CmpInst::FCMP_UNO:
503 Cond = Ice::InstFcmp::Uno;
504 break;
505 case CmpInst::FCMP_TRUE:
506 Cond = Ice::InstFcmp::True;
507 break;
508 }
509
Jim Stichnoth8e928382015-02-02 17:03:08 -0800510 return Ice::InstFcmp::create(Func.get(), Cond, Dest, Src0, Src1);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700511 }
512
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800513 Ice::Inst *convertExtractElementInstruction(const ExtractElementInst *Instr) {
514 Ice::Variable *Dest = mapValueToIceVar(Instr);
515 Ice::Operand *Source1 = convertValue(Instr->getOperand(0));
516 Ice::Operand *Source2 = convertValue(Instr->getOperand(1));
Jim Stichnoth8e928382015-02-02 17:03:08 -0800517 return Ice::InstExtractElement::create(Func.get(), Dest, Source1, Source2);
Matt Wala49889232014-07-18 12:45:09 -0700518 }
519
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800520 Ice::Inst *convertInsertElementInstruction(const InsertElementInst *Instr) {
521 Ice::Variable *Dest = mapValueToIceVar(Instr);
522 Ice::Operand *Source1 = convertValue(Instr->getOperand(0));
523 Ice::Operand *Source2 = convertValue(Instr->getOperand(1));
524 Ice::Operand *Source3 = convertValue(Instr->getOperand(2));
Jim Stichnoth8e928382015-02-02 17:03:08 -0800525 return Ice::InstInsertElement::create(Func.get(), Dest, Source1, Source2,
Matt Wala49889232014-07-18 12:45:09 -0700526 Source3);
527 }
528
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800529 Ice::Inst *convertSelectInstruction(const SelectInst *Instr) {
530 Ice::Variable *Dest = mapValueToIceVar(Instr);
531 Ice::Operand *Cond = convertValue(Instr->getCondition());
532 Ice::Operand *Source1 = convertValue(Instr->getTrueValue());
533 Ice::Operand *Source2 = convertValue(Instr->getFalseValue());
Jim Stichnoth8e928382015-02-02 17:03:08 -0800534 return Ice::InstSelect::create(Func.get(), Dest, Cond, Source1, Source2);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700535 }
536
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800537 Ice::Inst *convertSwitchInstruction(const SwitchInst *Instr) {
538 Ice::Operand *Source = convertValue(Instr->getCondition());
539 Ice::CfgNode *LabelDefault = mapBasicBlockToNode(Instr->getDefaultDest());
540 unsigned NumCases = Instr->getNumCases();
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700541 Ice::InstSwitch *Switch =
Jim Stichnoth8e928382015-02-02 17:03:08 -0800542 Ice::InstSwitch::create(Func.get(), NumCases, Source, LabelDefault);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700543 unsigned CurrentCase = 0;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800544 for (SwitchInst::ConstCaseIt I = Instr->case_begin(), E = Instr->case_end();
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700545 I != E; ++I, ++CurrentCase) {
Jim Stichnothcabfa302014-09-03 15:19:12 -0700546 uint64_t CaseValue = I.getCaseValue()->getSExtValue();
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700547 Ice::CfgNode *CaseSuccessor = mapBasicBlockToNode(I.getCaseSuccessor());
548 Switch->addBranch(CurrentCase, CaseValue, CaseSuccessor);
549 }
550 return Switch;
551 }
552
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800553 Ice::Inst *convertCallInstruction(const CallInst *Instr) {
554 Ice::Variable *Dest = mapValueToIceVar(Instr);
555 Ice::Operand *CallTarget = convertValue(Instr->getCalledValue());
556 unsigned NumArgs = Instr->getNumArgOperands();
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700557
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700558 if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) {
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700559 // Check if this direct call is to an Intrinsic (starts with "llvm.")
Jim Stichnotha67fc442015-03-03 16:13:11 -0800560 bool BadIntrinsic;
Nicolas Capens33a77f72021-02-08 15:04:38 -0500561 const Ice::Intrinsics::FullIntrinsicInfo *Info =
562 Ctx->getIntrinsicsInfo().find(Target->getName(), BadIntrinsic);
Jim Stichnotha67fc442015-03-03 16:13:11 -0800563 if (BadIntrinsic) {
564 report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") +
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800565 LLVMObjectAsString(Instr));
Jim Stichnotha67fc442015-03-03 16:13:11 -0800566 }
Nicolas Capens33a77f72021-02-08 15:04:38 -0500567 if (Info) {
568 Ice::InstIntrinsic *Intrinsic = Ice::InstIntrinsic::create(
569 Func.get(), NumArgs, Dest, CallTarget, Info->Info);
570 for (unsigned i = 0; i < NumArgs; ++i) {
571 Intrinsic->addArg(convertOperand(Instr, i));
572 }
573 validateIntrinsic(Intrinsic, Info);
574
575 return Intrinsic;
576 }
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700577 }
578
Nicolas Capens33a77f72021-02-08 15:04:38 -0500579 // Not an intrinsic.
580 // Note: Subzero doesn't (yet) do anything special with the Tail flag in
581 // the bitcode, i.e. CallInst::isTailCall().
582 Ice::InstCall *Call = Ice::InstCall::create(
583 Func.get(), NumArgs, Dest, CallTarget, Instr->isTailCall());
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700584 for (unsigned i = 0; i < NumArgs; ++i) {
Nicolas Capens33a77f72021-02-08 15:04:38 -0500585 Intrinsic->addArg(convertOperand(Instr, i));
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700586 }
Nicolas Capens33a77f72021-02-08 15:04:38 -0500587
588 return Call;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700589 }
590
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800591 Ice::Inst *convertAllocaInstruction(const AllocaInst *Instr) {
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700592 // PNaCl bitcode only contains allocas of byte-granular objects.
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800593 Ice::Operand *ByteCount = convertValue(Instr->getArraySize());
594 uint32_t Align = Instr->getAlignment();
595 Ice::Variable *Dest = mapValueToIceVar(Instr, Ice::getPointerType());
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700596
David Sehr2f3b8ec2015-11-16 16:51:39 -0800597 return Ice::InstAlloca::create(Func.get(), Dest, ByteCount, Align);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700598 }
599
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800600 Ice::Inst *convertUnreachableInstruction(const UnreachableInst * /*Instr*/) {
Jim Stichnoth8e928382015-02-02 17:03:08 -0800601 return Ice::InstUnreachable::create(Func.get());
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700602 }
603
604 Ice::CfgNode *convertBasicBlock(const BasicBlock *BB) {
605 Ice::CfgNode *Node = mapBasicBlockToNode(BB);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700606 for (const Instruction &II : *BB) {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800607 Ice::Inst *Instr = convertInstruction(&II);
608 Node->appendInst(Instr);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700609 }
610 return Node;
611 }
612
Nicolas Capens33a77f72021-02-08 15:04:38 -0500613 void validateIntrinsic(const Ice::InstIntrinsic *Intrinsic,
614 const Ice::Intrinsics::FullIntrinsicInfo *I) {
Karl Schimpf8df26f32014-09-19 09:33:26 -0700615 Ice::SizeT ArgIndex = 0;
Nicolas Capens33a77f72021-02-08 15:04:38 -0500616 switch (I->validateCall(Intrinsic, ArgIndex)) {
Karl Schimpf8df26f32014-09-19 09:33:26 -0700617 case Ice::Intrinsics::IsValidCall:
618 break;
619 case Ice::Intrinsics::BadReturnType: {
620 std::string Buffer;
621 raw_string_ostream StrBuf(Buffer);
622 StrBuf << "Intrinsic call expects return type " << I->getReturnType()
Nicolas Capens33a77f72021-02-08 15:04:38 -0500623 << ". Found: " << Intrinsic->getReturnType();
Karl Schimpf8df26f32014-09-19 09:33:26 -0700624 report_fatal_error(StrBuf.str());
625 break;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700626 }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700627 case Ice::Intrinsics::WrongNumOfArgs: {
628 std::string Buffer;
629 raw_string_ostream StrBuf(Buffer);
630 StrBuf << "Intrinsic call expects " << I->getNumArgs()
Nicolas Capens33a77f72021-02-08 15:04:38 -0500631 << ". Found: " << Intrinsic->getNumArgs();
Karl Schimpf8df26f32014-09-19 09:33:26 -0700632 report_fatal_error(StrBuf.str());
633 break;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700634 }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700635 case Ice::Intrinsics::WrongCallArgType: {
636 std::string Buffer;
637 raw_string_ostream StrBuf(Buffer);
638 StrBuf << "Intrinsic call argument " << ArgIndex << " expects type "
639 << I->getArgType(ArgIndex)
Nicolas Capens33a77f72021-02-08 15:04:38 -0500640 << ". Found: " << Intrinsic->getArg(ArgIndex)->getType();
Karl Schimpf8df26f32014-09-19 09:33:26 -0700641 report_fatal_error(StrBuf.str());
642 break;
643 }
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700644 }
645 }
646
647private:
648 // Data
Jim Stichnoth8e928382015-02-02 17:03:08 -0800649 std::unique_ptr<Ice::Cfg> Func;
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700650 std::map<const Value *, Ice::Variable *> VarMap;
651 std::map<const BasicBlock *, Ice::CfgNode *> NodeMap;
652};
653
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700654// Converter from LLVM global variables to ICE. The entry point is the
655// convertGlobalsToIce method.
656//
Andrew Scull57e12682015-09-16 11:30:19 -0700657// Note: this currently assumes that the given IR was verified to be valid
658// PNaCl bitcode. Otherwise, the behavior is undefined.
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700659class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800660 LLVM2ICEGlobalsConverter() = delete;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700661 LLVM2ICEGlobalsConverter(const LLVM2ICEGlobalsConverter &) = delete;
662 LLVM2ICEGlobalsConverter &
Jim Stichnothf4fbf7f2015-08-08 08:37:02 -0700663 operator=(const LLVM2ICEGlobalsConverter &) = delete;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700664
665public:
John Portoa78e4ba2016-03-15 09:28:04 -0700666 explicit LLVM2ICEGlobalsConverter(Ice::Converter &Converter,
667 Ice::VariableDeclarationList *G)
668 : LLVM2ICEConverter(Converter), GlobalPool(G) {}
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700669
Andrew Scull57e12682015-09-16 11:30:19 -0700670 /// Converts global variables, and their initializers into ICE global variable
671 /// declarations, for module Mod. Returns the set of converted declarations.
John Portoa78e4ba2016-03-15 09:28:04 -0700672 void convertGlobalsToIce(Module *Mod);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700673
674private:
Andrew Scull57e12682015-09-16 11:30:19 -0700675 // Adds the Initializer to the list of initializers for the Global variable
676 // declaration.
Karl Schimpf9d98d792014-10-13 15:01:08 -0700677 void addGlobalInitializer(Ice::VariableDeclaration &Global,
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700678 const Constant *Initializer) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700679 constexpr bool HasOffset = false;
680 constexpr Ice::RelocOffsetT Offset = 0;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700681 addGlobalInitializer(Global, Initializer, HasOffset, Offset);
682 }
683
Karl Schimpf9d98d792014-10-13 15:01:08 -0700684 // Adds Initializer to the list of initializers for Global variable
Andrew Scull57e12682015-09-16 11:30:19 -0700685 // declaration. HasOffset is true only if Initializer is a relocation
686 // initializer and Offset should be added to the relocation.
Karl Schimpf9d98d792014-10-13 15:01:08 -0700687 void addGlobalInitializer(Ice::VariableDeclaration &Global,
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700688 const Constant *Initializer, bool HasOffset,
Jan Voungc0d965f2014-11-04 16:55:01 -0800689 Ice::RelocOffsetT Offset);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700690
Andrew Scull57e12682015-09-16 11:30:19 -0700691 // Converts the given constant C to the corresponding integer literal it
692 // contains.
Jan Voungc0d965f2014-11-04 16:55:01 -0800693 Ice::RelocOffsetT getIntegerLiteralConstant(const Value *C) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700694 const auto CI = dyn_cast<ConstantInt>(C);
695 if (CI && CI->getType()->isIntegerTy(32))
696 return CI->getSExtValue();
697
698 std::string Buffer;
699 raw_string_ostream StrBuf(Buffer);
700 StrBuf << "Constant not i32 literal: " << *C;
701 report_fatal_error(StrBuf.str());
702 return 0;
703 }
John Portoa78e4ba2016-03-15 09:28:04 -0700704
705 Ice::VariableDeclarationList *GlobalPool;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700706};
707
John Portoa78e4ba2016-03-15 09:28:04 -0700708void LLVM2ICEGlobalsConverter::convertGlobalsToIce(Module *Mod) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700709 for (Module::const_global_iterator I = Mod->global_begin(),
710 E = Mod->global_end();
711 I != E; ++I) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700712
Jim Stichnothf5fdd232016-05-09 12:24:36 -0700713 const GlobalVariable *GV = &*I;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700714
Karl Schimpf9d98d792014-10-13 15:01:08 -0700715 Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV);
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800716 auto *VarDecl = cast<Ice::VariableDeclaration>(Var);
John Portoa78e4ba2016-03-15 09:28:04 -0700717 GlobalPool->push_back(VarDecl);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700718
Karl Schimpfdf6f9d12014-10-20 14:09:00 -0700719 if (!GV->hasInternalLinkage() && GV->hasInitializer()) {
720 std::string Buffer;
721 raw_string_ostream StrBuf(Buffer);
722 StrBuf << "Can't define external global declaration: " << GV->getName();
723 report_fatal_error(StrBuf.str());
724 }
725
726 if (!GV->hasInitializer()) {
Karl Schimpfd4699942016-04-02 09:55:31 -0700727 if (Ice::getFlags().getAllowUninitializedGlobals())
Karl Schimpfdf6f9d12014-10-20 14:09:00 -0700728 continue;
729 else {
730 std::string Buffer;
731 raw_string_ostream StrBuf(Buffer);
732 StrBuf << "Global declaration missing initializer: " << GV->getName();
733 report_fatal_error(StrBuf.str());
734 }
735 }
736
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700737 const Constant *Initializer = GV->getInitializer();
738 if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) {
739 for (ConstantStruct::const_op_iterator I = CompoundInit->op_begin(),
740 E = CompoundInit->op_end();
741 I != E; ++I) {
742 if (const auto Init = dyn_cast<Constant>(I)) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700743 addGlobalInitializer(*VarDecl, Init);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700744 }
745 }
746 } else {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700747 addGlobalInitializer(*VarDecl, Initializer);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700748 }
749 }
750}
751
752void LLVM2ICEGlobalsConverter::addGlobalInitializer(
Karl Schimpf9d98d792014-10-13 15:01:08 -0700753 Ice::VariableDeclaration &Global, const Constant *Initializer,
Jan Voungc0d965f2014-11-04 16:55:01 -0800754 bool HasOffset, Ice::RelocOffsetT Offset) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700755 (void)HasOffset;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700756 assert(HasOffset || Offset == 0);
757
758 if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) {
759 assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) &&
760 (cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8));
John Porto1bec8bc2015-06-22 10:51:13 -0700761 Global.addInitializer(Ice::VariableDeclaration::DataInitializer::create(
John Portoa78e4ba2016-03-15 09:28:04 -0700762 GlobalPool, CDA->getRawDataValues().data(), CDA->getNumElements()));
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700763 return;
764 }
765
766 if (isa<ConstantAggregateZero>(Initializer)) {
767 if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) {
768 assert(!HasOffset && isa<IntegerType>(AT->getElementType()) &&
769 (cast<IntegerType>(AT->getElementType())->getBitWidth() == 8));
John Porto1bec8bc2015-06-22 10:51:13 -0700770 Global.addInitializer(Ice::VariableDeclaration::ZeroInitializer::create(
John Portoa78e4ba2016-03-15 09:28:04 -0700771 GlobalPool, AT->getNumElements()));
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700772 } else {
773 llvm_unreachable("Unhandled constant aggregate zero type");
774 }
775 return;
776 }
777
778 if (const auto Exp = dyn_cast<ConstantExpr>(Initializer)) {
779 switch (Exp->getOpcode()) {
780 case Instruction::Add:
781 assert(!HasOffset);
782 addGlobalInitializer(Global, Exp->getOperand(0), true,
783 getIntegerLiteralConstant(Exp->getOperand(1)));
784 return;
785 case Instruction::PtrToInt: {
786 assert(TypeConverter.convertToIceType(Exp->getType()) ==
Karl Schimpf4019f082014-12-15 13:45:00 -0800787 Ice::getPointerType());
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700788 const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0));
789 assert(GV);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700790 const Ice::GlobalDeclaration *Addr =
791 getConverter().getGlobalDeclaration(GV);
John Porto844211e2016-02-04 08:42:48 -0800792 Global.addInitializer(Ice::VariableDeclaration::RelocInitializer::create(
John Portoa78e4ba2016-03-15 09:28:04 -0700793 GlobalPool, Addr, {Ice::RelocOffset::create(Ctx, Offset)}));
Karl Schimpf9d98d792014-10-13 15:01:08 -0700794 return;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700795 }
796 default:
797 break;
798 }
799 }
800
801 std::string Buffer;
802 raw_string_ostream StrBuf(Buffer);
803 StrBuf << "Unhandled global initializer: " << Initializer;
804 report_fatal_error(StrBuf.str());
805}
806
Jim Stichnoth989a7032014-08-08 10:13:44 -0700807} // end of anonymous namespace
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700808
Karl Schimpfb164d202014-07-11 10:26:34 -0700809namespace Ice {
810
Karl Schimpf9d98d792014-10-13 15:01:08 -0700811void Converter::nameUnnamedGlobalVariables(Module *Mod) {
Karl Schimpfd4699942016-04-02 09:55:31 -0700812 const std::string GlobalPrefix = getFlags().getDefaultGlobalPrefix();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700813 if (GlobalPrefix.empty())
814 return;
815 uint32_t NameIndex = 0;
Karl Schimpf9d98d792014-10-13 15:01:08 -0700816 for (auto V = Mod->global_begin(), E = Mod->global_end(); V != E; ++V) {
817 if (!V->hasName()) {
818 V->setName(createUnnamedName(GlobalPrefix, NameIndex));
819 ++NameIndex;
820 } else {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800821 checkIfUnnamedNameSafe(V->getName(), "global", GlobalPrefix);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700822 }
823 }
824}
825
826void Converter::nameUnnamedFunctions(Module *Mod) {
Karl Schimpfd4699942016-04-02 09:55:31 -0700827 const std::string FunctionPrefix = getFlags().getDefaultFunctionPrefix();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700828 if (FunctionPrefix.empty())
829 return;
830 uint32_t NameIndex = 0;
Karl Schimpf9d98d792014-10-13 15:01:08 -0700831 for (Function &F : *Mod) {
832 if (!F.hasName()) {
833 F.setName(createUnnamedName(FunctionPrefix, NameIndex));
834 ++NameIndex;
835 } else {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800836 checkIfUnnamedNameSafe(F.getName(), "function", FunctionPrefix);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700837 }
838 }
839}
840
Karl Schimpfd6064a12014-08-27 15:34:58 -0700841void Converter::convertToIce() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700842 TimerMarker T(TimerStack::TT_convertToIce, Ctx);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700843 nameUnnamedGlobalVariables(Mod);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700844 nameUnnamedFunctions(Mod);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700845 installGlobalDeclarations(Mod);
Jim Stichnoth2a063e22014-10-08 11:24:51 -0700846 convertGlobals(Mod);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700847 convertFunctions();
Karl Schimpfb164d202014-07-11 10:26:34 -0700848}
849
Karl Schimpf9d98d792014-10-13 15:01:08 -0700850GlobalDeclaration *Converter::getGlobalDeclaration(const GlobalValue *V) {
851 GlobalDeclarationMapType::const_iterator Pos = GlobalDeclarationMap.find(V);
852 if (Pos == GlobalDeclarationMap.end()) {
853 std::string Buffer;
854 raw_string_ostream StrBuf(Buffer);
855 StrBuf << "Can't find global declaration for: " << V->getName();
856 report_fatal_error(StrBuf.str());
857 }
858 return Pos->second;
859}
860
861void Converter::installGlobalDeclarations(Module *Mod) {
862 const TypeConverter Converter(Mod->getContext());
863 // Install function declarations.
864 for (const Function &Func : *Mod) {
865 FuncSigType Signature;
866 FunctionType *FuncType = Func.getFunctionType();
867 Signature.setReturnType(
868 Converter.convertToIceType(FuncType->getReturnType()));
869 for (size_t I = 0; I < FuncType->getNumParams(); ++I) {
870 Signature.appendArgType(
871 Converter.convertToIceType(FuncType->getParamType(I)));
872 }
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800873 auto *IceFunc = FunctionDeclaration::create(
John Porto1bec8bc2015-06-22 10:51:13 -0700874 Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty());
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700875 IceFunc->setName(Ctx, Func.getName());
Karl Schimpf57d31ac2015-10-07 09:53:12 -0700876 if (!IceFunc->verifyLinkageCorrect(Ctx)) {
877 std::string Buffer;
878 raw_string_ostream StrBuf(Buffer);
879 StrBuf << "Function " << IceFunc->getName()
880 << " has incorrect linkage: " << IceFunc->getLinkageName();
Jim Stichnoth4e10aa22015-10-16 13:13:11 -0700881 if (IceFunc->isExternal())
882 StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
Karl Schimpf57d31ac2015-10-07 09:53:12 -0700883 report_fatal_error(StrBuf.str());
884 }
Karl Schimpfbba77682016-01-15 07:33:15 -0800885 if (!IceFunc->validateTypeSignature(Ctx))
886 report_fatal_error(IceFunc->getTypeSignatureError(Ctx));
Karl Schimpf9d98d792014-10-13 15:01:08 -0700887 GlobalDeclarationMap[&Func] = IceFunc;
888 }
889 // Install global variable declarations.
890 for (Module::const_global_iterator I = Mod->global_begin(),
891 E = Mod->global_end();
892 I != E; ++I) {
Jim Stichnothf5fdd232016-05-09 12:24:36 -0700893 const GlobalVariable *GV = &*I;
Jim Stichnoth98ba0062016-03-07 09:26:22 -0800894 constexpr bool NoSuppressMangling = false;
John Portoa78e4ba2016-03-15 09:28:04 -0700895 auto *Var = VariableDeclaration::create(
896 GlobalDeclarationsPool.get(), NoSuppressMangling, GV->getLinkage());
Karl Schimpf9d98d792014-10-13 15:01:08 -0700897 Var->setAlignment(GV->getAlignment());
898 Var->setIsConstant(GV->isConstant());
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700899 Var->setName(Ctx, GV->getName());
Karl Schimpfd4699942016-04-02 09:55:31 -0700900 if (!Var->verifyLinkageCorrect()) {
Karl Schimpf57d31ac2015-10-07 09:53:12 -0700901 std::string Buffer;
902 raw_string_ostream StrBuf(Buffer);
903 StrBuf << "Global " << Var->getName()
904 << " has incorrect linkage: " << Var->getLinkageName();
Jim Stichnoth4e10aa22015-10-16 13:13:11 -0700905 if (Var->isExternal())
906 StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
Karl Schimpf57d31ac2015-10-07 09:53:12 -0700907 report_fatal_error(StrBuf.str());
908 }
Karl Schimpf9d98d792014-10-13 15:01:08 -0700909 GlobalDeclarationMap[GV] = Var;
910 }
911}
912
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700913void Converter::convertGlobals(Module *Mod) {
John Portoa78e4ba2016-03-15 09:28:04 -0700914 LLVM2ICEGlobalsConverter(*this, GlobalDeclarationsPool.get())
915 .convertGlobalsToIce(Mod);
916 lowerGlobals(std::move(GlobalDeclarationsPool));
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700917}
918
Karl Schimpfd6064a12014-08-27 15:34:58 -0700919void Converter::convertFunctions() {
Jim Stichnothf44f3712014-10-01 14:05:51 -0700920 for (const Function &I : *Mod) {
921 if (I.empty())
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700922 continue;
Jim Stichnothb88d8c82016-03-11 15:33:00 -0800923 TimerMarker _(Ctx, I.getName());
Karl Schimpf9d98d792014-10-13 15:01:08 -0700924 LLVM2ICEFunctionConverter FunctionConverter(*this);
Jim Stichnoth8e928382015-02-02 17:03:08 -0800925 FunctionConverter.convertFunction(&I);
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700926 }
Karl Schimpfe1e013c2014-06-27 09:15:29 -0700927}
Karl Schimpfb164d202014-07-11 10:26:34 -0700928
Jim Stichnoth989a7032014-08-08 10:13:44 -0700929} // end of namespace Ice