Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: src/PNaClTranslator.cpp

Issue 576853002: Add forward instruction declaration to Subzero bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits in patch set 3. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests_lit/lit.cfg » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===//
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 implements the PNaCl bitcode file to Ice, to machine code 10 // This file implements the PNaCl bitcode file to Ice, to machine code
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 FunctionParser &operator=(const FunctionParser &) LLVM_DELETED_FUNCTION; 807 FunctionParser &operator=(const FunctionParser &) LLVM_DELETED_FUNCTION;
808 friend class FunctionValuesymtabParser; 808 friend class FunctionValuesymtabParser;
809 809
810 public: 810 public:
811 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 811 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
812 : BlockParserBaseClass(BlockID, EnclosingParser), 812 : BlockParserBaseClass(BlockID, EnclosingParser),
813 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), 813 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0),
814 FcnId(Context->getNextFunctionBlockValueID()), 814 FcnId(Context->getNextFunctionBlockValueID()),
815 LLVMFunc(cast<Function>(Context->getGlobalValueByID(FcnId))), 815 LLVMFunc(cast<Function>(Context->getGlobalValueByID(FcnId))),
816 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()), 816 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()),
817 NextLocalInstIndex(Context->getNumGlobalValueIDs()),
817 InstIsTerminating(false) { 818 InstIsTerminating(false) {
818 Func->setFunctionName(LLVMFunc->getName()); 819 Func->setFunctionName(LLVMFunc->getName());
819 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType())); 820 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType()));
820 Func->setInternal(LLVMFunc->hasInternalLinkage()); 821 Func->setInternal(LLVMFunc->hasInternalLinkage());
821 CurrentNode = InstallNextBasicBlock(); 822 CurrentNode = InstallNextBasicBlock();
822 Func->setEntryNode(CurrentNode); 823 Func->setEntryNode(CurrentNode);
823 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(), 824 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(),
824 ArgE = LLVMFunc->arg_end(); 825 ArgE = LLVMFunc->arg_end();
825 ArgI != ArgE; ++ArgI) { 826 ArgI != ArgE; ++ArgI) {
826 Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType()))); 827 Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType())));
827 } 828 }
828 } 829 }
829 830
830 ~FunctionParser() LLVM_OVERRIDE; 831 ~FunctionParser() LLVM_OVERRIDE;
831 832
832 // Set the next constant ID to the given constant C. 833 // Set the next constant ID to the given constant C.
833 void setNextConstantID(Ice::Constant *C) { LocalOperands.push_back(C); } 834 void setNextConstantID(Ice::Constant *C) {
835 setOperand(NextLocalInstIndex++, C);
836 }
834 837
835 private: 838 private:
836 // Timer for reading function bitcode and converting to ICE. 839 // Timer for reading function bitcode and converting to ICE.
837 Ice::Timer TConvert; 840 Ice::Timer TConvert;
838 // The corresponding ICE function defined by the function block. 841 // The corresponding ICE function defined by the function block.
839 Ice::Cfg *Func; 842 Ice::Cfg *Func;
840 // The index to the current basic block being built. 843 // The index to the current basic block being built.
841 uint32_t CurrentBbIndex; 844 uint32_t CurrentBbIndex;
842 // The basic block being built. 845 // The basic block being built.
843 Ice::CfgNode *CurrentNode; 846 Ice::CfgNode *CurrentNode;
844 // The ID for the function. 847 // The ID for the function.
845 unsigned FcnId; 848 unsigned FcnId;
846 // The corresponding LLVM function. 849 // The corresponding LLVM function.
847 Function *LLVMFunc; 850 Function *LLVMFunc;
851 // Holds the dividing point between local and global absolute value indices.
852 uint32_t CachedNumGlobalValueIDs;
848 // Holds operands local to the function block, based on indices 853 // Holds operands local to the function block, based on indices
849 // defined in the bitcode file. 854 // defined in the bitcode file.
850 std::vector<Ice::Operand *> LocalOperands; 855 std::vector<Ice::Operand *> LocalOperands;
851 // Holds the dividing point between local and global absolute value indices. 856 // Holds the index within LocalOperands corresponding to the next
852 uint32_t CachedNumGlobalValueIDs; 857 // instruction that generates a value.
858 uint32_t NextLocalInstIndex;
853 // True if the last processed instruction was a terminating 859 // True if the last processed instruction was a terminating
854 // instruction. 860 // instruction.
855 bool InstIsTerminating; 861 bool InstIsTerminating;
856 // Upper limit of alignment power allowed by LLVM 862 // Upper limit of alignment power allowed by LLVM
857 static const uint64_t AlignPowerLimit = 29; 863 static const uint64_t AlignPowerLimit = 29;
858 864
859 // Extracts the corresponding Alignment to use, given the AlignPower 865 // Extracts the corresponding Alignment to use, given the AlignPower
860 // (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the 866 // (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the
861 // name of the instruction the alignment appears in. 867 // name of the instruction the alignment appears in.
862 void extractAlignment(const char *InstName, uint64_t AlignPower, 868 void extractAlignment(const char *InstName, uint64_t AlignPower,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 // the branch references the entry block, it also generates a 909 // the branch references the entry block, it also generates a
904 // corresponding error. 910 // corresponding error.
905 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { 911 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) {
906 if (Index == 0) { 912 if (Index == 0) {
907 Error("Branch to entry block not allowed"); 913 Error("Branch to entry block not allowed");
908 // TODO(kschimpf) Remove error recovery once implementation complete. 914 // TODO(kschimpf) Remove error recovery once implementation complete.
909 } 915 }
910 return getBasicBlock(Index); 916 return getBasicBlock(Index);
911 } 917 }
912 918
913 // Generates the next available local variable using the given type. 919 // Generate an instruction variable with type Ty.
914 Ice::Variable *getNextInstVar(Ice::Type Ty) { 920 Ice::Variable *createInstVar(Ice::Type Ty) {
915 if (Ty == Ice::IceType_void) { 921 if (Ty == Ice::IceType_void) {
916 Error("Can't define instruction value using type void"); 922 Error("Can't define instruction value using type void");
917 // Recover since we can't throw an exception. 923 // Recover since we can't throw an exception.
918 Ty = Ice::IceType_i32; 924 Ty = Ice::IceType_i32;
919 } 925 }
920 Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode); 926 return Func->makeVariable(Ty, CurrentNode);
921 LocalOperands.push_back(Var); 927 }
928
929 // Generates the next available local variable using the given type.
930 Ice::Variable *getNextInstVar(Ice::Type Ty) {
931 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs);
932 // Before creating one, see if a forwardtyperef has already defined it.
933 uint32_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs;
934 if (LocalIndex < LocalOperands.size()) {
935 Ice::Operand *Op = LocalOperands[LocalIndex];
936 if (Op != NULL) {
937 if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) {
938 if (Var->getType() == Ty) {
939 ++NextLocalInstIndex;
940 return Var;
941 }
942 }
943 std::string Buffer;
944 raw_string_ostream StrBuf(Buffer);
945 StrBuf << "Illegal forward referenced instruction ("
946 << NextLocalInstIndex << "): " << *Op;
947 Error(StrBuf.str());
948 // TODO(kschimpf) Remove error recovery once implementation complete.
949 ++NextLocalInstIndex;
950 return createInstVar(Ty);
951 }
952 }
953 Ice::Variable *Var = createInstVar(Ty);
954 setOperand(NextLocalInstIndex++, Var);
922 return Var; 955 return Var;
923 } 956 }
924 957
925 // Converts a relative index (wrt to BaseIndex) to an absolute value 958 // Converts a relative index (wrt to BaseIndex) to an absolute value
926 // index. 959 // index.
927 uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) { 960 uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) {
928 if (BaseIndex < Id) { 961 if (BaseIndex < Id) {
929 std::string Buffer; 962 std::string Buffer;
930 raw_string_ostream StrBuf(Buffer); 963 raw_string_ostream StrBuf(Buffer);
931 StrBuf << "Invalid relative value id: " << Id 964 StrBuf << "Invalid relative value id: " << Id
932 << " (must be <= " << BaseIndex << ")"; 965 << " (must be <= " << BaseIndex << ")";
933 Error(StrBuf.str()); 966 Error(StrBuf.str());
934 // TODO(kschimpf) Remove error recovery once implementation complete. 967 // TODO(kschimpf) Remove error recovery once implementation complete.
935 return 0; 968 return 0;
936 } 969 }
937 return BaseIndex - Id; 970 return BaseIndex - Id;
938 } 971 }
939 972
940 // Returns the value referenced by the given value Index. 973 // Returns the value referenced by the given value Index.
941 Ice::Operand *getOperand(uint32_t Index) { 974 Ice::Operand *getOperand(uint32_t Index) {
942 if (Index < CachedNumGlobalValueIDs) { 975 if (Index < CachedNumGlobalValueIDs) {
943 // TODO(kschimpf): Define implementation. 976 // TODO(kschimpf): Define implementation.
944 report_fatal_error("getOperand of global addresses not implemented"); 977 report_fatal_error("getOperand of global addresses not implemented");
945 } 978 }
946 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; 979 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
947 if (LocalIndex >= LocalOperands.size()) { 980 if (LocalIndex >= LocalOperands.size()) {
948 std::string Buffer; 981 std::string Buffer;
949 raw_string_ostream StrBuf(Buffer); 982 raw_string_ostream StrBuf(Buffer);
950 StrBuf << "Value index " << Index << " out of range. Must be less than " 983 StrBuf << "Value index " << Index << " not defined!";
951 << (LocalOperands.size() + CachedNumGlobalValueIDs);
952 Error(StrBuf.str()); 984 Error(StrBuf.str());
953 report_fatal_error("Unable to continue"); 985 report_fatal_error("Unable to continue");
954 } 986 }
955 return LocalOperands[LocalIndex]; 987 Ice::Operand *Op = LocalOperands[LocalIndex];
988 if (Op == NULL) {
989 std::string Buffer;
990 raw_string_ostream StrBuf(Buffer);
991 StrBuf << "Value index " << Index << " not defined!";
992 Error(StrBuf.str());
993 report_fatal_error("Unable to continue");
994 }
995 return Op;
996 }
997
998 // Sets element Index (in the local operands list) to Op.
999 void setOperand(uint32_t Index, Ice::Operand *Op) {
1000 assert(Op);
1001 // Check if simple push works.
1002 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
1003 if (LocalIndex == LocalOperands.size()) {
1004 LocalOperands.push_back(Op);
1005 return;
1006 }
1007
1008 // Must be forward reference, expand vector to accommodate.
1009 if (LocalIndex >= LocalOperands.size())
1010 LocalOperands.resize(LocalIndex+1);
1011
1012 // If element not defined, set it.
1013 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1014 if (OldOp == NULL) {
1015 LocalOperands[LocalIndex] = Op;
1016 return;
1017 }
1018
1019 // See if forward reference matches.
1020 if (OldOp == Op)
1021 return;
1022
1023 // Error has occurred.
1024 std::string Buffer;
1025 raw_string_ostream StrBuf(Buffer);
1026 StrBuf << "Multiple definitions for index " << Index
1027 << ": " << *Op << " and " << *OldOp;
1028 Error(StrBuf.str());
1029 // TODO(kschimpf) Remove error recovery once implementation complete.
1030 LocalOperands[LocalIndex] = Op;
956 } 1031 }
957 1032
958 // Returns the relative operand (wrt to BaseIndex) referenced by 1033 // Returns the relative operand (wrt to BaseIndex) referenced by
959 // the given value Index. 1034 // the given value Index.
960 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) { 1035 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) {
961 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); 1036 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
962 } 1037 }
963 1038
964 // Returns the absolute index of the next value generating instruction. 1039 // Returns the absolute index of the next value generating instruction.
965 uint32_t getNextInstIndex() const { 1040 uint32_t getNextInstIndex() const {
966 return CachedNumGlobalValueIDs + LocalOperands.size(); 1041 return NextLocalInstIndex;
967 } 1042 }
968 1043
969 // Generates type error message for binary operator Op 1044 // Generates type error message for binary operator Op
970 // operating on Type OpTy. 1045 // operating on Type OpTy.
971 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); 1046 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
972 1047
973 // Validates if integer logical Op, for type OpTy, is valid. 1048 // Validates if integer logical Op, for type OpTy, is valid.
974 // Returns true if valid. Otherwise generates error message and 1049 // Returns true if valid. Otherwise generates error message and
975 // returns false. 1050 // returns false.
976 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 1051 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 return; 1770 return;
1696 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); 1771 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
1697 unsigned Alignment; 1772 unsigned Alignment;
1698 extractAlignment("Store", Values[2], Alignment); 1773 extractAlignment("Store", Values[2], Alignment);
1699 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) 1774 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
1700 return; 1775 return;
1701 CurrentNode->appendInst( 1776 CurrentNode->appendInst(
1702 Ice::InstStore::create(Func, Value, Address, Alignment)); 1777 Ice::InstStore::create(Func, Value, Address, Alignment));
1703 break; 1778 break;
1704 } 1779 }
1780 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
1781 // FORWARDTYPEREF: [opval, ty]
1782 if (!isValidRecordSize(2, "function block forward type ref"))
1783 return;
1784 setOperand(Values[0], createInstVar(
1785 Context->convertToIceType(Context->getTypeByID(Values[1]))));
1786 break;
1787 }
1705 case naclbitc::FUNC_CODE_INST_SWITCH: 1788 case naclbitc::FUNC_CODE_INST_SWITCH:
1706 case naclbitc::FUNC_CODE_INST_CALL: 1789 case naclbitc::FUNC_CODE_INST_CALL:
1707 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: 1790 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT:
1708 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF:
1709 default: 1791 default:
1710 // Generate error message! 1792 // Generate error message!
1711 BlockParserBaseClass::ProcessRecord(); 1793 BlockParserBaseClass::ProcessRecord();
1712 break; 1794 break;
1713 } 1795 }
1714 } 1796 }
1715 1797
1716 /// Parses constants within a function block. 1798 /// Parses constants within a function block.
1717 class ConstantsParser : public BlockParserBaseClass { 1799 class ConstantsParser : public BlockParserBaseClass {
1718 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; 1800 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION;
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 if (TopLevelBlocks != 1) { 2185 if (TopLevelBlocks != 1) {
2104 errs() << IRFilename 2186 errs() << IRFilename
2105 << ": Contains more than one module. Found: " << TopLevelBlocks 2187 << ": Contains more than one module. Found: " << TopLevelBlocks
2106 << "\n"; 2188 << "\n";
2107 ErrorStatus = true; 2189 ErrorStatus = true;
2108 } 2190 }
2109 return; 2191 return;
2110 } 2192 }
2111 2193
2112 } // end of namespace Ice 2194 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/lit.cfg » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698