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