xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceConverter.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 //===- 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 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief Implements the LLVM to ICE converter.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "IceConverter.h"
16 
17 #include "IceCfg.h"
18 #include "IceCfgNode.h"
19 #include "IceClFlags.h"
20 #include "IceDefs.h"
21 #include "IceGlobalContext.h"
22 #include "IceGlobalInits.h"
23 #include "IceInst.h"
24 #include "IceMangling.h"
25 #include "IceOperand.h"
26 #include "IceTargetLowering.h"
27 #include "IceTypeConverter.h"
28 #include "IceTypes.h"
29 
30 #ifdef __clang__
31 #pragma clang diagnostic push
32 #pragma clang diagnostic ignored "-Wunused-parameter"
33 #endif // __clang__
34 
35 #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"
42 
43 #ifdef __clang__
44 #pragma clang diagnostic pop
45 #endif // __clang__
46 
47 // TODO(kschimpf): Remove two namespaces being visible at once.
48 using namespace llvm;
49 
50 namespace {
51 
52 // Debugging helper
LLVMObjectAsString(const T * O)53 template <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 
60 // Base class for converting LLVM to ICE.
61 // TODO(stichnot): Redesign Converter, LLVM2ICEConverter,
62 // LLVM2ICEFunctionConverter, and LLVM2ICEGlobalsConverter with respect to
63 // Translator.  In particular, the unique_ptr ownership rules in
64 // LLVM2ICEFunctionConverter.
65 class LLVM2ICEConverter {
66   LLVM2ICEConverter() = delete;
67   LLVM2ICEConverter(const LLVM2ICEConverter &) = delete;
68   LLVM2ICEConverter &operator=(const LLVM2ICEConverter &) = delete;
69 
70 public:
LLVM2ICEConverter(Ice::Converter & Converter)71   explicit LLVM2ICEConverter(Ice::Converter &Converter)
72       : Converter(Converter), Ctx(Converter.getContext()),
73         TypeConverter(Converter.getModule()->getContext()) {}
74 
getConverter() const75   Ice::Converter &getConverter() const { return Converter; }
76 
77 protected:
78   Ice::Converter &Converter;
79   Ice::GlobalContext *Ctx;
80   const Ice::TypeConverter TypeConverter;
81 };
82 
83 // Converter from LLVM functions to ICE. The entry point is the convertFunction
84 // method.
85 //
86 // Note: this currently assumes that the given IR was verified to be valid
87 // PNaCl bitcode. Otherwise, the behavior is undefined.
88 class LLVM2ICEFunctionConverter : LLVM2ICEConverter {
89   LLVM2ICEFunctionConverter() = delete;
90   LLVM2ICEFunctionConverter(const LLVM2ICEFunctionConverter &) = delete;
91   LLVM2ICEFunctionConverter &
92   operator=(const LLVM2ICEFunctionConverter &) = delete;
93 
94 public:
LLVM2ICEFunctionConverter(Ice::Converter & Converter)95   explicit LLVM2ICEFunctionConverter(Ice::Converter &Converter)
96       : LLVM2ICEConverter(Converter), Func(nullptr) {}
97 
convertFunction(const Function * F)98   void convertFunction(const Function *F) {
99     Func = Ice::Cfg::create(Ctx, Converter.getNextSequenceNumber());
100     {
101       Ice::CfgLocalAllocatorScope _(Func.get());
102 
103       VarMap.clear();
104       NodeMap.clear();
105       Func->setFunctionName(
106           Ctx->getGlobalString(Ice::mangleName(F->getName())));
107       Func->setReturnType(convertToIceType(F->getReturnType()));
108       Func->setInternal(F->hasInternalLinkage());
109       Ice::TimerMarker T(Ice::TimerStack::TT_llvmConvert, Func.get());
110 
111       // 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) {
114         Func->addArg(mapValueToIceVar(&*ArgI));
115       }
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();
126     }
127     Converter.translateFcn(std::move(Func));
128   }
129 
130   // 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.
convertConstant(const Constant * Const)132   Ice::Constant *convertConstant(const Constant *Const) {
133     if (const auto GV = dyn_cast<GlobalValue>(Const)) {
134       Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV);
135       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;
146         return Ctx->getConstantSym(
147             Offset, Ctx->getGlobalString(Decl->getName().toString()));
148       }
149     } else if (const auto CI = dyn_cast<ConstantInt>(Const)) {
150       Ice::Type Ty = convertToIceType(CI->getType());
151       return Ctx->getConstantInt(Ty, CI->getSExtValue());
152     } else if (const auto CFP = dyn_cast<ConstantFP>(Const)) {
153       Ice::Type Type = convertToIceType(CFP->getType());
154       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");
159       return nullptr;
160     } else if (const auto CU = dyn_cast<UndefValue>(Const)) {
161       return Ctx->getConstantUndef(convertToIceType(CU->getType()));
162     } else {
163       llvm_unreachable("Unhandled constant type");
164       return nullptr;
165     }
166   }
167 
168 private:
169   // LLVM values (instructions, etc.) are mapped directly to ICE variables.
170   // mapValueToIceVar has a version that forces an ICE type on the variable,
171   // and a version that just uses convertToIceType on V.
mapValueToIceVar(const Value * V,Ice::Type IceTy)172   Ice::Variable *mapValueToIceVar(const Value *V, Ice::Type IceTy) {
173     if (IceTy == Ice::IceType_void)
174       return nullptr;
175     if (VarMap.find(V) == VarMap.end()) {
176       VarMap[V] = Func->makeVariable(IceTy);
177       if (Ice::BuildDefs::dump())
178         VarMap[V]->setName(Func.get(), V->getName());
179     }
180     return VarMap[V];
181   }
182 
mapValueToIceVar(const Value * V)183   Ice::Variable *mapValueToIceVar(const Value *V) {
184     return mapValueToIceVar(V, convertToIceType(V->getType()));
185   }
186 
mapBasicBlockToNode(const BasicBlock * BB)187   Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) {
188     if (NodeMap.find(BB) == NodeMap.end()) {
189       NodeMap[BB] = Func->makeNode();
190       if (Ice::BuildDefs::dump())
191         NodeMap[BB]->setName(BB->getName());
192     }
193     return NodeMap[BB];
194   }
195 
convertToIceType(Type * LLVMTy) const196   Ice::Type convertToIceType(Type *LLVMTy) const {
197     Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy);
198     if (IceTy == Ice::IceType_NUM)
199       report_fatal_error(std::string("Invalid PNaCl type ") +
200                          LLVMObjectAsString(LLVMTy));
201     return IceTy;
202   }
203 
204   // Given an LLVM instruction and an operand number, produce the Ice::Operand
205   // this refers to. If there's no such operand, return nullptr.
convertOperand(const Instruction * Instr,unsigned OpNum)206   Ice::Operand *convertOperand(const Instruction *Instr, unsigned OpNum) {
207     if (OpNum >= Instr->getNumOperands()) {
208       return nullptr;
209     }
210     const Value *Op = Instr->getOperand(OpNum);
211     return convertValue(Op);
212   }
213 
convertValue(const Value * Op)214   Ice::Operand *convertValue(const Value *Op) {
215     if (const auto Const = dyn_cast<Constant>(Op)) {
216       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.
convertInstruction(const Instruction * Instr)224   Ice::Inst *convertInstruction(const Instruction *Instr) {
225     switch (Instr->getOpcode()) {
226     case Instruction::PHI:
227       return convertPHINodeInstruction(cast<PHINode>(Instr));
228     case Instruction::Br:
229       return convertBrInstruction(cast<BranchInst>(Instr));
230     case Instruction::Ret:
231       return convertRetInstruction(cast<ReturnInst>(Instr));
232     case Instruction::IntToPtr:
233       return convertIntToPtrInstruction(cast<IntToPtrInst>(Instr));
234     case Instruction::PtrToInt:
235       return convertPtrToIntInstruction(cast<PtrToIntInst>(Instr));
236     case Instruction::ICmp:
237       return convertICmpInstruction(cast<ICmpInst>(Instr));
238     case Instruction::FCmp:
239       return convertFCmpInstruction(cast<FCmpInst>(Instr));
240     case Instruction::Select:
241       return convertSelectInstruction(cast<SelectInst>(Instr));
242     case Instruction::Switch:
243       return convertSwitchInstruction(cast<SwitchInst>(Instr));
244     case Instruction::Load:
245       return convertLoadInstruction(cast<LoadInst>(Instr));
246     case Instruction::Store:
247       return convertStoreInstruction(cast<StoreInst>(Instr));
248     case Instruction::ZExt:
249       return convertCastInstruction(cast<ZExtInst>(Instr), Ice::InstCast::Zext);
250     case Instruction::SExt:
251       return convertCastInstruction(cast<SExtInst>(Instr), Ice::InstCast::Sext);
252     case Instruction::Trunc:
253       return convertCastInstruction(cast<TruncInst>(Instr),
254                                     Ice::InstCast::Trunc);
255     case Instruction::FPTrunc:
256       return convertCastInstruction(cast<FPTruncInst>(Instr),
257                                     Ice::InstCast::Fptrunc);
258     case Instruction::FPExt:
259       return convertCastInstruction(cast<FPExtInst>(Instr),
260                                     Ice::InstCast::Fpext);
261     case Instruction::FPToSI:
262       return convertCastInstruction(cast<FPToSIInst>(Instr),
263                                     Ice::InstCast::Fptosi);
264     case Instruction::FPToUI:
265       return convertCastInstruction(cast<FPToUIInst>(Instr),
266                                     Ice::InstCast::Fptoui);
267     case Instruction::SIToFP:
268       return convertCastInstruction(cast<SIToFPInst>(Instr),
269                                     Ice::InstCast::Sitofp);
270     case Instruction::UIToFP:
271       return convertCastInstruction(cast<UIToFPInst>(Instr),
272                                     Ice::InstCast::Uitofp);
273     case Instruction::BitCast:
274       return convertCastInstruction(cast<BitCastInst>(Instr),
275                                     Ice::InstCast::Bitcast);
276     case Instruction::Add:
277       return convertArithInstruction(Instr, Ice::InstArithmetic::Add);
278     case Instruction::Sub:
279       return convertArithInstruction(Instr, Ice::InstArithmetic::Sub);
280     case Instruction::Mul:
281       return convertArithInstruction(Instr, Ice::InstArithmetic::Mul);
282     case Instruction::UDiv:
283       return convertArithInstruction(Instr, Ice::InstArithmetic::Udiv);
284     case Instruction::SDiv:
285       return convertArithInstruction(Instr, Ice::InstArithmetic::Sdiv);
286     case Instruction::URem:
287       return convertArithInstruction(Instr, Ice::InstArithmetic::Urem);
288     case Instruction::SRem:
289       return convertArithInstruction(Instr, Ice::InstArithmetic::Srem);
290     case Instruction::Shl:
291       return convertArithInstruction(Instr, Ice::InstArithmetic::Shl);
292     case Instruction::LShr:
293       return convertArithInstruction(Instr, Ice::InstArithmetic::Lshr);
294     case Instruction::AShr:
295       return convertArithInstruction(Instr, Ice::InstArithmetic::Ashr);
296     case Instruction::FAdd:
297       return convertArithInstruction(Instr, Ice::InstArithmetic::Fadd);
298     case Instruction::FSub:
299       return convertArithInstruction(Instr, Ice::InstArithmetic::Fsub);
300     case Instruction::FMul:
301       return convertArithInstruction(Instr, Ice::InstArithmetic::Fmul);
302     case Instruction::FDiv:
303       return convertArithInstruction(Instr, Ice::InstArithmetic::Fdiv);
304     case Instruction::FRem:
305       return convertArithInstruction(Instr, Ice::InstArithmetic::Frem);
306     case Instruction::And:
307       return convertArithInstruction(Instr, Ice::InstArithmetic::And);
308     case Instruction::Or:
309       return convertArithInstruction(Instr, Ice::InstArithmetic::Or);
310     case Instruction::Xor:
311       return convertArithInstruction(Instr, Ice::InstArithmetic::Xor);
312     case Instruction::ExtractElement:
313       return convertExtractElementInstruction(cast<ExtractElementInst>(Instr));
314     case Instruction::InsertElement:
315       return convertInsertElementInstruction(cast<InsertElementInst>(Instr));
316     case Instruction::Call:
317       return convertCallInstruction(cast<CallInst>(Instr));
318     case Instruction::Alloca:
319       return convertAllocaInstruction(cast<AllocaInst>(Instr));
320     case Instruction::Unreachable:
321       return convertUnreachableInstruction(cast<UnreachableInst>(Instr));
322     default:
323       report_fatal_error(std::string("Invalid PNaCl instruction: ") +
324                          LLVMObjectAsString(Instr));
325     }
326 
327     llvm_unreachable("convertInstruction");
328     return nullptr;
329   }
330 
convertLoadInstruction(const LoadInst * Instr)331   Ice::Inst *convertLoadInstruction(const LoadInst *Instr) {
332     Ice::Operand *Src = convertOperand(Instr, 0);
333     Ice::Variable *Dest = mapValueToIceVar(Instr);
334     return Ice::InstLoad::create(Func.get(), Dest, Src);
335   }
336 
convertStoreInstruction(const StoreInst * Instr)337   Ice::Inst *convertStoreInstruction(const StoreInst *Instr) {
338     Ice::Operand *Addr = convertOperand(Instr, 1);
339     Ice::Operand *Val = convertOperand(Instr, 0);
340     return Ice::InstStore::create(Func.get(), Val, Addr);
341   }
342 
convertArithInstruction(const Instruction * Instr,Ice::InstArithmetic::OpKind Opcode)343   Ice::Inst *convertArithInstruction(const Instruction *Instr,
344                                      Ice::InstArithmetic::OpKind Opcode) {
345     const auto BinOp = cast<BinaryOperator>(Instr);
346     Ice::Operand *Src0 = convertOperand(Instr, 0);
347     Ice::Operand *Src1 = convertOperand(Instr, 1);
348     Ice::Variable *Dest = mapValueToIceVar(BinOp);
349     return Ice::InstArithmetic::create(Func.get(), Opcode, Dest, Src0, Src1);
350   }
351 
convertPHINodeInstruction(const PHINode * Instr)352   Ice::Inst *convertPHINodeInstruction(const PHINode *Instr) {
353     unsigned NumValues = Instr->getNumIncomingValues();
354     Ice::InstPhi *IcePhi =
355         Ice::InstPhi::create(Func.get(), NumValues, mapValueToIceVar(Instr));
356     for (unsigned N = 0, E = NumValues; N != E; ++N) {
357       IcePhi->addArgument(convertOperand(Instr, N),
358                           mapBasicBlockToNode(Instr->getIncomingBlock(N)));
359     }
360     return IcePhi;
361   }
362 
convertBrInstruction(const BranchInst * Instr)363   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);
368       Ice::CfgNode *NodeThen = mapBasicBlockToNode(BBThen);
369       Ice::CfgNode *NodeElse = mapBasicBlockToNode(BBElse);
370       return Ice::InstBr::create(Func.get(), Src, NodeThen, NodeElse);
371     } else {
372       BasicBlock *BBSucc = Instr->getSuccessor(0);
373       return Ice::InstBr::create(Func.get(), mapBasicBlockToNode(BBSucc));
374     }
375   }
376 
convertIntToPtrInstruction(const IntToPtrInst * Instr)377   Ice::Inst *convertIntToPtrInstruction(const IntToPtrInst *Instr) {
378     Ice::Operand *Src = convertOperand(Instr, 0);
379     Ice::Variable *Dest = mapValueToIceVar(Instr, Ice::getPointerType());
380     return Ice::InstAssign::create(Func.get(), Dest, Src);
381   }
382 
convertPtrToIntInstruction(const PtrToIntInst * Instr)383   Ice::Inst *convertPtrToIntInstruction(const PtrToIntInst *Instr) {
384     Ice::Operand *Src = convertOperand(Instr, 0);
385     Ice::Variable *Dest = mapValueToIceVar(Instr);
386     return Ice::InstAssign::create(Func.get(), Dest, Src);
387   }
388 
convertRetInstruction(const ReturnInst * Instr)389   Ice::Inst *convertRetInstruction(const ReturnInst *Instr) {
390     Ice::Operand *RetOperand = convertOperand(Instr, 0);
391     if (RetOperand) {
392       return Ice::InstRet::create(Func.get(), RetOperand);
393     } else {
394       return Ice::InstRet::create(Func.get());
395     }
396   }
397 
convertCastInstruction(const Instruction * Instr,Ice::InstCast::OpKind CastKind)398   Ice::Inst *convertCastInstruction(const Instruction *Instr,
399                                     Ice::InstCast::OpKind CastKind) {
400     Ice::Operand *Src = convertOperand(Instr, 0);
401     Ice::Variable *Dest = mapValueToIceVar(Instr);
402     return Ice::InstCast::create(Func.get(), CastKind, Dest, Src);
403   }
404 
convertICmpInstruction(const ICmpInst * Instr)405   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);
409 
410     Ice::InstIcmp::ICond Cond;
411     switch (Instr->getPredicate()) {
412     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 
446     return Ice::InstIcmp::create(Func.get(), Cond, Dest, Src0, Src1);
447   }
448 
convertFCmpInstruction(const FCmpInst * Instr)449   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);
453 
454     Ice::InstFcmp::FCond Cond;
455     switch (Instr->getPredicate()) {
456 
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 
510     return Ice::InstFcmp::create(Func.get(), Cond, Dest, Src0, Src1);
511   }
512 
convertExtractElementInstruction(const ExtractElementInst * Instr)513   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));
517     return Ice::InstExtractElement::create(Func.get(), Dest, Source1, Source2);
518   }
519 
convertInsertElementInstruction(const InsertElementInst * Instr)520   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));
525     return Ice::InstInsertElement::create(Func.get(), Dest, Source1, Source2,
526                                           Source3);
527   }
528 
convertSelectInstruction(const SelectInst * Instr)529   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());
534     return Ice::InstSelect::create(Func.get(), Dest, Cond, Source1, Source2);
535   }
536 
convertSwitchInstruction(const SwitchInst * Instr)537   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();
541     Ice::InstSwitch *Switch =
542         Ice::InstSwitch::create(Func.get(), NumCases, Source, LabelDefault);
543     unsigned CurrentCase = 0;
544     for (SwitchInst::ConstCaseIt I = Instr->case_begin(), E = Instr->case_end();
545          I != E; ++I, ++CurrentCase) {
546       uint64_t CaseValue = I.getCaseValue()->getSExtValue();
547       Ice::CfgNode *CaseSuccessor = mapBasicBlockToNode(I.getCaseSuccessor());
548       Switch->addBranch(CurrentCase, CaseValue, CaseSuccessor);
549     }
550     return Switch;
551   }
552 
convertCallInstruction(const CallInst * Instr)553   Ice::Inst *convertCallInstruction(const CallInst *Instr) {
554     Ice::Variable *Dest = mapValueToIceVar(Instr);
555     Ice::Operand *CallTarget = convertValue(Instr->getCalledValue());
556     unsigned NumArgs = Instr->getNumArgOperands();
557 
558     if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) {
559       // Check if this direct call is to an Intrinsic (starts with "llvm.")
560       bool BadIntrinsic;
561       const Ice::Intrinsics::FullIntrinsicInfo *Info =
562           Ctx->getIntrinsicsInfo().find(Target->getName(), BadIntrinsic);
563       if (BadIntrinsic) {
564         report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") +
565                            LLVMObjectAsString(Instr));
566       }
567       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       }
577     }
578 
579     // 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());
584     for (unsigned i = 0; i < NumArgs; ++i) {
585       Intrinsic->addArg(convertOperand(Instr, i));
586     }
587 
588     return Call;
589   }
590 
convertAllocaInstruction(const AllocaInst * Instr)591   Ice::Inst *convertAllocaInstruction(const AllocaInst *Instr) {
592     // PNaCl bitcode only contains allocas of byte-granular objects.
593     Ice::Operand *ByteCount = convertValue(Instr->getArraySize());
594     uint32_t Align = Instr->getAlignment();
595     Ice::Variable *Dest = mapValueToIceVar(Instr, Ice::getPointerType());
596 
597     return Ice::InstAlloca::create(Func.get(), Dest, ByteCount, Align);
598   }
599 
convertUnreachableInstruction(const UnreachableInst *)600   Ice::Inst *convertUnreachableInstruction(const UnreachableInst * /*Instr*/) {
601     return Ice::InstUnreachable::create(Func.get());
602   }
603 
convertBasicBlock(const BasicBlock * BB)604   Ice::CfgNode *convertBasicBlock(const BasicBlock *BB) {
605     Ice::CfgNode *Node = mapBasicBlockToNode(BB);
606     for (const Instruction &II : *BB) {
607       Ice::Inst *Instr = convertInstruction(&II);
608       Node->appendInst(Instr);
609     }
610     return Node;
611   }
612 
validateIntrinsic(const Ice::InstIntrinsic * Intrinsic,const Ice::Intrinsics::FullIntrinsicInfo * I)613   void validateIntrinsic(const Ice::InstIntrinsic *Intrinsic,
614                          const Ice::Intrinsics::FullIntrinsicInfo *I) {
615     Ice::SizeT ArgIndex = 0;
616     switch (I->validateCall(Intrinsic, ArgIndex)) {
617     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()
623              << ". Found: " << Intrinsic->getReturnType();
624       report_fatal_error(StrBuf.str());
625       break;
626     }
627     case Ice::Intrinsics::WrongNumOfArgs: {
628       std::string Buffer;
629       raw_string_ostream StrBuf(Buffer);
630       StrBuf << "Intrinsic call expects " << I->getNumArgs()
631              << ". Found: " << Intrinsic->getNumArgs();
632       report_fatal_error(StrBuf.str());
633       break;
634     }
635     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)
640              << ". Found: " << Intrinsic->getArg(ArgIndex)->getType();
641       report_fatal_error(StrBuf.str());
642       break;
643     }
644     }
645   }
646 
647 private:
648   // Data
649   std::unique_ptr<Ice::Cfg> Func;
650   std::map<const Value *, Ice::Variable *> VarMap;
651   std::map<const BasicBlock *, Ice::CfgNode *> NodeMap;
652 };
653 
654 // Converter from LLVM global variables to ICE. The entry point is the
655 // convertGlobalsToIce method.
656 //
657 // Note: this currently assumes that the given IR was verified to be valid
658 // PNaCl bitcode. Otherwise, the behavior is undefined.
659 class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter {
660   LLVM2ICEGlobalsConverter() = delete;
661   LLVM2ICEGlobalsConverter(const LLVM2ICEGlobalsConverter &) = delete;
662   LLVM2ICEGlobalsConverter &
663   operator=(const LLVM2ICEGlobalsConverter &) = delete;
664 
665 public:
LLVM2ICEGlobalsConverter(Ice::Converter & Converter,Ice::VariableDeclarationList * G)666   explicit LLVM2ICEGlobalsConverter(Ice::Converter &Converter,
667                                     Ice::VariableDeclarationList *G)
668       : LLVM2ICEConverter(Converter), GlobalPool(G) {}
669 
670   /// Converts global variables, and their initializers into ICE global variable
671   /// declarations, for module Mod. Returns the set of converted declarations.
672   void convertGlobalsToIce(Module *Mod);
673 
674 private:
675   // Adds the Initializer to the list of initializers for the Global variable
676   // declaration.
addGlobalInitializer(Ice::VariableDeclaration & Global,const Constant * Initializer)677   void addGlobalInitializer(Ice::VariableDeclaration &Global,
678                             const Constant *Initializer) {
679     constexpr bool HasOffset = false;
680     constexpr Ice::RelocOffsetT Offset = 0;
681     addGlobalInitializer(Global, Initializer, HasOffset, Offset);
682   }
683 
684   // Adds Initializer to the list of initializers for Global variable
685   // declaration. HasOffset is true only if Initializer is a relocation
686   // initializer and Offset should be added to the relocation.
687   void addGlobalInitializer(Ice::VariableDeclaration &Global,
688                             const Constant *Initializer, bool HasOffset,
689                             Ice::RelocOffsetT Offset);
690 
691   // Converts the given constant C to the corresponding integer literal it
692   // contains.
getIntegerLiteralConstant(const Value * C)693   Ice::RelocOffsetT getIntegerLiteralConstant(const Value *C) {
694     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   }
704 
705   Ice::VariableDeclarationList *GlobalPool;
706 };
707 
convertGlobalsToIce(Module * Mod)708 void LLVM2ICEGlobalsConverter::convertGlobalsToIce(Module *Mod) {
709   for (Module::const_global_iterator I = Mod->global_begin(),
710                                      E = Mod->global_end();
711        I != E; ++I) {
712 
713     const GlobalVariable *GV = &*I;
714 
715     Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV);
716     auto *VarDecl = cast<Ice::VariableDeclaration>(Var);
717     GlobalPool->push_back(VarDecl);
718 
719     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()) {
727       if (Ice::getFlags().getAllowUninitializedGlobals())
728         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 
737     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)) {
743           addGlobalInitializer(*VarDecl, Init);
744         }
745       }
746     } else {
747       addGlobalInitializer(*VarDecl, Initializer);
748     }
749   }
750 }
751 
addGlobalInitializer(Ice::VariableDeclaration & Global,const Constant * Initializer,bool HasOffset,Ice::RelocOffsetT Offset)752 void LLVM2ICEGlobalsConverter::addGlobalInitializer(
753     Ice::VariableDeclaration &Global, const Constant *Initializer,
754     bool HasOffset, Ice::RelocOffsetT Offset) {
755   (void)HasOffset;
756   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));
761     Global.addInitializer(Ice::VariableDeclaration::DataInitializer::create(
762         GlobalPool, CDA->getRawDataValues().data(), CDA->getNumElements()));
763     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));
770       Global.addInitializer(Ice::VariableDeclaration::ZeroInitializer::create(
771           GlobalPool, AT->getNumElements()));
772     } 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()) ==
787              Ice::getPointerType());
788       const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0));
789       assert(GV);
790       const Ice::GlobalDeclaration *Addr =
791           getConverter().getGlobalDeclaration(GV);
792       Global.addInitializer(Ice::VariableDeclaration::RelocInitializer::create(
793           GlobalPool, Addr, {Ice::RelocOffset::create(Ctx, Offset)}));
794       return;
795     }
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 
807 } // end of anonymous namespace
808 
809 namespace Ice {
810 
nameUnnamedGlobalVariables(Module * Mod)811 void Converter::nameUnnamedGlobalVariables(Module *Mod) {
812   const std::string GlobalPrefix = getFlags().getDefaultGlobalPrefix();
813   if (GlobalPrefix.empty())
814     return;
815   uint32_t NameIndex = 0;
816   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 {
821       checkIfUnnamedNameSafe(V->getName(), "global", GlobalPrefix);
822     }
823   }
824 }
825 
nameUnnamedFunctions(Module * Mod)826 void Converter::nameUnnamedFunctions(Module *Mod) {
827   const std::string FunctionPrefix = getFlags().getDefaultFunctionPrefix();
828   if (FunctionPrefix.empty())
829     return;
830   uint32_t NameIndex = 0;
831   for (Function &F : *Mod) {
832     if (!F.hasName()) {
833       F.setName(createUnnamedName(FunctionPrefix, NameIndex));
834       ++NameIndex;
835     } else {
836       checkIfUnnamedNameSafe(F.getName(), "function", FunctionPrefix);
837     }
838   }
839 }
840 
convertToIce()841 void Converter::convertToIce() {
842   TimerMarker T(TimerStack::TT_convertToIce, Ctx);
843   nameUnnamedGlobalVariables(Mod);
844   nameUnnamedFunctions(Mod);
845   installGlobalDeclarations(Mod);
846   convertGlobals(Mod);
847   convertFunctions();
848 }
849 
getGlobalDeclaration(const GlobalValue * V)850 GlobalDeclaration *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 
installGlobalDeclarations(Module * Mod)861 void 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     }
873     auto *IceFunc = FunctionDeclaration::create(
874         Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty());
875     IceFunc->setName(Ctx, Func.getName());
876     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();
881       if (IceFunc->isExternal())
882         StrBuf << "\n  Use flag -allow-externally-defined-symbols to override";
883       report_fatal_error(StrBuf.str());
884     }
885     if (!IceFunc->validateTypeSignature(Ctx))
886       report_fatal_error(IceFunc->getTypeSignatureError(Ctx));
887     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) {
893     const GlobalVariable *GV = &*I;
894     constexpr bool NoSuppressMangling = false;
895     auto *Var = VariableDeclaration::create(
896         GlobalDeclarationsPool.get(), NoSuppressMangling, GV->getLinkage());
897     Var->setAlignment(GV->getAlignment());
898     Var->setIsConstant(GV->isConstant());
899     Var->setName(Ctx, GV->getName());
900     if (!Var->verifyLinkageCorrect()) {
901       std::string Buffer;
902       raw_string_ostream StrBuf(Buffer);
903       StrBuf << "Global " << Var->getName()
904              << " has incorrect linkage: " << Var->getLinkageName();
905       if (Var->isExternal())
906         StrBuf << "\n  Use flag -allow-externally-defined-symbols to override";
907       report_fatal_error(StrBuf.str());
908     }
909     GlobalDeclarationMap[GV] = Var;
910   }
911 }
912 
convertGlobals(Module * Mod)913 void Converter::convertGlobals(Module *Mod) {
914   LLVM2ICEGlobalsConverter(*this, GlobalDeclarationsPool.get())
915       .convertGlobalsToIce(Mod);
916   lowerGlobals(std::move(GlobalDeclarationsPool));
917 }
918 
convertFunctions()919 void Converter::convertFunctions() {
920   for (const Function &I : *Mod) {
921     if (I.empty())
922       continue;
923     TimerMarker _(Ctx, I.getName());
924     LLVM2ICEFunctionConverter FunctionConverter(*this);
925     FunctionConverter.convertFunction(&I);
926   }
927 }
928 
929 } // end of namespace Ice
930