OLD | NEW |
---|---|
1 //===- subzero/src/llvm2ice.cpp - Driver for testing ----------------------===// | 1 //===- subzero/src/llvm2ice.cpp - Driver for testing ----------------------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines a driver that uses LLVM capabilities to parse a | 10 // This file defines a driver that uses LLVM capabilities to parse a |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 return SubzeroPointerType; | 158 return SubzeroPointerType; |
159 default: | 159 default: |
160 report_fatal_error(std::string("Invalid PNaCl type: ") + | 160 report_fatal_error(std::string("Invalid PNaCl type: ") + |
161 LLVMObjectAsString(Ty)); | 161 LLVMObjectAsString(Ty)); |
162 } | 162 } |
163 | 163 |
164 llvm_unreachable("convertType"); | 164 llvm_unreachable("convertType"); |
165 return Ice::IceType_void; | 165 return Ice::IceType_void; |
166 } | 166 } |
167 | 167 |
168 // Given a LLVM instruction and an operand number, produce the Operand this | 168 // Given an LLVM instruction and an operand number, produce the |
169 // refers to. If there's no such operand, return NULL. | 169 // Ice::Operand this refers to. If there's no such operand, return |
170 // NULL. | |
170 Ice::Operand *convertOperand(const Instruction *Inst, unsigned OpNum) { | 171 Ice::Operand *convertOperand(const Instruction *Inst, unsigned OpNum) { |
171 if (OpNum >= Inst->getNumOperands()) { | 172 if (OpNum >= Inst->getNumOperands()) { |
172 return NULL; | 173 return NULL; |
173 } | 174 } |
174 const Value *Op = Inst->getOperand(OpNum); | 175 const Value *Op = Inst->getOperand(OpNum); |
175 return convertValue(Op); | 176 return convertValue(Op); |
176 } | 177 } |
177 | 178 |
178 Ice::Operand *convertValue(const Value *Op) { | 179 Ice::Operand *convertValue(const Value *Op) { |
179 if (const Constant *Const = dyn_cast<Constant>(Op)) { | 180 if (const Constant *Const = dyn_cast<Constant>(Op)) { |
180 if (const GlobalValue *GV = dyn_cast<GlobalValue>(Const)) { | 181 if (const GlobalValue *GV = dyn_cast<GlobalValue>(Const)) { |
181 return Ctx->getConstantSym(convertType(GV->getType()), 0, | 182 return Ctx->getConstantSym(convertType(GV->getType()), 0, |
182 GV->getName()); | 183 GV->getName()); |
183 } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(Const)) { | 184 } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(Const)) { |
184 return Ctx->getConstantInt(convertIntegerType(CI->getType()), | 185 return Ctx->getConstantInt(convertIntegerType(CI->getType()), |
185 CI->getZExtValue()); | 186 CI->getZExtValue()); |
186 } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Const)) { | 187 } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Const)) { |
187 Ice::Type Type = convertType(CFP->getType()); | 188 Ice::Type Type = convertType(CFP->getType()); |
188 if (Type == Ice::IceType_f32) | 189 if (Type == Ice::IceType_f32) |
189 return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat()); | 190 return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat()); |
190 else if (Type == Ice::IceType_f64) | 191 else if (Type == Ice::IceType_f64) |
191 return Ctx->getConstantDouble(CFP->getValueAPF().convertToDouble()); | 192 return Ctx->getConstantDouble(CFP->getValueAPF().convertToDouble()); |
192 assert(0 && "Unexpected floating point type"); | 193 llvm_unreachable("Unexpected floating point type"); |
193 return NULL; | 194 return NULL; |
194 } else { | 195 } else { |
195 assert(0 && "Unhandled constant type"); | 196 llvm_unreachable("Unhandled constant type"); |
196 return NULL; | 197 return NULL; |
197 } | 198 } |
198 } else { | 199 } else { |
199 return mapValueToIceVar(Op); | 200 return mapValueToIceVar(Op); |
200 } | 201 } |
201 } | 202 } |
202 | 203 |
203 // Note: this currently assumes a 1x1 mapping between LLVM IR and Ice | 204 // Note: this currently assumes a 1x1 mapping between LLVM IR and Ice |
204 // instructions. | 205 // instructions. |
205 Ice::Inst *convertInstruction(const Instruction *Inst) { | 206 Ice::Inst *convertInstruction(const Instruction *Inst) { |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 | 528 |
528 Ice::Inst *convertAllocaInstruction(const AllocaInst *Inst) { | 529 Ice::Inst *convertAllocaInstruction(const AllocaInst *Inst) { |
529 // PNaCl bitcode only contains allocas of byte-granular objects. | 530 // PNaCl bitcode only contains allocas of byte-granular objects. |
530 Ice::Operand *ByteCount = convertValue(Inst->getArraySize()); | 531 Ice::Operand *ByteCount = convertValue(Inst->getArraySize()); |
531 uint32_t Align = Inst->getAlignment(); | 532 uint32_t Align = Inst->getAlignment(); |
532 Ice::Variable *Dest = mapValueToIceVar(Inst, SubzeroPointerType); | 533 Ice::Variable *Dest = mapValueToIceVar(Inst, SubzeroPointerType); |
533 | 534 |
534 return Ice::InstAlloca::create(Func, ByteCount, Align, Dest); | 535 return Ice::InstAlloca::create(Func, ByteCount, Align, Dest); |
535 } | 536 } |
536 | 537 |
537 Ice::Inst *convertUnreachableInstruction(const UnreachableInst *Inst) { | 538 Ice::Inst *convertUnreachableInstruction(const UnreachableInst * /*Inst*/) { |
538 return Ice::InstUnreachable::create(Func); | 539 return Ice::InstUnreachable::create(Func); |
539 } | 540 } |
540 | 541 |
541 Ice::CfgNode *convertBasicBlock(const BasicBlock *BB) { | 542 Ice::CfgNode *convertBasicBlock(const BasicBlock *BB) { |
542 Ice::CfgNode *Node = mapBasicBlockToNode(BB); | 543 Ice::CfgNode *Node = mapBasicBlockToNode(BB); |
543 for (BasicBlock::const_iterator II = BB->begin(), II_e = BB->end(); | 544 for (BasicBlock::const_iterator II = BB->begin(), II_e = BB->end(); |
544 II != II_e; ++II) { | 545 II != II_e; ++II) { |
545 Ice::Inst *Inst = convertInstruction(II); | 546 Ice::Inst *Inst = convertInstruction(II); |
546 Node->appendInst(Inst); | 547 Node->appendInst(Inst); |
547 } | 548 } |
(...skipping 21 matching lines...) Expand all Loading... | |
569 clEnumValN(Ice::IceV_Preds, "pred", "Show predecessors"), | 570 clEnumValN(Ice::IceV_Preds, "pred", "Show predecessors"), |
570 clEnumValN(Ice::IceV_Succs, "succ", "Show successors"), | 571 clEnumValN(Ice::IceV_Succs, "succ", "Show successors"), |
571 clEnumValN(Ice::IceV_Liveness, "live", "Liveness information"), | 572 clEnumValN(Ice::IceV_Liveness, "live", "Liveness information"), |
572 clEnumValN(Ice::IceV_RegManager, "rmgr", "Register manager status"), | 573 clEnumValN(Ice::IceV_RegManager, "rmgr", "Register manager status"), |
573 clEnumValN(Ice::IceV_RegOrigins, "orig", "Physical register origins"), | 574 clEnumValN(Ice::IceV_RegOrigins, "orig", "Physical register origins"), |
574 clEnumValN(Ice::IceV_LinearScan, "regalloc", "Linear scan details"), | 575 clEnumValN(Ice::IceV_LinearScan, "regalloc", "Linear scan details"), |
575 clEnumValN(Ice::IceV_Frame, "frame", "Stack frame layout details"), | 576 clEnumValN(Ice::IceV_Frame, "frame", "Stack frame layout details"), |
576 clEnumValN(Ice::IceV_Timing, "time", "Pass timing details"), | 577 clEnumValN(Ice::IceV_Timing, "time", "Pass timing details"), |
577 clEnumValN(Ice::IceV_All, "all", "Use all verbose options"), | 578 clEnumValN(Ice::IceV_All, "all", "Use all verbose options"), |
578 clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd)); | 579 clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd)); |
580 static cl::opt<Ice::TargetArch> TargetArch( | |
581 "target", cl::desc("Target architecture:"), cl::init(Ice::Target_X8632), | |
582 cl::values( | |
583 clEnumValN(Ice::Target_X8632, "x8632", "x86-32"), | |
584 clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"), | |
585 clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"), | |
586 clEnumValN(Ice::Target_X8664, "x8664", "x86-64"), | |
587 clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"), | |
588 clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"), | |
589 clEnumValN(Ice::Target_ARM32, "arm", "arm32"), | |
590 clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"), | |
591 clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd)); | |
592 static cl::opt<Ice::OptLevel> | |
593 OptLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1), | |
594 cl::value_desc("level"), | |
595 cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"), | |
596 clEnumValN(Ice::Opt_m1, "O-1", "-1"), | |
597 clEnumValN(Ice::Opt_0, "O0", "0"), | |
598 clEnumValN(Ice::Opt_0, "O1", "1"), | |
jvoung (off chromium)
2014/05/15 23:47:34
Should this be Opt_1 for O1?
Jim Stichnoth
2014/05/17 14:14:32
Done.
| |
599 clEnumValN(Ice::Opt_2, "O2", "2"), clEnumValEnd)); | |
579 static cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"), | 600 static cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"), |
580 cl::Required); | 601 cl::Required); |
581 static cl::opt<std::string> OutputFilename("o", | 602 static cl::opt<std::string> OutputFilename("o", cl::desc("Set output filename"), |
582 cl::desc("Override output filename"), | |
583 cl::init("-"), | 603 cl::init("-"), |
584 cl::value_desc("filename")); | 604 cl::value_desc("filename")); |
605 static cl::opt<std::string> LogFilename("log", cl::desc("Set log filename"), | |
606 cl::init("-"), | |
607 cl::value_desc("filename")); | |
585 static cl::opt<std::string> | 608 static cl::opt<std::string> |
586 TestPrefix("prefix", cl::desc("Prepend a prefix to symbol names for testing"), | 609 TestPrefix("prefix", cl::desc("Prepend a prefix to symbol names for testing"), |
587 cl::init(""), cl::value_desc("prefix")); | 610 cl::init(""), cl::value_desc("prefix")); |
588 static cl::opt<bool> | 611 static cl::opt<bool> |
589 DisableInternal("external", | 612 DisableInternal("external", |
590 cl::desc("Disable 'internal' linkage type for testing")); | 613 cl::desc("Disable 'internal' linkage type for testing")); |
591 static cl::opt<bool> | 614 static cl::opt<bool> |
592 DisableTranslation("notranslate", cl::desc("Disable Subzero translation")); | 615 DisableTranslation("notranslate", cl::desc("Disable Subzero translation")); |
593 | 616 |
594 static cl::opt<bool> SubzeroTimingEnabled( | 617 static cl::opt<bool> SubzeroTimingEnabled( |
(...skipping 25 matching lines...) Expand all Loading... | |
620 for (unsigned i = 0; i != VerboseList.size(); ++i) | 643 for (unsigned i = 0; i != VerboseList.size(); ++i) |
621 VMask |= VerboseList[i]; | 644 VMask |= VerboseList[i]; |
622 | 645 |
623 std::ofstream Ofs; | 646 std::ofstream Ofs; |
624 if (OutputFilename != "-") { | 647 if (OutputFilename != "-") { |
625 Ofs.open(OutputFilename.c_str(), std::ofstream::out); | 648 Ofs.open(OutputFilename.c_str(), std::ofstream::out); |
626 } | 649 } |
627 raw_os_ostream *Os = | 650 raw_os_ostream *Os = |
628 new raw_os_ostream(OutputFilename == "-" ? std::cout : Ofs); | 651 new raw_os_ostream(OutputFilename == "-" ? std::cout : Ofs); |
629 Os->SetUnbuffered(); | 652 Os->SetUnbuffered(); |
653 std::ofstream Lfs; | |
654 if (LogFilename != "-") { | |
655 Lfs.open(LogFilename.c_str(), std::ofstream::out); | |
656 } | |
657 raw_os_ostream *Ls = new raw_os_ostream(LogFilename == "-" ? std::cout : Lfs); | |
658 Ls->SetUnbuffered(); | |
630 | 659 |
631 Ice::GlobalContext Ctx(Os, Os, VMask, TestPrefix); | 660 Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix); |
632 | 661 |
633 for (Module::const_iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) { | 662 for (Module::const_iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) { |
634 if (I->empty()) | 663 if (I->empty()) |
635 continue; | 664 continue; |
636 LLVM2ICEConverter FunctionConverter(&Ctx); | 665 LLVM2ICEConverter FunctionConverter(&Ctx); |
637 | 666 |
638 Ice::Timer TConvert; | 667 Ice::Timer TConvert; |
639 Ice::Cfg *Func = FunctionConverter.convertFunction(I); | 668 Ice::Cfg *Func = FunctionConverter.convertFunction(I); |
640 if (DisableInternal) | 669 if (DisableInternal) |
641 Func->setInternal(false); | 670 Func->setInternal(false); |
642 | 671 |
643 if (SubzeroTimingEnabled) { | 672 if (SubzeroTimingEnabled) { |
644 std::cerr << "[Subzero timing] Convert function " | 673 std::cerr << "[Subzero timing] Convert function " |
645 << Func->getFunctionName() << ": " << TConvert.getElapsedSec() | 674 << Func->getFunctionName() << ": " << TConvert.getElapsedSec() |
646 << " sec\n"; | 675 << " sec\n"; |
647 } | 676 } |
648 | 677 |
649 if (DisableTranslation) { | 678 if (DisableTranslation) { |
650 Func->dump(); | 679 Func->dump(); |
680 } else { | |
681 Ice::Timer TTranslate; | |
682 Func->translate(); | |
683 if (SubzeroTimingEnabled) { | |
684 std::cerr << "[Subzero timing] Translate function " | |
685 << Func->getFunctionName() << ": " | |
686 << TTranslate.getElapsedSec() << " sec\n"; | |
687 } | |
688 if (Func->hasError()) { | |
689 errs() << "ICE translation error: " << Func->getError() << "\n"; | |
jvoung (off chromium)
2014/05/19 20:28:54
Should this also toggle a flag that can help decid
Jim Stichnoth
2014/05/20 18:20:08
Done.
| |
690 } | |
691 | |
692 Ice::Timer TEmit; | |
693 Func->emit(); | |
694 if (SubzeroTimingEnabled) { | |
695 std::cerr << "[Subzero timing] Emit function " | |
696 << Func->getFunctionName() << ": " << TEmit.getElapsedSec() | |
697 << " sec\n"; | |
698 } | |
651 } | 699 } |
652 } | 700 } |
653 | 701 |
654 return 0; | 702 return 0; |
655 } | 703 } |
OLD | NEW |