• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "IceTypes.h"
28 #include "IceTypeConverter.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     // Note: Subzero doesn't (yet) do anything special with the Tail flag in
558     // the bitcode, i.e. CallInst::isTailCall().
559     Ice::InstCall *NewInst = nullptr;
560     const Ice::Intrinsics::FullIntrinsicInfo *Info = nullptr;
561 
562     if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) {
563       // Check if this direct call is to an Intrinsic (starts with "llvm.")
564       bool BadIntrinsic;
565       Info = Ctx->getIntrinsicsInfo().find(Target->getName(), BadIntrinsic);
566       if (BadIntrinsic) {
567         report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") +
568                            LLVMObjectAsString(Instr));
569       }
570       if (Info)
571         NewInst = Ice::InstIntrinsicCall::create(Func.get(), NumArgs, Dest,
572                                                  CallTarget, Info->Info);
573     }
574 
575     // Not an intrinsic call.
576     if (NewInst == nullptr) {
577       NewInst = Ice::InstCall::create(Func.get(), NumArgs, Dest, CallTarget,
578                                       Instr->isTailCall());
579     }
580     for (unsigned i = 0; i < NumArgs; ++i) {
581       NewInst->addArg(convertOperand(Instr, i));
582     }
583     if (Info) {
584       validateIntrinsicCall(NewInst, Info);
585     }
586     return NewInst;
587   }
588 
convertAllocaInstruction(const AllocaInst * Instr)589   Ice::Inst *convertAllocaInstruction(const AllocaInst *Instr) {
590     // PNaCl bitcode only contains allocas of byte-granular objects.
591     Ice::Operand *ByteCount = convertValue(Instr->getArraySize());
592     uint32_t Align = Instr->getAlignment();
593     Ice::Variable *Dest = mapValueToIceVar(Instr, Ice::getPointerType());
594 
595     return Ice::InstAlloca::create(Func.get(), Dest, ByteCount, Align);
596   }
597 
convertUnreachableInstruction(const UnreachableInst *)598   Ice::Inst *convertUnreachableInstruction(const UnreachableInst * /*Instr*/) {
599     return Ice::InstUnreachable::create(Func.get());
600   }
601 
convertBasicBlock(const BasicBlock * BB)602   Ice::CfgNode *convertBasicBlock(const BasicBlock *BB) {
603     Ice::CfgNode *Node = mapBasicBlockToNode(BB);
604     for (const Instruction &II : *BB) {
605       Ice::Inst *Instr = convertInstruction(&II);
606       Node->appendInst(Instr);
607     }
608     return Node;
609   }
610 
validateIntrinsicCall(const Ice::InstCall * Call,const Ice::Intrinsics::FullIntrinsicInfo * I)611   void validateIntrinsicCall(const Ice::InstCall *Call,
612                              const Ice::Intrinsics::FullIntrinsicInfo *I) {
613     Ice::SizeT ArgIndex = 0;
614     switch (I->validateCall(Call, ArgIndex)) {
615     case Ice::Intrinsics::IsValidCall:
616       break;
617     case Ice::Intrinsics::BadReturnType: {
618       std::string Buffer;
619       raw_string_ostream StrBuf(Buffer);
620       StrBuf << "Intrinsic call expects return type " << I->getReturnType()
621              << ". Found: " << Call->getReturnType();
622       report_fatal_error(StrBuf.str());
623       break;
624     }
625     case Ice::Intrinsics::WrongNumOfArgs: {
626       std::string Buffer;
627       raw_string_ostream StrBuf(Buffer);
628       StrBuf << "Intrinsic call expects " << I->getNumArgs()
629              << ". Found: " << Call->getNumArgs();
630       report_fatal_error(StrBuf.str());
631       break;
632     }
633     case Ice::Intrinsics::WrongCallArgType: {
634       std::string Buffer;
635       raw_string_ostream StrBuf(Buffer);
636       StrBuf << "Intrinsic call argument " << ArgIndex << " expects type "
637              << I->getArgType(ArgIndex)
638              << ". Found: " << Call->getArg(ArgIndex)->getType();
639       report_fatal_error(StrBuf.str());
640       break;
641     }
642     }
643   }
644 
645 private:
646   // Data
647   std::unique_ptr<Ice::Cfg> Func;
648   std::map<const Value *, Ice::Variable *> VarMap;
649   std::map<const BasicBlock *, Ice::CfgNode *> NodeMap;
650 };
651 
652 // Converter from LLVM global variables to ICE. The entry point is the
653 // convertGlobalsToIce method.
654 //
655 // Note: this currently assumes that the given IR was verified to be valid
656 // PNaCl bitcode. Otherwise, the behavior is undefined.
657 class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter {
658   LLVM2ICEGlobalsConverter() = delete;
659   LLVM2ICEGlobalsConverter(const LLVM2ICEGlobalsConverter &) = delete;
660   LLVM2ICEGlobalsConverter &
661   operator=(const LLVM2ICEGlobalsConverter &) = delete;
662 
663 public:
LLVM2ICEGlobalsConverter(Ice::Converter & Converter,Ice::VariableDeclarationList * G)664   explicit LLVM2ICEGlobalsConverter(Ice::Converter &Converter,
665                                     Ice::VariableDeclarationList *G)
666       : LLVM2ICEConverter(Converter), GlobalPool(G) {}
667 
668   /// Converts global variables, and their initializers into ICE global variable
669   /// declarations, for module Mod. Returns the set of converted declarations.
670   void convertGlobalsToIce(Module *Mod);
671 
672 private:
673   // Adds the Initializer to the list of initializers for the Global variable
674   // declaration.
addGlobalInitializer(Ice::VariableDeclaration & Global,const Constant * Initializer)675   void addGlobalInitializer(Ice::VariableDeclaration &Global,
676                             const Constant *Initializer) {
677     constexpr bool HasOffset = false;
678     constexpr Ice::RelocOffsetT Offset = 0;
679     addGlobalInitializer(Global, Initializer, HasOffset, Offset);
680   }
681 
682   // Adds Initializer to the list of initializers for Global variable
683   // declaration. HasOffset is true only if Initializer is a relocation
684   // initializer and Offset should be added to the relocation.
685   void addGlobalInitializer(Ice::VariableDeclaration &Global,
686                             const Constant *Initializer, bool HasOffset,
687                             Ice::RelocOffsetT Offset);
688 
689   // Converts the given constant C to the corresponding integer literal it
690   // contains.
getIntegerLiteralConstant(const Value * C)691   Ice::RelocOffsetT getIntegerLiteralConstant(const Value *C) {
692     const auto CI = dyn_cast<ConstantInt>(C);
693     if (CI && CI->getType()->isIntegerTy(32))
694       return CI->getSExtValue();
695 
696     std::string Buffer;
697     raw_string_ostream StrBuf(Buffer);
698     StrBuf << "Constant not i32 literal: " << *C;
699     report_fatal_error(StrBuf.str());
700     return 0;
701   }
702 
703   Ice::VariableDeclarationList *GlobalPool;
704 };
705 
convertGlobalsToIce(Module * Mod)706 void LLVM2ICEGlobalsConverter::convertGlobalsToIce(Module *Mod) {
707   for (Module::const_global_iterator I = Mod->global_begin(),
708                                      E = Mod->global_end();
709        I != E; ++I) {
710 
711     const GlobalVariable *GV = &*I;
712 
713     Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV);
714     auto *VarDecl = cast<Ice::VariableDeclaration>(Var);
715     GlobalPool->push_back(VarDecl);
716 
717     if (!GV->hasInternalLinkage() && GV->hasInitializer()) {
718       std::string Buffer;
719       raw_string_ostream StrBuf(Buffer);
720       StrBuf << "Can't define external global declaration: " << GV->getName();
721       report_fatal_error(StrBuf.str());
722     }
723 
724     if (!GV->hasInitializer()) {
725       if (Ice::getFlags().getAllowUninitializedGlobals())
726         continue;
727       else {
728         std::string Buffer;
729         raw_string_ostream StrBuf(Buffer);
730         StrBuf << "Global declaration missing initializer: " << GV->getName();
731         report_fatal_error(StrBuf.str());
732       }
733     }
734 
735     const Constant *Initializer = GV->getInitializer();
736     if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) {
737       for (ConstantStruct::const_op_iterator I = CompoundInit->op_begin(),
738                                              E = CompoundInit->op_end();
739            I != E; ++I) {
740         if (const auto Init = dyn_cast<Constant>(I)) {
741           addGlobalInitializer(*VarDecl, Init);
742         }
743       }
744     } else {
745       addGlobalInitializer(*VarDecl, Initializer);
746     }
747   }
748 }
749 
addGlobalInitializer(Ice::VariableDeclaration & Global,const Constant * Initializer,bool HasOffset,Ice::RelocOffsetT Offset)750 void LLVM2ICEGlobalsConverter::addGlobalInitializer(
751     Ice::VariableDeclaration &Global, const Constant *Initializer,
752     bool HasOffset, Ice::RelocOffsetT Offset) {
753   (void)HasOffset;
754   assert(HasOffset || Offset == 0);
755 
756   if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) {
757     assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) &&
758            (cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8));
759     Global.addInitializer(Ice::VariableDeclaration::DataInitializer::create(
760         GlobalPool, CDA->getRawDataValues().data(), CDA->getNumElements()));
761     return;
762   }
763 
764   if (isa<ConstantAggregateZero>(Initializer)) {
765     if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) {
766       assert(!HasOffset && isa<IntegerType>(AT->getElementType()) &&
767              (cast<IntegerType>(AT->getElementType())->getBitWidth() == 8));
768       Global.addInitializer(Ice::VariableDeclaration::ZeroInitializer::create(
769           GlobalPool, AT->getNumElements()));
770     } else {
771       llvm_unreachable("Unhandled constant aggregate zero type");
772     }
773     return;
774   }
775 
776   if (const auto Exp = dyn_cast<ConstantExpr>(Initializer)) {
777     switch (Exp->getOpcode()) {
778     case Instruction::Add:
779       assert(!HasOffset);
780       addGlobalInitializer(Global, Exp->getOperand(0), true,
781                            getIntegerLiteralConstant(Exp->getOperand(1)));
782       return;
783     case Instruction::PtrToInt: {
784       assert(TypeConverter.convertToIceType(Exp->getType()) ==
785              Ice::getPointerType());
786       const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0));
787       assert(GV);
788       const Ice::GlobalDeclaration *Addr =
789           getConverter().getGlobalDeclaration(GV);
790       Global.addInitializer(Ice::VariableDeclaration::RelocInitializer::create(
791           GlobalPool, Addr, {Ice::RelocOffset::create(Ctx, Offset)}));
792       return;
793     }
794     default:
795       break;
796     }
797   }
798 
799   std::string Buffer;
800   raw_string_ostream StrBuf(Buffer);
801   StrBuf << "Unhandled global initializer: " << Initializer;
802   report_fatal_error(StrBuf.str());
803 }
804 
805 } // end of anonymous namespace
806 
807 namespace Ice {
808 
nameUnnamedGlobalVariables(Module * Mod)809 void Converter::nameUnnamedGlobalVariables(Module *Mod) {
810   const std::string GlobalPrefix = getFlags().getDefaultGlobalPrefix();
811   if (GlobalPrefix.empty())
812     return;
813   uint32_t NameIndex = 0;
814   for (auto V = Mod->global_begin(), E = Mod->global_end(); V != E; ++V) {
815     if (!V->hasName()) {
816       V->setName(createUnnamedName(GlobalPrefix, NameIndex));
817       ++NameIndex;
818     } else {
819       checkIfUnnamedNameSafe(V->getName(), "global", GlobalPrefix);
820     }
821   }
822 }
823 
nameUnnamedFunctions(Module * Mod)824 void Converter::nameUnnamedFunctions(Module *Mod) {
825   const std::string FunctionPrefix = getFlags().getDefaultFunctionPrefix();
826   if (FunctionPrefix.empty())
827     return;
828   uint32_t NameIndex = 0;
829   for (Function &F : *Mod) {
830     if (!F.hasName()) {
831       F.setName(createUnnamedName(FunctionPrefix, NameIndex));
832       ++NameIndex;
833     } else {
834       checkIfUnnamedNameSafe(F.getName(), "function", FunctionPrefix);
835     }
836   }
837 }
838 
convertToIce()839 void Converter::convertToIce() {
840   TimerMarker T(TimerStack::TT_convertToIce, Ctx);
841   nameUnnamedGlobalVariables(Mod);
842   nameUnnamedFunctions(Mod);
843   installGlobalDeclarations(Mod);
844   convertGlobals(Mod);
845   convertFunctions();
846 }
847 
getGlobalDeclaration(const GlobalValue * V)848 GlobalDeclaration *Converter::getGlobalDeclaration(const GlobalValue *V) {
849   GlobalDeclarationMapType::const_iterator Pos = GlobalDeclarationMap.find(V);
850   if (Pos == GlobalDeclarationMap.end()) {
851     std::string Buffer;
852     raw_string_ostream StrBuf(Buffer);
853     StrBuf << "Can't find global declaration for: " << V->getName();
854     report_fatal_error(StrBuf.str());
855   }
856   return Pos->second;
857 }
858 
installGlobalDeclarations(Module * Mod)859 void Converter::installGlobalDeclarations(Module *Mod) {
860   const TypeConverter Converter(Mod->getContext());
861   // Install function declarations.
862   for (const Function &Func : *Mod) {
863     FuncSigType Signature;
864     FunctionType *FuncType = Func.getFunctionType();
865     Signature.setReturnType(
866         Converter.convertToIceType(FuncType->getReturnType()));
867     for (size_t I = 0; I < FuncType->getNumParams(); ++I) {
868       Signature.appendArgType(
869           Converter.convertToIceType(FuncType->getParamType(I)));
870     }
871     auto *IceFunc = FunctionDeclaration::create(
872         Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty());
873     IceFunc->setName(Ctx, Func.getName());
874     if (!IceFunc->verifyLinkageCorrect(Ctx)) {
875       std::string Buffer;
876       raw_string_ostream StrBuf(Buffer);
877       StrBuf << "Function " << IceFunc->getName()
878              << " has incorrect linkage: " << IceFunc->getLinkageName();
879       if (IceFunc->isExternal())
880         StrBuf << "\n  Use flag -allow-externally-defined-symbols to override";
881       report_fatal_error(StrBuf.str());
882     }
883     if (!IceFunc->validateTypeSignature(Ctx))
884       report_fatal_error(IceFunc->getTypeSignatureError(Ctx));
885     GlobalDeclarationMap[&Func] = IceFunc;
886   }
887   // Install global variable declarations.
888   for (Module::const_global_iterator I = Mod->global_begin(),
889                                      E = Mod->global_end();
890        I != E; ++I) {
891     const GlobalVariable *GV = &*I;
892     constexpr bool NoSuppressMangling = false;
893     auto *Var = VariableDeclaration::create(
894         GlobalDeclarationsPool.get(), NoSuppressMangling, GV->getLinkage());
895     Var->setAlignment(GV->getAlignment());
896     Var->setIsConstant(GV->isConstant());
897     Var->setName(Ctx, GV->getName());
898     if (!Var->verifyLinkageCorrect()) {
899       std::string Buffer;
900       raw_string_ostream StrBuf(Buffer);
901       StrBuf << "Global " << Var->getName()
902              << " has incorrect linkage: " << Var->getLinkageName();
903       if (Var->isExternal())
904         StrBuf << "\n  Use flag -allow-externally-defined-symbols to override";
905       report_fatal_error(StrBuf.str());
906     }
907     GlobalDeclarationMap[GV] = Var;
908   }
909 }
910 
convertGlobals(Module * Mod)911 void Converter::convertGlobals(Module *Mod) {
912   LLVM2ICEGlobalsConverter(*this, GlobalDeclarationsPool.get())
913       .convertGlobalsToIce(Mod);
914   lowerGlobals(std::move(GlobalDeclarationsPool));
915 }
916 
convertFunctions()917 void Converter::convertFunctions() {
918   for (const Function &I : *Mod) {
919     if (I.empty())
920       continue;
921     TimerMarker _(Ctx, I.getName());
922     LLVM2ICEFunctionConverter FunctionConverter(*this);
923     FunctionConverter.convertFunction(&I);
924   }
925 }
926 
927 } // end of namespace Ice
928