1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceConverter.cpp - Converts LLVM to Ice ---------------===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Implements the LLVM to ICE converter.
12*03ce13f7SAndroid Build Coastguard Worker ///
13*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*03ce13f7SAndroid Build Coastguard Worker
15*03ce13f7SAndroid Build Coastguard Worker #include "IceConverter.h"
16*03ce13f7SAndroid Build Coastguard Worker
17*03ce13f7SAndroid Build Coastguard Worker #include "IceCfg.h"
18*03ce13f7SAndroid Build Coastguard Worker #include "IceCfgNode.h"
19*03ce13f7SAndroid Build Coastguard Worker #include "IceClFlags.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceGlobalContext.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceGlobalInits.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "IceInst.h"
24*03ce13f7SAndroid Build Coastguard Worker #include "IceMangling.h"
25*03ce13f7SAndroid Build Coastguard Worker #include "IceOperand.h"
26*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h"
27*03ce13f7SAndroid Build Coastguard Worker #include "IceTypeConverter.h"
28*03ce13f7SAndroid Build Coastguard Worker #include "IceTypes.h"
29*03ce13f7SAndroid Build Coastguard Worker
30*03ce13f7SAndroid Build Coastguard Worker #ifdef __clang__
31*03ce13f7SAndroid Build Coastguard Worker #pragma clang diagnostic push
32*03ce13f7SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wunused-parameter"
33*03ce13f7SAndroid Build Coastguard Worker #endif // __clang__
34*03ce13f7SAndroid Build Coastguard Worker
35*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/Constant.h"
36*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
37*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
38*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/Instruction.h"
39*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
40*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
41*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
42*03ce13f7SAndroid Build Coastguard Worker
43*03ce13f7SAndroid Build Coastguard Worker #ifdef __clang__
44*03ce13f7SAndroid Build Coastguard Worker #pragma clang diagnostic pop
45*03ce13f7SAndroid Build Coastguard Worker #endif // __clang__
46*03ce13f7SAndroid Build Coastguard Worker
47*03ce13f7SAndroid Build Coastguard Worker // TODO(kschimpf): Remove two namespaces being visible at once.
48*03ce13f7SAndroid Build Coastguard Worker using namespace llvm;
49*03ce13f7SAndroid Build Coastguard Worker
50*03ce13f7SAndroid Build Coastguard Worker namespace {
51*03ce13f7SAndroid Build Coastguard Worker
52*03ce13f7SAndroid Build Coastguard Worker // Debugging helper
LLVMObjectAsString(const T * O)53*03ce13f7SAndroid Build Coastguard Worker template <typename T> static std::string LLVMObjectAsString(const T *O) {
54*03ce13f7SAndroid Build Coastguard Worker std::string Dump;
55*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream Stream(Dump);
56*03ce13f7SAndroid Build Coastguard Worker O->print(Stream);
57*03ce13f7SAndroid Build Coastguard Worker return Stream.str();
58*03ce13f7SAndroid Build Coastguard Worker }
59*03ce13f7SAndroid Build Coastguard Worker
60*03ce13f7SAndroid Build Coastguard Worker // Base class for converting LLVM to ICE.
61*03ce13f7SAndroid Build Coastguard Worker // TODO(stichnot): Redesign Converter, LLVM2ICEConverter,
62*03ce13f7SAndroid Build Coastguard Worker // LLVM2ICEFunctionConverter, and LLVM2ICEGlobalsConverter with respect to
63*03ce13f7SAndroid Build Coastguard Worker // Translator. In particular, the unique_ptr ownership rules in
64*03ce13f7SAndroid Build Coastguard Worker // LLVM2ICEFunctionConverter.
65*03ce13f7SAndroid Build Coastguard Worker class LLVM2ICEConverter {
66*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEConverter() = delete;
67*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEConverter(const LLVM2ICEConverter &) = delete;
68*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEConverter &operator=(const LLVM2ICEConverter &) = delete;
69*03ce13f7SAndroid Build Coastguard Worker
70*03ce13f7SAndroid Build Coastguard Worker public:
LLVM2ICEConverter(Ice::Converter & Converter)71*03ce13f7SAndroid Build Coastguard Worker explicit LLVM2ICEConverter(Ice::Converter &Converter)
72*03ce13f7SAndroid Build Coastguard Worker : Converter(Converter), Ctx(Converter.getContext()),
73*03ce13f7SAndroid Build Coastguard Worker TypeConverter(Converter.getModule()->getContext()) {}
74*03ce13f7SAndroid Build Coastguard Worker
getConverter() const75*03ce13f7SAndroid Build Coastguard Worker Ice::Converter &getConverter() const { return Converter; }
76*03ce13f7SAndroid Build Coastguard Worker
77*03ce13f7SAndroid Build Coastguard Worker protected:
78*03ce13f7SAndroid Build Coastguard Worker Ice::Converter &Converter;
79*03ce13f7SAndroid Build Coastguard Worker Ice::GlobalContext *Ctx;
80*03ce13f7SAndroid Build Coastguard Worker const Ice::TypeConverter TypeConverter;
81*03ce13f7SAndroid Build Coastguard Worker };
82*03ce13f7SAndroid Build Coastguard Worker
83*03ce13f7SAndroid Build Coastguard Worker // Converter from LLVM functions to ICE. The entry point is the convertFunction
84*03ce13f7SAndroid Build Coastguard Worker // method.
85*03ce13f7SAndroid Build Coastguard Worker //
86*03ce13f7SAndroid Build Coastguard Worker // Note: this currently assumes that the given IR was verified to be valid
87*03ce13f7SAndroid Build Coastguard Worker // PNaCl bitcode. Otherwise, the behavior is undefined.
88*03ce13f7SAndroid Build Coastguard Worker class LLVM2ICEFunctionConverter : LLVM2ICEConverter {
89*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEFunctionConverter() = delete;
90*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEFunctionConverter(const LLVM2ICEFunctionConverter &) = delete;
91*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEFunctionConverter &
92*03ce13f7SAndroid Build Coastguard Worker operator=(const LLVM2ICEFunctionConverter &) = delete;
93*03ce13f7SAndroid Build Coastguard Worker
94*03ce13f7SAndroid Build Coastguard Worker public:
LLVM2ICEFunctionConverter(Ice::Converter & Converter)95*03ce13f7SAndroid Build Coastguard Worker explicit LLVM2ICEFunctionConverter(Ice::Converter &Converter)
96*03ce13f7SAndroid Build Coastguard Worker : LLVM2ICEConverter(Converter), Func(nullptr) {}
97*03ce13f7SAndroid Build Coastguard Worker
convertFunction(const Function * F)98*03ce13f7SAndroid Build Coastguard Worker void convertFunction(const Function *F) {
99*03ce13f7SAndroid Build Coastguard Worker Func = Ice::Cfg::create(Ctx, Converter.getNextSequenceNumber());
100*03ce13f7SAndroid Build Coastguard Worker {
101*03ce13f7SAndroid Build Coastguard Worker Ice::CfgLocalAllocatorScope _(Func.get());
102*03ce13f7SAndroid Build Coastguard Worker
103*03ce13f7SAndroid Build Coastguard Worker VarMap.clear();
104*03ce13f7SAndroid Build Coastguard Worker NodeMap.clear();
105*03ce13f7SAndroid Build Coastguard Worker Func->setFunctionName(
106*03ce13f7SAndroid Build Coastguard Worker Ctx->getGlobalString(Ice::mangleName(F->getName())));
107*03ce13f7SAndroid Build Coastguard Worker Func->setReturnType(convertToIceType(F->getReturnType()));
108*03ce13f7SAndroid Build Coastguard Worker Func->setInternal(F->hasInternalLinkage());
109*03ce13f7SAndroid Build Coastguard Worker Ice::TimerMarker T(Ice::TimerStack::TT_llvmConvert, Func.get());
110*03ce13f7SAndroid Build Coastguard Worker
111*03ce13f7SAndroid Build Coastguard Worker // The initial definition/use of each arg is the entry node.
112*03ce13f7SAndroid Build Coastguard Worker for (auto ArgI = F->arg_begin(), ArgE = F->arg_end(); ArgI != ArgE;
113*03ce13f7SAndroid Build Coastguard Worker ++ArgI) {
114*03ce13f7SAndroid Build Coastguard Worker Func->addArg(mapValueToIceVar(&*ArgI));
115*03ce13f7SAndroid Build Coastguard Worker }
116*03ce13f7SAndroid Build Coastguard Worker
117*03ce13f7SAndroid Build Coastguard Worker // Make an initial pass through the block list just to resolve the blocks
118*03ce13f7SAndroid Build Coastguard Worker // in the original linearized order. Otherwise the ICE linearized order
119*03ce13f7SAndroid Build Coastguard Worker // will be affected by branch targets in terminator instructions.
120*03ce13f7SAndroid Build Coastguard Worker for (const BasicBlock &BBI : *F)
121*03ce13f7SAndroid Build Coastguard Worker mapBasicBlockToNode(&BBI);
122*03ce13f7SAndroid Build Coastguard Worker for (const BasicBlock &BBI : *F)
123*03ce13f7SAndroid Build Coastguard Worker convertBasicBlock(&BBI);
124*03ce13f7SAndroid Build Coastguard Worker Func->setEntryNode(mapBasicBlockToNode(&F->getEntryBlock()));
125*03ce13f7SAndroid Build Coastguard Worker Func->computeInOutEdges();
126*03ce13f7SAndroid Build Coastguard Worker }
127*03ce13f7SAndroid Build Coastguard Worker Converter.translateFcn(std::move(Func));
128*03ce13f7SAndroid Build Coastguard Worker }
129*03ce13f7SAndroid Build Coastguard Worker
130*03ce13f7SAndroid Build Coastguard Worker // convertConstant() does not use Func or require it to be a valid Ice::Cfg
131*03ce13f7SAndroid Build Coastguard Worker // pointer. As such, it's suitable for e.g. constructing global initializers.
convertConstant(const Constant * Const)132*03ce13f7SAndroid Build Coastguard Worker Ice::Constant *convertConstant(const Constant *Const) {
133*03ce13f7SAndroid Build Coastguard Worker if (const auto GV = dyn_cast<GlobalValue>(Const)) {
134*03ce13f7SAndroid Build Coastguard Worker Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV);
135*03ce13f7SAndroid Build Coastguard Worker bool IsUndefined = false;
136*03ce13f7SAndroid Build Coastguard Worker if (const auto *Func = llvm::dyn_cast<Ice::FunctionDeclaration>(Decl))
137*03ce13f7SAndroid Build Coastguard Worker IsUndefined = Func->isProto();
138*03ce13f7SAndroid Build Coastguard Worker else if (const auto *Var = llvm::dyn_cast<Ice::VariableDeclaration>(Decl))
139*03ce13f7SAndroid Build Coastguard Worker IsUndefined = !Var->hasInitializer();
140*03ce13f7SAndroid Build Coastguard Worker else
141*03ce13f7SAndroid Build Coastguard Worker report_fatal_error("Unhandled GlobalDeclaration type");
142*03ce13f7SAndroid Build Coastguard Worker if (IsUndefined)
143*03ce13f7SAndroid Build Coastguard Worker return Ctx->getConstantExternSym(Decl->getName());
144*03ce13f7SAndroid Build Coastguard Worker else {
145*03ce13f7SAndroid Build Coastguard Worker const Ice::RelocOffsetT Offset = 0;
146*03ce13f7SAndroid Build Coastguard Worker return Ctx->getConstantSym(
147*03ce13f7SAndroid Build Coastguard Worker Offset, Ctx->getGlobalString(Decl->getName().toString()));
148*03ce13f7SAndroid Build Coastguard Worker }
149*03ce13f7SAndroid Build Coastguard Worker } else if (const auto CI = dyn_cast<ConstantInt>(Const)) {
150*03ce13f7SAndroid Build Coastguard Worker Ice::Type Ty = convertToIceType(CI->getType());
151*03ce13f7SAndroid Build Coastguard Worker return Ctx->getConstantInt(Ty, CI->getSExtValue());
152*03ce13f7SAndroid Build Coastguard Worker } else if (const auto CFP = dyn_cast<ConstantFP>(Const)) {
153*03ce13f7SAndroid Build Coastguard Worker Ice::Type Type = convertToIceType(CFP->getType());
154*03ce13f7SAndroid Build Coastguard Worker if (Type == Ice::IceType_f32)
155*03ce13f7SAndroid Build Coastguard Worker return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat());
156*03ce13f7SAndroid Build Coastguard Worker else if (Type == Ice::IceType_f64)
157*03ce13f7SAndroid Build Coastguard Worker return Ctx->getConstantDouble(CFP->getValueAPF().convertToDouble());
158*03ce13f7SAndroid Build Coastguard Worker llvm_unreachable("Unexpected floating point type");
159*03ce13f7SAndroid Build Coastguard Worker return nullptr;
160*03ce13f7SAndroid Build Coastguard Worker } else if (const auto CU = dyn_cast<UndefValue>(Const)) {
161*03ce13f7SAndroid Build Coastguard Worker return Ctx->getConstantUndef(convertToIceType(CU->getType()));
162*03ce13f7SAndroid Build Coastguard Worker } else {
163*03ce13f7SAndroid Build Coastguard Worker llvm_unreachable("Unhandled constant type");
164*03ce13f7SAndroid Build Coastguard Worker return nullptr;
165*03ce13f7SAndroid Build Coastguard Worker }
166*03ce13f7SAndroid Build Coastguard Worker }
167*03ce13f7SAndroid Build Coastguard Worker
168*03ce13f7SAndroid Build Coastguard Worker private:
169*03ce13f7SAndroid Build Coastguard Worker // LLVM values (instructions, etc.) are mapped directly to ICE variables.
170*03ce13f7SAndroid Build Coastguard Worker // mapValueToIceVar has a version that forces an ICE type on the variable,
171*03ce13f7SAndroid Build Coastguard Worker // and a version that just uses convertToIceType on V.
mapValueToIceVar(const Value * V,Ice::Type IceTy)172*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *mapValueToIceVar(const Value *V, Ice::Type IceTy) {
173*03ce13f7SAndroid Build Coastguard Worker if (IceTy == Ice::IceType_void)
174*03ce13f7SAndroid Build Coastguard Worker return nullptr;
175*03ce13f7SAndroid Build Coastguard Worker if (VarMap.find(V) == VarMap.end()) {
176*03ce13f7SAndroid Build Coastguard Worker VarMap[V] = Func->makeVariable(IceTy);
177*03ce13f7SAndroid Build Coastguard Worker if (Ice::BuildDefs::dump())
178*03ce13f7SAndroid Build Coastguard Worker VarMap[V]->setName(Func.get(), V->getName());
179*03ce13f7SAndroid Build Coastguard Worker }
180*03ce13f7SAndroid Build Coastguard Worker return VarMap[V];
181*03ce13f7SAndroid Build Coastguard Worker }
182*03ce13f7SAndroid Build Coastguard Worker
mapValueToIceVar(const Value * V)183*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *mapValueToIceVar(const Value *V) {
184*03ce13f7SAndroid Build Coastguard Worker return mapValueToIceVar(V, convertToIceType(V->getType()));
185*03ce13f7SAndroid Build Coastguard Worker }
186*03ce13f7SAndroid Build Coastguard Worker
mapBasicBlockToNode(const BasicBlock * BB)187*03ce13f7SAndroid Build Coastguard Worker Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) {
188*03ce13f7SAndroid Build Coastguard Worker if (NodeMap.find(BB) == NodeMap.end()) {
189*03ce13f7SAndroid Build Coastguard Worker NodeMap[BB] = Func->makeNode();
190*03ce13f7SAndroid Build Coastguard Worker if (Ice::BuildDefs::dump())
191*03ce13f7SAndroid Build Coastguard Worker NodeMap[BB]->setName(BB->getName());
192*03ce13f7SAndroid Build Coastguard Worker }
193*03ce13f7SAndroid Build Coastguard Worker return NodeMap[BB];
194*03ce13f7SAndroid Build Coastguard Worker }
195*03ce13f7SAndroid Build Coastguard Worker
convertToIceType(Type * LLVMTy) const196*03ce13f7SAndroid Build Coastguard Worker Ice::Type convertToIceType(Type *LLVMTy) const {
197*03ce13f7SAndroid Build Coastguard Worker Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy);
198*03ce13f7SAndroid Build Coastguard Worker if (IceTy == Ice::IceType_NUM)
199*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(std::string("Invalid PNaCl type ") +
200*03ce13f7SAndroid Build Coastguard Worker LLVMObjectAsString(LLVMTy));
201*03ce13f7SAndroid Build Coastguard Worker return IceTy;
202*03ce13f7SAndroid Build Coastguard Worker }
203*03ce13f7SAndroid Build Coastguard Worker
204*03ce13f7SAndroid Build Coastguard Worker // Given an LLVM instruction and an operand number, produce the Ice::Operand
205*03ce13f7SAndroid Build Coastguard Worker // this refers to. If there's no such operand, return nullptr.
convertOperand(const Instruction * Instr,unsigned OpNum)206*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *convertOperand(const Instruction *Instr, unsigned OpNum) {
207*03ce13f7SAndroid Build Coastguard Worker if (OpNum >= Instr->getNumOperands()) {
208*03ce13f7SAndroid Build Coastguard Worker return nullptr;
209*03ce13f7SAndroid Build Coastguard Worker }
210*03ce13f7SAndroid Build Coastguard Worker const Value *Op = Instr->getOperand(OpNum);
211*03ce13f7SAndroid Build Coastguard Worker return convertValue(Op);
212*03ce13f7SAndroid Build Coastguard Worker }
213*03ce13f7SAndroid Build Coastguard Worker
convertValue(const Value * Op)214*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *convertValue(const Value *Op) {
215*03ce13f7SAndroid Build Coastguard Worker if (const auto Const = dyn_cast<Constant>(Op)) {
216*03ce13f7SAndroid Build Coastguard Worker return convertConstant(Const);
217*03ce13f7SAndroid Build Coastguard Worker } else {
218*03ce13f7SAndroid Build Coastguard Worker return mapValueToIceVar(Op);
219*03ce13f7SAndroid Build Coastguard Worker }
220*03ce13f7SAndroid Build Coastguard Worker }
221*03ce13f7SAndroid Build Coastguard Worker
222*03ce13f7SAndroid Build Coastguard Worker // Note: this currently assumes a 1x1 mapping between LLVM IR and Ice
223*03ce13f7SAndroid Build Coastguard Worker // instructions.
convertInstruction(const Instruction * Instr)224*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertInstruction(const Instruction *Instr) {
225*03ce13f7SAndroid Build Coastguard Worker switch (Instr->getOpcode()) {
226*03ce13f7SAndroid Build Coastguard Worker case Instruction::PHI:
227*03ce13f7SAndroid Build Coastguard Worker return convertPHINodeInstruction(cast<PHINode>(Instr));
228*03ce13f7SAndroid Build Coastguard Worker case Instruction::Br:
229*03ce13f7SAndroid Build Coastguard Worker return convertBrInstruction(cast<BranchInst>(Instr));
230*03ce13f7SAndroid Build Coastguard Worker case Instruction::Ret:
231*03ce13f7SAndroid Build Coastguard Worker return convertRetInstruction(cast<ReturnInst>(Instr));
232*03ce13f7SAndroid Build Coastguard Worker case Instruction::IntToPtr:
233*03ce13f7SAndroid Build Coastguard Worker return convertIntToPtrInstruction(cast<IntToPtrInst>(Instr));
234*03ce13f7SAndroid Build Coastguard Worker case Instruction::PtrToInt:
235*03ce13f7SAndroid Build Coastguard Worker return convertPtrToIntInstruction(cast<PtrToIntInst>(Instr));
236*03ce13f7SAndroid Build Coastguard Worker case Instruction::ICmp:
237*03ce13f7SAndroid Build Coastguard Worker return convertICmpInstruction(cast<ICmpInst>(Instr));
238*03ce13f7SAndroid Build Coastguard Worker case Instruction::FCmp:
239*03ce13f7SAndroid Build Coastguard Worker return convertFCmpInstruction(cast<FCmpInst>(Instr));
240*03ce13f7SAndroid Build Coastguard Worker case Instruction::Select:
241*03ce13f7SAndroid Build Coastguard Worker return convertSelectInstruction(cast<SelectInst>(Instr));
242*03ce13f7SAndroid Build Coastguard Worker case Instruction::Switch:
243*03ce13f7SAndroid Build Coastguard Worker return convertSwitchInstruction(cast<SwitchInst>(Instr));
244*03ce13f7SAndroid Build Coastguard Worker case Instruction::Load:
245*03ce13f7SAndroid Build Coastguard Worker return convertLoadInstruction(cast<LoadInst>(Instr));
246*03ce13f7SAndroid Build Coastguard Worker case Instruction::Store:
247*03ce13f7SAndroid Build Coastguard Worker return convertStoreInstruction(cast<StoreInst>(Instr));
248*03ce13f7SAndroid Build Coastguard Worker case Instruction::ZExt:
249*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<ZExtInst>(Instr), Ice::InstCast::Zext);
250*03ce13f7SAndroid Build Coastguard Worker case Instruction::SExt:
251*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<SExtInst>(Instr), Ice::InstCast::Sext);
252*03ce13f7SAndroid Build Coastguard Worker case Instruction::Trunc:
253*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<TruncInst>(Instr),
254*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::Trunc);
255*03ce13f7SAndroid Build Coastguard Worker case Instruction::FPTrunc:
256*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<FPTruncInst>(Instr),
257*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::Fptrunc);
258*03ce13f7SAndroid Build Coastguard Worker case Instruction::FPExt:
259*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<FPExtInst>(Instr),
260*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::Fpext);
261*03ce13f7SAndroid Build Coastguard Worker case Instruction::FPToSI:
262*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<FPToSIInst>(Instr),
263*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::Fptosi);
264*03ce13f7SAndroid Build Coastguard Worker case Instruction::FPToUI:
265*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<FPToUIInst>(Instr),
266*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::Fptoui);
267*03ce13f7SAndroid Build Coastguard Worker case Instruction::SIToFP:
268*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<SIToFPInst>(Instr),
269*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::Sitofp);
270*03ce13f7SAndroid Build Coastguard Worker case Instruction::UIToFP:
271*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<UIToFPInst>(Instr),
272*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::Uitofp);
273*03ce13f7SAndroid Build Coastguard Worker case Instruction::BitCast:
274*03ce13f7SAndroid Build Coastguard Worker return convertCastInstruction(cast<BitCastInst>(Instr),
275*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::Bitcast);
276*03ce13f7SAndroid Build Coastguard Worker case Instruction::Add:
277*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Add);
278*03ce13f7SAndroid Build Coastguard Worker case Instruction::Sub:
279*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Sub);
280*03ce13f7SAndroid Build Coastguard Worker case Instruction::Mul:
281*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Mul);
282*03ce13f7SAndroid Build Coastguard Worker case Instruction::UDiv:
283*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Udiv);
284*03ce13f7SAndroid Build Coastguard Worker case Instruction::SDiv:
285*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Sdiv);
286*03ce13f7SAndroid Build Coastguard Worker case Instruction::URem:
287*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Urem);
288*03ce13f7SAndroid Build Coastguard Worker case Instruction::SRem:
289*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Srem);
290*03ce13f7SAndroid Build Coastguard Worker case Instruction::Shl:
291*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Shl);
292*03ce13f7SAndroid Build Coastguard Worker case Instruction::LShr:
293*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Lshr);
294*03ce13f7SAndroid Build Coastguard Worker case Instruction::AShr:
295*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Ashr);
296*03ce13f7SAndroid Build Coastguard Worker case Instruction::FAdd:
297*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Fadd);
298*03ce13f7SAndroid Build Coastguard Worker case Instruction::FSub:
299*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Fsub);
300*03ce13f7SAndroid Build Coastguard Worker case Instruction::FMul:
301*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Fmul);
302*03ce13f7SAndroid Build Coastguard Worker case Instruction::FDiv:
303*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Fdiv);
304*03ce13f7SAndroid Build Coastguard Worker case Instruction::FRem:
305*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Frem);
306*03ce13f7SAndroid Build Coastguard Worker case Instruction::And:
307*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::And);
308*03ce13f7SAndroid Build Coastguard Worker case Instruction::Or:
309*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Or);
310*03ce13f7SAndroid Build Coastguard Worker case Instruction::Xor:
311*03ce13f7SAndroid Build Coastguard Worker return convertArithInstruction(Instr, Ice::InstArithmetic::Xor);
312*03ce13f7SAndroid Build Coastguard Worker case Instruction::ExtractElement:
313*03ce13f7SAndroid Build Coastguard Worker return convertExtractElementInstruction(cast<ExtractElementInst>(Instr));
314*03ce13f7SAndroid Build Coastguard Worker case Instruction::InsertElement:
315*03ce13f7SAndroid Build Coastguard Worker return convertInsertElementInstruction(cast<InsertElementInst>(Instr));
316*03ce13f7SAndroid Build Coastguard Worker case Instruction::Call:
317*03ce13f7SAndroid Build Coastguard Worker return convertCallInstruction(cast<CallInst>(Instr));
318*03ce13f7SAndroid Build Coastguard Worker case Instruction::Alloca:
319*03ce13f7SAndroid Build Coastguard Worker return convertAllocaInstruction(cast<AllocaInst>(Instr));
320*03ce13f7SAndroid Build Coastguard Worker case Instruction::Unreachable:
321*03ce13f7SAndroid Build Coastguard Worker return convertUnreachableInstruction(cast<UnreachableInst>(Instr));
322*03ce13f7SAndroid Build Coastguard Worker default:
323*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(std::string("Invalid PNaCl instruction: ") +
324*03ce13f7SAndroid Build Coastguard Worker LLVMObjectAsString(Instr));
325*03ce13f7SAndroid Build Coastguard Worker }
326*03ce13f7SAndroid Build Coastguard Worker
327*03ce13f7SAndroid Build Coastguard Worker llvm_unreachable("convertInstruction");
328*03ce13f7SAndroid Build Coastguard Worker return nullptr;
329*03ce13f7SAndroid Build Coastguard Worker }
330*03ce13f7SAndroid Build Coastguard Worker
convertLoadInstruction(const LoadInst * Instr)331*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertLoadInstruction(const LoadInst *Instr) {
332*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src = convertOperand(Instr, 0);
333*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
334*03ce13f7SAndroid Build Coastguard Worker return Ice::InstLoad::create(Func.get(), Dest, Src);
335*03ce13f7SAndroid Build Coastguard Worker }
336*03ce13f7SAndroid Build Coastguard Worker
convertStoreInstruction(const StoreInst * Instr)337*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertStoreInstruction(const StoreInst *Instr) {
338*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Addr = convertOperand(Instr, 1);
339*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Val = convertOperand(Instr, 0);
340*03ce13f7SAndroid Build Coastguard Worker return Ice::InstStore::create(Func.get(), Val, Addr);
341*03ce13f7SAndroid Build Coastguard Worker }
342*03ce13f7SAndroid Build Coastguard Worker
convertArithInstruction(const Instruction * Instr,Ice::InstArithmetic::OpKind Opcode)343*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertArithInstruction(const Instruction *Instr,
344*03ce13f7SAndroid Build Coastguard Worker Ice::InstArithmetic::OpKind Opcode) {
345*03ce13f7SAndroid Build Coastguard Worker const auto BinOp = cast<BinaryOperator>(Instr);
346*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src0 = convertOperand(Instr, 0);
347*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src1 = convertOperand(Instr, 1);
348*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(BinOp);
349*03ce13f7SAndroid Build Coastguard Worker return Ice::InstArithmetic::create(Func.get(), Opcode, Dest, Src0, Src1);
350*03ce13f7SAndroid Build Coastguard Worker }
351*03ce13f7SAndroid Build Coastguard Worker
convertPHINodeInstruction(const PHINode * Instr)352*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertPHINodeInstruction(const PHINode *Instr) {
353*03ce13f7SAndroid Build Coastguard Worker unsigned NumValues = Instr->getNumIncomingValues();
354*03ce13f7SAndroid Build Coastguard Worker Ice::InstPhi *IcePhi =
355*03ce13f7SAndroid Build Coastguard Worker Ice::InstPhi::create(Func.get(), NumValues, mapValueToIceVar(Instr));
356*03ce13f7SAndroid Build Coastguard Worker for (unsigned N = 0, E = NumValues; N != E; ++N) {
357*03ce13f7SAndroid Build Coastguard Worker IcePhi->addArgument(convertOperand(Instr, N),
358*03ce13f7SAndroid Build Coastguard Worker mapBasicBlockToNode(Instr->getIncomingBlock(N)));
359*03ce13f7SAndroid Build Coastguard Worker }
360*03ce13f7SAndroid Build Coastguard Worker return IcePhi;
361*03ce13f7SAndroid Build Coastguard Worker }
362*03ce13f7SAndroid Build Coastguard Worker
convertBrInstruction(const BranchInst * Instr)363*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertBrInstruction(const BranchInst *Instr) {
364*03ce13f7SAndroid Build Coastguard Worker if (Instr->isConditional()) {
365*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src = convertOperand(Instr, 0);
366*03ce13f7SAndroid Build Coastguard Worker BasicBlock *BBThen = Instr->getSuccessor(0);
367*03ce13f7SAndroid Build Coastguard Worker BasicBlock *BBElse = Instr->getSuccessor(1);
368*03ce13f7SAndroid Build Coastguard Worker Ice::CfgNode *NodeThen = mapBasicBlockToNode(BBThen);
369*03ce13f7SAndroid Build Coastguard Worker Ice::CfgNode *NodeElse = mapBasicBlockToNode(BBElse);
370*03ce13f7SAndroid Build Coastguard Worker return Ice::InstBr::create(Func.get(), Src, NodeThen, NodeElse);
371*03ce13f7SAndroid Build Coastguard Worker } else {
372*03ce13f7SAndroid Build Coastguard Worker BasicBlock *BBSucc = Instr->getSuccessor(0);
373*03ce13f7SAndroid Build Coastguard Worker return Ice::InstBr::create(Func.get(), mapBasicBlockToNode(BBSucc));
374*03ce13f7SAndroid Build Coastguard Worker }
375*03ce13f7SAndroid Build Coastguard Worker }
376*03ce13f7SAndroid Build Coastguard Worker
convertIntToPtrInstruction(const IntToPtrInst * Instr)377*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertIntToPtrInstruction(const IntToPtrInst *Instr) {
378*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src = convertOperand(Instr, 0);
379*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr, Ice::getPointerType());
380*03ce13f7SAndroid Build Coastguard Worker return Ice::InstAssign::create(Func.get(), Dest, Src);
381*03ce13f7SAndroid Build Coastguard Worker }
382*03ce13f7SAndroid Build Coastguard Worker
convertPtrToIntInstruction(const PtrToIntInst * Instr)383*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertPtrToIntInstruction(const PtrToIntInst *Instr) {
384*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src = convertOperand(Instr, 0);
385*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
386*03ce13f7SAndroid Build Coastguard Worker return Ice::InstAssign::create(Func.get(), Dest, Src);
387*03ce13f7SAndroid Build Coastguard Worker }
388*03ce13f7SAndroid Build Coastguard Worker
convertRetInstruction(const ReturnInst * Instr)389*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertRetInstruction(const ReturnInst *Instr) {
390*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *RetOperand = convertOperand(Instr, 0);
391*03ce13f7SAndroid Build Coastguard Worker if (RetOperand) {
392*03ce13f7SAndroid Build Coastguard Worker return Ice::InstRet::create(Func.get(), RetOperand);
393*03ce13f7SAndroid Build Coastguard Worker } else {
394*03ce13f7SAndroid Build Coastguard Worker return Ice::InstRet::create(Func.get());
395*03ce13f7SAndroid Build Coastguard Worker }
396*03ce13f7SAndroid Build Coastguard Worker }
397*03ce13f7SAndroid Build Coastguard Worker
convertCastInstruction(const Instruction * Instr,Ice::InstCast::OpKind CastKind)398*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertCastInstruction(const Instruction *Instr,
399*03ce13f7SAndroid Build Coastguard Worker Ice::InstCast::OpKind CastKind) {
400*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src = convertOperand(Instr, 0);
401*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
402*03ce13f7SAndroid Build Coastguard Worker return Ice::InstCast::create(Func.get(), CastKind, Dest, Src);
403*03ce13f7SAndroid Build Coastguard Worker }
404*03ce13f7SAndroid Build Coastguard Worker
convertICmpInstruction(const ICmpInst * Instr)405*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertICmpInstruction(const ICmpInst *Instr) {
406*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src0 = convertOperand(Instr, 0);
407*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src1 = convertOperand(Instr, 1);
408*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
409*03ce13f7SAndroid Build Coastguard Worker
410*03ce13f7SAndroid Build Coastguard Worker Ice::InstIcmp::ICond Cond;
411*03ce13f7SAndroid Build Coastguard Worker switch (Instr->getPredicate()) {
412*03ce13f7SAndroid Build Coastguard Worker default:
413*03ce13f7SAndroid Build Coastguard Worker llvm_unreachable("ICmpInst predicate");
414*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_EQ:
415*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Eq;
416*03ce13f7SAndroid Build Coastguard Worker break;
417*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_NE:
418*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Ne;
419*03ce13f7SAndroid Build Coastguard Worker break;
420*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_UGT:
421*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Ugt;
422*03ce13f7SAndroid Build Coastguard Worker break;
423*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_UGE:
424*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Uge;
425*03ce13f7SAndroid Build Coastguard Worker break;
426*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_ULT:
427*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Ult;
428*03ce13f7SAndroid Build Coastguard Worker break;
429*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_ULE:
430*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Ule;
431*03ce13f7SAndroid Build Coastguard Worker break;
432*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_SGT:
433*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Sgt;
434*03ce13f7SAndroid Build Coastguard Worker break;
435*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_SGE:
436*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Sge;
437*03ce13f7SAndroid Build Coastguard Worker break;
438*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_SLT:
439*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Slt;
440*03ce13f7SAndroid Build Coastguard Worker break;
441*03ce13f7SAndroid Build Coastguard Worker case CmpInst::ICMP_SLE:
442*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstIcmp::Sle;
443*03ce13f7SAndroid Build Coastguard Worker break;
444*03ce13f7SAndroid Build Coastguard Worker }
445*03ce13f7SAndroid Build Coastguard Worker
446*03ce13f7SAndroid Build Coastguard Worker return Ice::InstIcmp::create(Func.get(), Cond, Dest, Src0, Src1);
447*03ce13f7SAndroid Build Coastguard Worker }
448*03ce13f7SAndroid Build Coastguard Worker
convertFCmpInstruction(const FCmpInst * Instr)449*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertFCmpInstruction(const FCmpInst *Instr) {
450*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src0 = convertOperand(Instr, 0);
451*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Src1 = convertOperand(Instr, 1);
452*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
453*03ce13f7SAndroid Build Coastguard Worker
454*03ce13f7SAndroid Build Coastguard Worker Ice::InstFcmp::FCond Cond;
455*03ce13f7SAndroid Build Coastguard Worker switch (Instr->getPredicate()) {
456*03ce13f7SAndroid Build Coastguard Worker
457*03ce13f7SAndroid Build Coastguard Worker default:
458*03ce13f7SAndroid Build Coastguard Worker llvm_unreachable("FCmpInst predicate");
459*03ce13f7SAndroid Build Coastguard Worker
460*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_FALSE:
461*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::False;
462*03ce13f7SAndroid Build Coastguard Worker break;
463*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_OEQ:
464*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Oeq;
465*03ce13f7SAndroid Build Coastguard Worker break;
466*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_OGT:
467*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Ogt;
468*03ce13f7SAndroid Build Coastguard Worker break;
469*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_OGE:
470*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Oge;
471*03ce13f7SAndroid Build Coastguard Worker break;
472*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_OLT:
473*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Olt;
474*03ce13f7SAndroid Build Coastguard Worker break;
475*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_OLE:
476*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Ole;
477*03ce13f7SAndroid Build Coastguard Worker break;
478*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_ONE:
479*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::One;
480*03ce13f7SAndroid Build Coastguard Worker break;
481*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_ORD:
482*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Ord;
483*03ce13f7SAndroid Build Coastguard Worker break;
484*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_UEQ:
485*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Ueq;
486*03ce13f7SAndroid Build Coastguard Worker break;
487*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_UGT:
488*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Ugt;
489*03ce13f7SAndroid Build Coastguard Worker break;
490*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_UGE:
491*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Uge;
492*03ce13f7SAndroid Build Coastguard Worker break;
493*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_ULT:
494*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Ult;
495*03ce13f7SAndroid Build Coastguard Worker break;
496*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_ULE:
497*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Ule;
498*03ce13f7SAndroid Build Coastguard Worker break;
499*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_UNE:
500*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Une;
501*03ce13f7SAndroid Build Coastguard Worker break;
502*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_UNO:
503*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::Uno;
504*03ce13f7SAndroid Build Coastguard Worker break;
505*03ce13f7SAndroid Build Coastguard Worker case CmpInst::FCMP_TRUE:
506*03ce13f7SAndroid Build Coastguard Worker Cond = Ice::InstFcmp::True;
507*03ce13f7SAndroid Build Coastguard Worker break;
508*03ce13f7SAndroid Build Coastguard Worker }
509*03ce13f7SAndroid Build Coastguard Worker
510*03ce13f7SAndroid Build Coastguard Worker return Ice::InstFcmp::create(Func.get(), Cond, Dest, Src0, Src1);
511*03ce13f7SAndroid Build Coastguard Worker }
512*03ce13f7SAndroid Build Coastguard Worker
convertExtractElementInstruction(const ExtractElementInst * Instr)513*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertExtractElementInstruction(const ExtractElementInst *Instr) {
514*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
515*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Source1 = convertValue(Instr->getOperand(0));
516*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Source2 = convertValue(Instr->getOperand(1));
517*03ce13f7SAndroid Build Coastguard Worker return Ice::InstExtractElement::create(Func.get(), Dest, Source1, Source2);
518*03ce13f7SAndroid Build Coastguard Worker }
519*03ce13f7SAndroid Build Coastguard Worker
convertInsertElementInstruction(const InsertElementInst * Instr)520*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertInsertElementInstruction(const InsertElementInst *Instr) {
521*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
522*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Source1 = convertValue(Instr->getOperand(0));
523*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Source2 = convertValue(Instr->getOperand(1));
524*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Source3 = convertValue(Instr->getOperand(2));
525*03ce13f7SAndroid Build Coastguard Worker return Ice::InstInsertElement::create(Func.get(), Dest, Source1, Source2,
526*03ce13f7SAndroid Build Coastguard Worker Source3);
527*03ce13f7SAndroid Build Coastguard Worker }
528*03ce13f7SAndroid Build Coastguard Worker
convertSelectInstruction(const SelectInst * Instr)529*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertSelectInstruction(const SelectInst *Instr) {
530*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
531*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Cond = convertValue(Instr->getCondition());
532*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Source1 = convertValue(Instr->getTrueValue());
533*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Source2 = convertValue(Instr->getFalseValue());
534*03ce13f7SAndroid Build Coastguard Worker return Ice::InstSelect::create(Func.get(), Dest, Cond, Source1, Source2);
535*03ce13f7SAndroid Build Coastguard Worker }
536*03ce13f7SAndroid Build Coastguard Worker
convertSwitchInstruction(const SwitchInst * Instr)537*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertSwitchInstruction(const SwitchInst *Instr) {
538*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *Source = convertValue(Instr->getCondition());
539*03ce13f7SAndroid Build Coastguard Worker Ice::CfgNode *LabelDefault = mapBasicBlockToNode(Instr->getDefaultDest());
540*03ce13f7SAndroid Build Coastguard Worker unsigned NumCases = Instr->getNumCases();
541*03ce13f7SAndroid Build Coastguard Worker Ice::InstSwitch *Switch =
542*03ce13f7SAndroid Build Coastguard Worker Ice::InstSwitch::create(Func.get(), NumCases, Source, LabelDefault);
543*03ce13f7SAndroid Build Coastguard Worker unsigned CurrentCase = 0;
544*03ce13f7SAndroid Build Coastguard Worker for (SwitchInst::ConstCaseIt I = Instr->case_begin(), E = Instr->case_end();
545*03ce13f7SAndroid Build Coastguard Worker I != E; ++I, ++CurrentCase) {
546*03ce13f7SAndroid Build Coastguard Worker uint64_t CaseValue = I.getCaseValue()->getSExtValue();
547*03ce13f7SAndroid Build Coastguard Worker Ice::CfgNode *CaseSuccessor = mapBasicBlockToNode(I.getCaseSuccessor());
548*03ce13f7SAndroid Build Coastguard Worker Switch->addBranch(CurrentCase, CaseValue, CaseSuccessor);
549*03ce13f7SAndroid Build Coastguard Worker }
550*03ce13f7SAndroid Build Coastguard Worker return Switch;
551*03ce13f7SAndroid Build Coastguard Worker }
552*03ce13f7SAndroid Build Coastguard Worker
convertCallInstruction(const CallInst * Instr)553*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertCallInstruction(const CallInst *Instr) {
554*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr);
555*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *CallTarget = convertValue(Instr->getCalledValue());
556*03ce13f7SAndroid Build Coastguard Worker unsigned NumArgs = Instr->getNumArgOperands();
557*03ce13f7SAndroid Build Coastguard Worker
558*03ce13f7SAndroid Build Coastguard Worker if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) {
559*03ce13f7SAndroid Build Coastguard Worker // Check if this direct call is to an Intrinsic (starts with "llvm.")
560*03ce13f7SAndroid Build Coastguard Worker bool BadIntrinsic;
561*03ce13f7SAndroid Build Coastguard Worker const Ice::Intrinsics::FullIntrinsicInfo *Info =
562*03ce13f7SAndroid Build Coastguard Worker Ctx->getIntrinsicsInfo().find(Target->getName(), BadIntrinsic);
563*03ce13f7SAndroid Build Coastguard Worker if (BadIntrinsic) {
564*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") +
565*03ce13f7SAndroid Build Coastguard Worker LLVMObjectAsString(Instr));
566*03ce13f7SAndroid Build Coastguard Worker }
567*03ce13f7SAndroid Build Coastguard Worker if (Info) {
568*03ce13f7SAndroid Build Coastguard Worker Ice::InstIntrinsic *Intrinsic = Ice::InstIntrinsic::create(
569*03ce13f7SAndroid Build Coastguard Worker Func.get(), NumArgs, Dest, CallTarget, Info->Info);
570*03ce13f7SAndroid Build Coastguard Worker for (unsigned i = 0; i < NumArgs; ++i) {
571*03ce13f7SAndroid Build Coastguard Worker Intrinsic->addArg(convertOperand(Instr, i));
572*03ce13f7SAndroid Build Coastguard Worker }
573*03ce13f7SAndroid Build Coastguard Worker validateIntrinsic(Intrinsic, Info);
574*03ce13f7SAndroid Build Coastguard Worker
575*03ce13f7SAndroid Build Coastguard Worker return Intrinsic;
576*03ce13f7SAndroid Build Coastguard Worker }
577*03ce13f7SAndroid Build Coastguard Worker }
578*03ce13f7SAndroid Build Coastguard Worker
579*03ce13f7SAndroid Build Coastguard Worker // Not an intrinsic.
580*03ce13f7SAndroid Build Coastguard Worker // Note: Subzero doesn't (yet) do anything special with the Tail flag in
581*03ce13f7SAndroid Build Coastguard Worker // the bitcode, i.e. CallInst::isTailCall().
582*03ce13f7SAndroid Build Coastguard Worker Ice::InstCall *Call = Ice::InstCall::create(
583*03ce13f7SAndroid Build Coastguard Worker Func.get(), NumArgs, Dest, CallTarget, Instr->isTailCall());
584*03ce13f7SAndroid Build Coastguard Worker for (unsigned i = 0; i < NumArgs; ++i) {
585*03ce13f7SAndroid Build Coastguard Worker Intrinsic->addArg(convertOperand(Instr, i));
586*03ce13f7SAndroid Build Coastguard Worker }
587*03ce13f7SAndroid Build Coastguard Worker
588*03ce13f7SAndroid Build Coastguard Worker return Call;
589*03ce13f7SAndroid Build Coastguard Worker }
590*03ce13f7SAndroid Build Coastguard Worker
convertAllocaInstruction(const AllocaInst * Instr)591*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertAllocaInstruction(const AllocaInst *Instr) {
592*03ce13f7SAndroid Build Coastguard Worker // PNaCl bitcode only contains allocas of byte-granular objects.
593*03ce13f7SAndroid Build Coastguard Worker Ice::Operand *ByteCount = convertValue(Instr->getArraySize());
594*03ce13f7SAndroid Build Coastguard Worker uint32_t Align = Instr->getAlignment();
595*03ce13f7SAndroid Build Coastguard Worker Ice::Variable *Dest = mapValueToIceVar(Instr, Ice::getPointerType());
596*03ce13f7SAndroid Build Coastguard Worker
597*03ce13f7SAndroid Build Coastguard Worker return Ice::InstAlloca::create(Func.get(), Dest, ByteCount, Align);
598*03ce13f7SAndroid Build Coastguard Worker }
599*03ce13f7SAndroid Build Coastguard Worker
convertUnreachableInstruction(const UnreachableInst *)600*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *convertUnreachableInstruction(const UnreachableInst * /*Instr*/) {
601*03ce13f7SAndroid Build Coastguard Worker return Ice::InstUnreachable::create(Func.get());
602*03ce13f7SAndroid Build Coastguard Worker }
603*03ce13f7SAndroid Build Coastguard Worker
convertBasicBlock(const BasicBlock * BB)604*03ce13f7SAndroid Build Coastguard Worker Ice::CfgNode *convertBasicBlock(const BasicBlock *BB) {
605*03ce13f7SAndroid Build Coastguard Worker Ice::CfgNode *Node = mapBasicBlockToNode(BB);
606*03ce13f7SAndroid Build Coastguard Worker for (const Instruction &II : *BB) {
607*03ce13f7SAndroid Build Coastguard Worker Ice::Inst *Instr = convertInstruction(&II);
608*03ce13f7SAndroid Build Coastguard Worker Node->appendInst(Instr);
609*03ce13f7SAndroid Build Coastguard Worker }
610*03ce13f7SAndroid Build Coastguard Worker return Node;
611*03ce13f7SAndroid Build Coastguard Worker }
612*03ce13f7SAndroid Build Coastguard Worker
validateIntrinsic(const Ice::InstIntrinsic * Intrinsic,const Ice::Intrinsics::FullIntrinsicInfo * I)613*03ce13f7SAndroid Build Coastguard Worker void validateIntrinsic(const Ice::InstIntrinsic *Intrinsic,
614*03ce13f7SAndroid Build Coastguard Worker const Ice::Intrinsics::FullIntrinsicInfo *I) {
615*03ce13f7SAndroid Build Coastguard Worker Ice::SizeT ArgIndex = 0;
616*03ce13f7SAndroid Build Coastguard Worker switch (I->validateCall(Intrinsic, ArgIndex)) {
617*03ce13f7SAndroid Build Coastguard Worker case Ice::Intrinsics::IsValidCall:
618*03ce13f7SAndroid Build Coastguard Worker break;
619*03ce13f7SAndroid Build Coastguard Worker case Ice::Intrinsics::BadReturnType: {
620*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
621*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
622*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Intrinsic call expects return type " << I->getReturnType()
623*03ce13f7SAndroid Build Coastguard Worker << ". Found: " << Intrinsic->getReturnType();
624*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
625*03ce13f7SAndroid Build Coastguard Worker break;
626*03ce13f7SAndroid Build Coastguard Worker }
627*03ce13f7SAndroid Build Coastguard Worker case Ice::Intrinsics::WrongNumOfArgs: {
628*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
629*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
630*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Intrinsic call expects " << I->getNumArgs()
631*03ce13f7SAndroid Build Coastguard Worker << ". Found: " << Intrinsic->getNumArgs();
632*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
633*03ce13f7SAndroid Build Coastguard Worker break;
634*03ce13f7SAndroid Build Coastguard Worker }
635*03ce13f7SAndroid Build Coastguard Worker case Ice::Intrinsics::WrongCallArgType: {
636*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
637*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
638*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Intrinsic call argument " << ArgIndex << " expects type "
639*03ce13f7SAndroid Build Coastguard Worker << I->getArgType(ArgIndex)
640*03ce13f7SAndroid Build Coastguard Worker << ". Found: " << Intrinsic->getArg(ArgIndex)->getType();
641*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
642*03ce13f7SAndroid Build Coastguard Worker break;
643*03ce13f7SAndroid Build Coastguard Worker }
644*03ce13f7SAndroid Build Coastguard Worker }
645*03ce13f7SAndroid Build Coastguard Worker }
646*03ce13f7SAndroid Build Coastguard Worker
647*03ce13f7SAndroid Build Coastguard Worker private:
648*03ce13f7SAndroid Build Coastguard Worker // Data
649*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<Ice::Cfg> Func;
650*03ce13f7SAndroid Build Coastguard Worker std::map<const Value *, Ice::Variable *> VarMap;
651*03ce13f7SAndroid Build Coastguard Worker std::map<const BasicBlock *, Ice::CfgNode *> NodeMap;
652*03ce13f7SAndroid Build Coastguard Worker };
653*03ce13f7SAndroid Build Coastguard Worker
654*03ce13f7SAndroid Build Coastguard Worker // Converter from LLVM global variables to ICE. The entry point is the
655*03ce13f7SAndroid Build Coastguard Worker // convertGlobalsToIce method.
656*03ce13f7SAndroid Build Coastguard Worker //
657*03ce13f7SAndroid Build Coastguard Worker // Note: this currently assumes that the given IR was verified to be valid
658*03ce13f7SAndroid Build Coastguard Worker // PNaCl bitcode. Otherwise, the behavior is undefined.
659*03ce13f7SAndroid Build Coastguard Worker class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter {
660*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEGlobalsConverter() = delete;
661*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEGlobalsConverter(const LLVM2ICEGlobalsConverter &) = delete;
662*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEGlobalsConverter &
663*03ce13f7SAndroid Build Coastguard Worker operator=(const LLVM2ICEGlobalsConverter &) = delete;
664*03ce13f7SAndroid Build Coastguard Worker
665*03ce13f7SAndroid Build Coastguard Worker public:
LLVM2ICEGlobalsConverter(Ice::Converter & Converter,Ice::VariableDeclarationList * G)666*03ce13f7SAndroid Build Coastguard Worker explicit LLVM2ICEGlobalsConverter(Ice::Converter &Converter,
667*03ce13f7SAndroid Build Coastguard Worker Ice::VariableDeclarationList *G)
668*03ce13f7SAndroid Build Coastguard Worker : LLVM2ICEConverter(Converter), GlobalPool(G) {}
669*03ce13f7SAndroid Build Coastguard Worker
670*03ce13f7SAndroid Build Coastguard Worker /// Converts global variables, and their initializers into ICE global variable
671*03ce13f7SAndroid Build Coastguard Worker /// declarations, for module Mod. Returns the set of converted declarations.
672*03ce13f7SAndroid Build Coastguard Worker void convertGlobalsToIce(Module *Mod);
673*03ce13f7SAndroid Build Coastguard Worker
674*03ce13f7SAndroid Build Coastguard Worker private:
675*03ce13f7SAndroid Build Coastguard Worker // Adds the Initializer to the list of initializers for the Global variable
676*03ce13f7SAndroid Build Coastguard Worker // declaration.
addGlobalInitializer(Ice::VariableDeclaration & Global,const Constant * Initializer)677*03ce13f7SAndroid Build Coastguard Worker void addGlobalInitializer(Ice::VariableDeclaration &Global,
678*03ce13f7SAndroid Build Coastguard Worker const Constant *Initializer) {
679*03ce13f7SAndroid Build Coastguard Worker constexpr bool HasOffset = false;
680*03ce13f7SAndroid Build Coastguard Worker constexpr Ice::RelocOffsetT Offset = 0;
681*03ce13f7SAndroid Build Coastguard Worker addGlobalInitializer(Global, Initializer, HasOffset, Offset);
682*03ce13f7SAndroid Build Coastguard Worker }
683*03ce13f7SAndroid Build Coastguard Worker
684*03ce13f7SAndroid Build Coastguard Worker // Adds Initializer to the list of initializers for Global variable
685*03ce13f7SAndroid Build Coastguard Worker // declaration. HasOffset is true only if Initializer is a relocation
686*03ce13f7SAndroid Build Coastguard Worker // initializer and Offset should be added to the relocation.
687*03ce13f7SAndroid Build Coastguard Worker void addGlobalInitializer(Ice::VariableDeclaration &Global,
688*03ce13f7SAndroid Build Coastguard Worker const Constant *Initializer, bool HasOffset,
689*03ce13f7SAndroid Build Coastguard Worker Ice::RelocOffsetT Offset);
690*03ce13f7SAndroid Build Coastguard Worker
691*03ce13f7SAndroid Build Coastguard Worker // Converts the given constant C to the corresponding integer literal it
692*03ce13f7SAndroid Build Coastguard Worker // contains.
getIntegerLiteralConstant(const Value * C)693*03ce13f7SAndroid Build Coastguard Worker Ice::RelocOffsetT getIntegerLiteralConstant(const Value *C) {
694*03ce13f7SAndroid Build Coastguard Worker const auto CI = dyn_cast<ConstantInt>(C);
695*03ce13f7SAndroid Build Coastguard Worker if (CI && CI->getType()->isIntegerTy(32))
696*03ce13f7SAndroid Build Coastguard Worker return CI->getSExtValue();
697*03ce13f7SAndroid Build Coastguard Worker
698*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
699*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
700*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Constant not i32 literal: " << *C;
701*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
702*03ce13f7SAndroid Build Coastguard Worker return 0;
703*03ce13f7SAndroid Build Coastguard Worker }
704*03ce13f7SAndroid Build Coastguard Worker
705*03ce13f7SAndroid Build Coastguard Worker Ice::VariableDeclarationList *GlobalPool;
706*03ce13f7SAndroid Build Coastguard Worker };
707*03ce13f7SAndroid Build Coastguard Worker
convertGlobalsToIce(Module * Mod)708*03ce13f7SAndroid Build Coastguard Worker void LLVM2ICEGlobalsConverter::convertGlobalsToIce(Module *Mod) {
709*03ce13f7SAndroid Build Coastguard Worker for (Module::const_global_iterator I = Mod->global_begin(),
710*03ce13f7SAndroid Build Coastguard Worker E = Mod->global_end();
711*03ce13f7SAndroid Build Coastguard Worker I != E; ++I) {
712*03ce13f7SAndroid Build Coastguard Worker
713*03ce13f7SAndroid Build Coastguard Worker const GlobalVariable *GV = &*I;
714*03ce13f7SAndroid Build Coastguard Worker
715*03ce13f7SAndroid Build Coastguard Worker Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV);
716*03ce13f7SAndroid Build Coastguard Worker auto *VarDecl = cast<Ice::VariableDeclaration>(Var);
717*03ce13f7SAndroid Build Coastguard Worker GlobalPool->push_back(VarDecl);
718*03ce13f7SAndroid Build Coastguard Worker
719*03ce13f7SAndroid Build Coastguard Worker if (!GV->hasInternalLinkage() && GV->hasInitializer()) {
720*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
721*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
722*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Can't define external global declaration: " << GV->getName();
723*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
724*03ce13f7SAndroid Build Coastguard Worker }
725*03ce13f7SAndroid Build Coastguard Worker
726*03ce13f7SAndroid Build Coastguard Worker if (!GV->hasInitializer()) {
727*03ce13f7SAndroid Build Coastguard Worker if (Ice::getFlags().getAllowUninitializedGlobals())
728*03ce13f7SAndroid Build Coastguard Worker continue;
729*03ce13f7SAndroid Build Coastguard Worker else {
730*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
731*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
732*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Global declaration missing initializer: " << GV->getName();
733*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
734*03ce13f7SAndroid Build Coastguard Worker }
735*03ce13f7SAndroid Build Coastguard Worker }
736*03ce13f7SAndroid Build Coastguard Worker
737*03ce13f7SAndroid Build Coastguard Worker const Constant *Initializer = GV->getInitializer();
738*03ce13f7SAndroid Build Coastguard Worker if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) {
739*03ce13f7SAndroid Build Coastguard Worker for (ConstantStruct::const_op_iterator I = CompoundInit->op_begin(),
740*03ce13f7SAndroid Build Coastguard Worker E = CompoundInit->op_end();
741*03ce13f7SAndroid Build Coastguard Worker I != E; ++I) {
742*03ce13f7SAndroid Build Coastguard Worker if (const auto Init = dyn_cast<Constant>(I)) {
743*03ce13f7SAndroid Build Coastguard Worker addGlobalInitializer(*VarDecl, Init);
744*03ce13f7SAndroid Build Coastguard Worker }
745*03ce13f7SAndroid Build Coastguard Worker }
746*03ce13f7SAndroid Build Coastguard Worker } else {
747*03ce13f7SAndroid Build Coastguard Worker addGlobalInitializer(*VarDecl, Initializer);
748*03ce13f7SAndroid Build Coastguard Worker }
749*03ce13f7SAndroid Build Coastguard Worker }
750*03ce13f7SAndroid Build Coastguard Worker }
751*03ce13f7SAndroid Build Coastguard Worker
addGlobalInitializer(Ice::VariableDeclaration & Global,const Constant * Initializer,bool HasOffset,Ice::RelocOffsetT Offset)752*03ce13f7SAndroid Build Coastguard Worker void LLVM2ICEGlobalsConverter::addGlobalInitializer(
753*03ce13f7SAndroid Build Coastguard Worker Ice::VariableDeclaration &Global, const Constant *Initializer,
754*03ce13f7SAndroid Build Coastguard Worker bool HasOffset, Ice::RelocOffsetT Offset) {
755*03ce13f7SAndroid Build Coastguard Worker (void)HasOffset;
756*03ce13f7SAndroid Build Coastguard Worker assert(HasOffset || Offset == 0);
757*03ce13f7SAndroid Build Coastguard Worker
758*03ce13f7SAndroid Build Coastguard Worker if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) {
759*03ce13f7SAndroid Build Coastguard Worker assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) &&
760*03ce13f7SAndroid Build Coastguard Worker (cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8));
761*03ce13f7SAndroid Build Coastguard Worker Global.addInitializer(Ice::VariableDeclaration::DataInitializer::create(
762*03ce13f7SAndroid Build Coastguard Worker GlobalPool, CDA->getRawDataValues().data(), CDA->getNumElements()));
763*03ce13f7SAndroid Build Coastguard Worker return;
764*03ce13f7SAndroid Build Coastguard Worker }
765*03ce13f7SAndroid Build Coastguard Worker
766*03ce13f7SAndroid Build Coastguard Worker if (isa<ConstantAggregateZero>(Initializer)) {
767*03ce13f7SAndroid Build Coastguard Worker if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) {
768*03ce13f7SAndroid Build Coastguard Worker assert(!HasOffset && isa<IntegerType>(AT->getElementType()) &&
769*03ce13f7SAndroid Build Coastguard Worker (cast<IntegerType>(AT->getElementType())->getBitWidth() == 8));
770*03ce13f7SAndroid Build Coastguard Worker Global.addInitializer(Ice::VariableDeclaration::ZeroInitializer::create(
771*03ce13f7SAndroid Build Coastguard Worker GlobalPool, AT->getNumElements()));
772*03ce13f7SAndroid Build Coastguard Worker } else {
773*03ce13f7SAndroid Build Coastguard Worker llvm_unreachable("Unhandled constant aggregate zero type");
774*03ce13f7SAndroid Build Coastguard Worker }
775*03ce13f7SAndroid Build Coastguard Worker return;
776*03ce13f7SAndroid Build Coastguard Worker }
777*03ce13f7SAndroid Build Coastguard Worker
778*03ce13f7SAndroid Build Coastguard Worker if (const auto Exp = dyn_cast<ConstantExpr>(Initializer)) {
779*03ce13f7SAndroid Build Coastguard Worker switch (Exp->getOpcode()) {
780*03ce13f7SAndroid Build Coastguard Worker case Instruction::Add:
781*03ce13f7SAndroid Build Coastguard Worker assert(!HasOffset);
782*03ce13f7SAndroid Build Coastguard Worker addGlobalInitializer(Global, Exp->getOperand(0), true,
783*03ce13f7SAndroid Build Coastguard Worker getIntegerLiteralConstant(Exp->getOperand(1)));
784*03ce13f7SAndroid Build Coastguard Worker return;
785*03ce13f7SAndroid Build Coastguard Worker case Instruction::PtrToInt: {
786*03ce13f7SAndroid Build Coastguard Worker assert(TypeConverter.convertToIceType(Exp->getType()) ==
787*03ce13f7SAndroid Build Coastguard Worker Ice::getPointerType());
788*03ce13f7SAndroid Build Coastguard Worker const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0));
789*03ce13f7SAndroid Build Coastguard Worker assert(GV);
790*03ce13f7SAndroid Build Coastguard Worker const Ice::GlobalDeclaration *Addr =
791*03ce13f7SAndroid Build Coastguard Worker getConverter().getGlobalDeclaration(GV);
792*03ce13f7SAndroid Build Coastguard Worker Global.addInitializer(Ice::VariableDeclaration::RelocInitializer::create(
793*03ce13f7SAndroid Build Coastguard Worker GlobalPool, Addr, {Ice::RelocOffset::create(Ctx, Offset)}));
794*03ce13f7SAndroid Build Coastguard Worker return;
795*03ce13f7SAndroid Build Coastguard Worker }
796*03ce13f7SAndroid Build Coastguard Worker default:
797*03ce13f7SAndroid Build Coastguard Worker break;
798*03ce13f7SAndroid Build Coastguard Worker }
799*03ce13f7SAndroid Build Coastguard Worker }
800*03ce13f7SAndroid Build Coastguard Worker
801*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
802*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
803*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Unhandled global initializer: " << Initializer;
804*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
805*03ce13f7SAndroid Build Coastguard Worker }
806*03ce13f7SAndroid Build Coastguard Worker
807*03ce13f7SAndroid Build Coastguard Worker } // end of anonymous namespace
808*03ce13f7SAndroid Build Coastguard Worker
809*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
810*03ce13f7SAndroid Build Coastguard Worker
nameUnnamedGlobalVariables(Module * Mod)811*03ce13f7SAndroid Build Coastguard Worker void Converter::nameUnnamedGlobalVariables(Module *Mod) {
812*03ce13f7SAndroid Build Coastguard Worker const std::string GlobalPrefix = getFlags().getDefaultGlobalPrefix();
813*03ce13f7SAndroid Build Coastguard Worker if (GlobalPrefix.empty())
814*03ce13f7SAndroid Build Coastguard Worker return;
815*03ce13f7SAndroid Build Coastguard Worker uint32_t NameIndex = 0;
816*03ce13f7SAndroid Build Coastguard Worker for (auto V = Mod->global_begin(), E = Mod->global_end(); V != E; ++V) {
817*03ce13f7SAndroid Build Coastguard Worker if (!V->hasName()) {
818*03ce13f7SAndroid Build Coastguard Worker V->setName(createUnnamedName(GlobalPrefix, NameIndex));
819*03ce13f7SAndroid Build Coastguard Worker ++NameIndex;
820*03ce13f7SAndroid Build Coastguard Worker } else {
821*03ce13f7SAndroid Build Coastguard Worker checkIfUnnamedNameSafe(V->getName(), "global", GlobalPrefix);
822*03ce13f7SAndroid Build Coastguard Worker }
823*03ce13f7SAndroid Build Coastguard Worker }
824*03ce13f7SAndroid Build Coastguard Worker }
825*03ce13f7SAndroid Build Coastguard Worker
nameUnnamedFunctions(Module * Mod)826*03ce13f7SAndroid Build Coastguard Worker void Converter::nameUnnamedFunctions(Module *Mod) {
827*03ce13f7SAndroid Build Coastguard Worker const std::string FunctionPrefix = getFlags().getDefaultFunctionPrefix();
828*03ce13f7SAndroid Build Coastguard Worker if (FunctionPrefix.empty())
829*03ce13f7SAndroid Build Coastguard Worker return;
830*03ce13f7SAndroid Build Coastguard Worker uint32_t NameIndex = 0;
831*03ce13f7SAndroid Build Coastguard Worker for (Function &F : *Mod) {
832*03ce13f7SAndroid Build Coastguard Worker if (!F.hasName()) {
833*03ce13f7SAndroid Build Coastguard Worker F.setName(createUnnamedName(FunctionPrefix, NameIndex));
834*03ce13f7SAndroid Build Coastguard Worker ++NameIndex;
835*03ce13f7SAndroid Build Coastguard Worker } else {
836*03ce13f7SAndroid Build Coastguard Worker checkIfUnnamedNameSafe(F.getName(), "function", FunctionPrefix);
837*03ce13f7SAndroid Build Coastguard Worker }
838*03ce13f7SAndroid Build Coastguard Worker }
839*03ce13f7SAndroid Build Coastguard Worker }
840*03ce13f7SAndroid Build Coastguard Worker
convertToIce()841*03ce13f7SAndroid Build Coastguard Worker void Converter::convertToIce() {
842*03ce13f7SAndroid Build Coastguard Worker TimerMarker T(TimerStack::TT_convertToIce, Ctx);
843*03ce13f7SAndroid Build Coastguard Worker nameUnnamedGlobalVariables(Mod);
844*03ce13f7SAndroid Build Coastguard Worker nameUnnamedFunctions(Mod);
845*03ce13f7SAndroid Build Coastguard Worker installGlobalDeclarations(Mod);
846*03ce13f7SAndroid Build Coastguard Worker convertGlobals(Mod);
847*03ce13f7SAndroid Build Coastguard Worker convertFunctions();
848*03ce13f7SAndroid Build Coastguard Worker }
849*03ce13f7SAndroid Build Coastguard Worker
getGlobalDeclaration(const GlobalValue * V)850*03ce13f7SAndroid Build Coastguard Worker GlobalDeclaration *Converter::getGlobalDeclaration(const GlobalValue *V) {
851*03ce13f7SAndroid Build Coastguard Worker GlobalDeclarationMapType::const_iterator Pos = GlobalDeclarationMap.find(V);
852*03ce13f7SAndroid Build Coastguard Worker if (Pos == GlobalDeclarationMap.end()) {
853*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
854*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
855*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Can't find global declaration for: " << V->getName();
856*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
857*03ce13f7SAndroid Build Coastguard Worker }
858*03ce13f7SAndroid Build Coastguard Worker return Pos->second;
859*03ce13f7SAndroid Build Coastguard Worker }
860*03ce13f7SAndroid Build Coastguard Worker
installGlobalDeclarations(Module * Mod)861*03ce13f7SAndroid Build Coastguard Worker void Converter::installGlobalDeclarations(Module *Mod) {
862*03ce13f7SAndroid Build Coastguard Worker const TypeConverter Converter(Mod->getContext());
863*03ce13f7SAndroid Build Coastguard Worker // Install function declarations.
864*03ce13f7SAndroid Build Coastguard Worker for (const Function &Func : *Mod) {
865*03ce13f7SAndroid Build Coastguard Worker FuncSigType Signature;
866*03ce13f7SAndroid Build Coastguard Worker FunctionType *FuncType = Func.getFunctionType();
867*03ce13f7SAndroid Build Coastguard Worker Signature.setReturnType(
868*03ce13f7SAndroid Build Coastguard Worker Converter.convertToIceType(FuncType->getReturnType()));
869*03ce13f7SAndroid Build Coastguard Worker for (size_t I = 0; I < FuncType->getNumParams(); ++I) {
870*03ce13f7SAndroid Build Coastguard Worker Signature.appendArgType(
871*03ce13f7SAndroid Build Coastguard Worker Converter.convertToIceType(FuncType->getParamType(I)));
872*03ce13f7SAndroid Build Coastguard Worker }
873*03ce13f7SAndroid Build Coastguard Worker auto *IceFunc = FunctionDeclaration::create(
874*03ce13f7SAndroid Build Coastguard Worker Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty());
875*03ce13f7SAndroid Build Coastguard Worker IceFunc->setName(Ctx, Func.getName());
876*03ce13f7SAndroid Build Coastguard Worker if (!IceFunc->verifyLinkageCorrect(Ctx)) {
877*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
878*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
879*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Function " << IceFunc->getName()
880*03ce13f7SAndroid Build Coastguard Worker << " has incorrect linkage: " << IceFunc->getLinkageName();
881*03ce13f7SAndroid Build Coastguard Worker if (IceFunc->isExternal())
882*03ce13f7SAndroid Build Coastguard Worker StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
883*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
884*03ce13f7SAndroid Build Coastguard Worker }
885*03ce13f7SAndroid Build Coastguard Worker if (!IceFunc->validateTypeSignature(Ctx))
886*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(IceFunc->getTypeSignatureError(Ctx));
887*03ce13f7SAndroid Build Coastguard Worker GlobalDeclarationMap[&Func] = IceFunc;
888*03ce13f7SAndroid Build Coastguard Worker }
889*03ce13f7SAndroid Build Coastguard Worker // Install global variable declarations.
890*03ce13f7SAndroid Build Coastguard Worker for (Module::const_global_iterator I = Mod->global_begin(),
891*03ce13f7SAndroid Build Coastguard Worker E = Mod->global_end();
892*03ce13f7SAndroid Build Coastguard Worker I != E; ++I) {
893*03ce13f7SAndroid Build Coastguard Worker const GlobalVariable *GV = &*I;
894*03ce13f7SAndroid Build Coastguard Worker constexpr bool NoSuppressMangling = false;
895*03ce13f7SAndroid Build Coastguard Worker auto *Var = VariableDeclaration::create(
896*03ce13f7SAndroid Build Coastguard Worker GlobalDeclarationsPool.get(), NoSuppressMangling, GV->getLinkage());
897*03ce13f7SAndroid Build Coastguard Worker Var->setAlignment(GV->getAlignment());
898*03ce13f7SAndroid Build Coastguard Worker Var->setIsConstant(GV->isConstant());
899*03ce13f7SAndroid Build Coastguard Worker Var->setName(Ctx, GV->getName());
900*03ce13f7SAndroid Build Coastguard Worker if (!Var->verifyLinkageCorrect()) {
901*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
902*03ce13f7SAndroid Build Coastguard Worker raw_string_ostream StrBuf(Buffer);
903*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Global " << Var->getName()
904*03ce13f7SAndroid Build Coastguard Worker << " has incorrect linkage: " << Var->getLinkageName();
905*03ce13f7SAndroid Build Coastguard Worker if (Var->isExternal())
906*03ce13f7SAndroid Build Coastguard Worker StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
907*03ce13f7SAndroid Build Coastguard Worker report_fatal_error(StrBuf.str());
908*03ce13f7SAndroid Build Coastguard Worker }
909*03ce13f7SAndroid Build Coastguard Worker GlobalDeclarationMap[GV] = Var;
910*03ce13f7SAndroid Build Coastguard Worker }
911*03ce13f7SAndroid Build Coastguard Worker }
912*03ce13f7SAndroid Build Coastguard Worker
convertGlobals(Module * Mod)913*03ce13f7SAndroid Build Coastguard Worker void Converter::convertGlobals(Module *Mod) {
914*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEGlobalsConverter(*this, GlobalDeclarationsPool.get())
915*03ce13f7SAndroid Build Coastguard Worker .convertGlobalsToIce(Mod);
916*03ce13f7SAndroid Build Coastguard Worker lowerGlobals(std::move(GlobalDeclarationsPool));
917*03ce13f7SAndroid Build Coastguard Worker }
918*03ce13f7SAndroid Build Coastguard Worker
convertFunctions()919*03ce13f7SAndroid Build Coastguard Worker void Converter::convertFunctions() {
920*03ce13f7SAndroid Build Coastguard Worker for (const Function &I : *Mod) {
921*03ce13f7SAndroid Build Coastguard Worker if (I.empty())
922*03ce13f7SAndroid Build Coastguard Worker continue;
923*03ce13f7SAndroid Build Coastguard Worker TimerMarker _(Ctx, I.getName());
924*03ce13f7SAndroid Build Coastguard Worker LLVM2ICEFunctionConverter FunctionConverter(*this);
925*03ce13f7SAndroid Build Coastguard Worker FunctionConverter.convertFunction(&I);
926*03ce13f7SAndroid Build Coastguard Worker }
927*03ce13f7SAndroid Build Coastguard Worker }
928*03ce13f7SAndroid Build Coastguard Worker
929*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
930