Index: src/PNaClTranslator.cpp |
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
index f2d8e0cbf2b9d7d54896249bfc1cdb298826ef1b..304fe200202c5c6ba59c973399ddc8ec4cd86f79 100644 |
--- a/src/PNaClTranslator.cpp |
+++ b/src/PNaClTranslator.cpp |
@@ -201,6 +201,10 @@ public: |
/// Changes the size of the type list to the given size. |
void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } |
+ bool disableIRGeneration() const { |
Jim Stichnoth
2014/11/04 00:07:07
Add comment for consistency with other methods?
M
Karl
2014/11/04 20:37:21
Done.
|
+ return Translator.getFlags().DisableIRGeneration; |
+ } |
+ |
/// Returns the undefined type associated with type ID. |
/// Note: Returns extended type ready to be defined. |
ExtendedType *getTypeByIDForDefining(unsigned ID) { |
@@ -284,6 +288,11 @@ public: |
if (C != nullptr) |
return C; |
+ if (disableIRGeneration()) { |
Jim Stichnoth
2014/11/04 00:07:07
There's a vast number of disableIRGeneration() cal
Karl
2014/11/04 20:37:21
Done.
|
+ ValueIDConstants[ID] = nullptr; |
+ return nullptr; |
+ } |
+ |
// If reached, no such constant exists, create one. |
// TODO(kschimpf) Don't get addresses of intrinsic function declarations. |
Ice::GlobalDeclaration *Decl = nullptr; |
@@ -523,6 +532,10 @@ protected: |
const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } |
+ bool disableIRGeneration() const { |
+ return getTranslator().getFlags().DisableIRGeneration; |
+ } |
+ |
// Generates an error Message with the bit address prefixed to it. |
bool Error(const std::string &Message) override { |
uint64_t Bit = Record.GetStartBit() + Context->getHeaderSize() * 8; |
@@ -881,10 +894,12 @@ void GlobalsParser::ProcessRecord() { |
if (!isValidRecordSize(2, "Globals variable")) |
return; |
verifyNoMissingInitializers(); |
- InitializersNeeded = 1; |
- CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID); |
- CurGlobalVar->setAlignment((1 << Values[0]) >> 1); |
- CurGlobalVar->setIsConstant(Values[1] != 0); |
+ if (!disableIRGeneration()) { |
+ InitializersNeeded = 1; |
+ CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID); |
+ CurGlobalVar->setAlignment((1 << Values[0]) >> 1); |
+ CurGlobalVar->setIsConstant(Values[1] != 0); |
+ } |
++NextGlobalID; |
return; |
} |
@@ -903,12 +918,16 @@ void GlobalsParser::ProcessRecord() { |
Error(StrBuf.str()); |
return; |
} |
+ if (disableIRGeneration()) |
+ return; |
InitializersNeeded = Values[0]; |
return; |
case naclbitc::GLOBALVAR_ZEROFILL: { |
// ZEROFILL: [size] |
if (!isValidRecordSize(1, "Globals zerofill")) |
return; |
+ if (disableIRGeneration()) |
+ return; |
CurGlobalVar->addInitializer( |
new Ice::VariableDeclaration::ZeroInitializer(Values[0])); |
return; |
@@ -917,6 +936,8 @@ void GlobalsParser::ProcessRecord() { |
// DATA: [b0, b1, ...] |
if (!isValidRecordSizeAtLeast(1, "Globals data")) |
return; |
+ if (disableIRGeneration()) |
+ return; |
CurGlobalVar->addInitializer( |
new Ice::VariableDeclaration::DataInitializer(Values)); |
return; |
@@ -925,6 +946,8 @@ void GlobalsParser::ProcessRecord() { |
// RELOC: [val, [addend]] |
if (!isValidRecordSizeInRange(1, 2, "Globals reloc")) |
return; |
+ if (disableIRGeneration()) |
+ return; |
unsigned Index = Values[0]; |
Ice::SizeT Offset = 0; |
if (Values.size() == 2) |
@@ -1011,37 +1034,49 @@ public: |
FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
: BlockParserBaseClass(BlockID, EnclosingParser), |
Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), |
- Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), |
- FcnId(Context->getNextFunctionBlockValueID()), |
+ Func(disableIRGeneration() |
+ ? nullptr |
+ : new Ice::Cfg(getTranslator().getContext())), |
+ CurrentBbIndex(0), FcnId(Context->getNextFunctionBlockValueID()), |
FuncDecl(Context->getFunctionByID(FcnId)), |
CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), |
NextLocalInstIndex(Context->getNumGlobalIDs()), |
InstIsTerminating(false) { |
- Func->setFunctionName(FuncDecl->getName()); |
if (getFlags().TimeEachFunction) |
getTranslator().getContext()->pushTimer( |
getTranslator().getContext()->getTimerID( |
- Ice::GlobalContext::TSK_Funcs, Func->getFunctionName()), |
+ Ice::GlobalContext::TSK_Funcs, FuncDecl->getName()), |
Ice::GlobalContext::TSK_Funcs); |
// TODO(kschimpf) Clean up API to add a function signature to |
// a CFG. |
const Ice::FuncSigType &Signature = FuncDecl->getSignature(); |
- Func->setReturnType(Signature.getReturnType()); |
- Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
- CurrentNode = InstallNextBasicBlock(); |
- Func->setEntryNode(CurrentNode); |
- for (Ice::Type ArgType : Signature.getArgList()) { |
- Func->addArg(getNextInstVar(ArgType)); |
+ if (disableIRGeneration()) { |
+ CurrentNode = nullptr; |
+ for (Ice::Type ArgType : Signature.getArgList()) { |
+ (void)ArgType; |
+ setNextLocalInstIndex(nullptr); |
+ } |
+ } else { |
+ Func->setFunctionName(FuncDecl->getName()); |
+ Func->setReturnType(Signature.getReturnType()); |
+ Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
+ CurrentNode = InstallNextBasicBlock(); |
+ Func->setEntryNode(CurrentNode); |
+ for (Ice::Type ArgType : Signature.getArgList()) { |
+ Func->addArg(getNextInstVar(ArgType)); |
+ } |
} |
} |
~FunctionParser() override {}; |
- // Set the next constant ID to the given constant C. |
- void setNextConstantID(Ice::Constant *C) { |
- setOperand(NextLocalInstIndex++, C); |
+ void setNextLocalInstIndex(Ice::Operand *Op) { |
+ setOperand(NextLocalInstIndex++, Op); |
} |
+ // Set the next constant ID to the given constant C. |
+ void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } |
+ |
private: |
Ice::TimerMarker Timer; |
// The corresponding ICE function defined by the function block. |
@@ -1068,6 +1103,14 @@ private: |
// Upper limit of alignment power allowed by LLVM |
static const uint64_t AlignPowerLimit = 29; |
+ void popTimerIfTimingEachFunction() const { |
+ if (getFlags().TimeEachFunction) |
+ getTranslator().getContext()->popTimer( |
+ getTranslator().getContext()->getTimerID( |
+ Ice::GlobalContext::TSK_Funcs, Func->getFunctionName()), |
+ Ice::GlobalContext::TSK_Funcs); |
+ } |
+ |
// Extracts the corresponding Alignment to use, given the AlignPower |
// (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the |
// name of the instruction the alignment appears in. |
@@ -1093,10 +1136,14 @@ private: |
void ExitBlock() override; |
// Creates and appends a new basic block to the list of basic blocks. |
- Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); } |
+ Ice::CfgNode *InstallNextBasicBlock() { |
+ assert(!disableIRGeneration()); |
+ return Func->makeNode(); |
+ } |
// Returns the Index-th basic block in the list of basic blocks. |
Ice::CfgNode *getBasicBlock(uint32_t Index) { |
+ assert(!disableIRGeneration()); |
const Ice::NodeList &Nodes = Func->getNodes(); |
if (Index >= Nodes.size()) { |
std::string Buffer; |
@@ -1115,6 +1162,7 @@ private: |
// the branch references the entry block, it also generates a |
// corresponding error. |
Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { |
+ assert(!disableIRGeneration()); |
if (Index == 0) { |
Error("Branch to entry block not allowed"); |
// TODO(kschimpf) Remove error recovery once implementation complete. |
@@ -1124,6 +1172,7 @@ private: |
// Generate an instruction variable with type Ty. |
Ice::Variable *createInstVar(Ice::Type Ty) { |
+ assert(!disableIRGeneration()); |
if (Ty == Ice::IceType_void) { |
Error("Can't define instruction value using type void"); |
// Recover since we can't throw an exception. |
@@ -1134,6 +1183,7 @@ private: |
// Generates the next available local variable using the given type. |
Ice::Variable *getNextInstVar(Ice::Type Ty) { |
+ assert(!disableIRGeneration()); |
assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); |
// Before creating one, see if a forwardtyperef has already defined it. |
uint32_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; |
@@ -1191,6 +1241,8 @@ private: |
} |
Ice::Operand *Op = LocalOperands[LocalIndex]; |
if (Op == nullptr) { |
+ if (disableIRGeneration()) |
+ return nullptr; |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
StrBuf << "Value index " << Index << " not defined!"; |
@@ -1202,7 +1254,7 @@ private: |
// Sets element Index (in the local operands list) to Op. |
void setOperand(uint32_t Index, Ice::Operand *Op) { |
- assert(Op); |
+ assert(Op || disableIRGeneration()); |
// Check if simple push works. |
uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
if (LocalIndex == LocalOperands.size()) { |
@@ -1217,6 +1269,8 @@ private: |
// If element not defined, set it. |
Ice::Operand *OldOp = LocalOperands[LocalIndex]; |
if (OldOp == nullptr) { |
+ if (disableIRGeneration()) |
+ return; |
LocalOperands[LocalIndex] = Op; |
return; |
} |
@@ -1633,6 +1687,10 @@ void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { |
} |
void FunctionParser::ExitBlock() { |
+ if (disableIRGeneration()) { |
+ popTimerIfTimingEachFunction(); |
+ return; |
+ } |
// Before translating, check for blocks without instructions, and |
// insert unreachable. This shouldn't happen, but be safe. |
unsigned Index = 0; |
@@ -1654,11 +1712,7 @@ void FunctionParser::ExitBlock() { |
// for such parsing errors. |
if (Context->getNumErrors() == 0) |
getTranslator().translateFcn(Func); |
- if (getFlags().TimeEachFunction) |
- getTranslator().getContext()->popTimer( |
- getTranslator().getContext()->getTimerID(Ice::GlobalContext::TSK_Funcs, |
- Func->getFunctionName()), |
- Ice::GlobalContext::TSK_Funcs); |
+ popTimerIfTimingEachFunction(); |
} |
void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, |
@@ -1674,7 +1728,8 @@ void FunctionParser::ProcessRecord() { |
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
if (InstIsTerminating) { |
InstIsTerminating = false; |
- CurrentNode = getBasicBlock(++CurrentBbIndex); |
+ if (!disableIRGeneration()) |
+ CurrentNode = getBasicBlock(++CurrentBbIndex); |
} |
// The base index for relative indexing. |
int32_t BaseIndex = getNextInstIndex(); |
@@ -1683,6 +1738,8 @@ void FunctionParser::ProcessRecord() { |
// DECLAREBLOCKS: [n] |
if (!isValidRecordSize(1, "function block count")) |
return; |
+ if (disableIRGeneration()) |
+ return; |
if (Func->getNodes().size() != 1) { |
Error("Duplicate function block count record"); |
return; |
@@ -1703,6 +1760,10 @@ void FunctionParser::ProcessRecord() { |
// BINOP: [opval, opval, opcode] |
if (!isValidRecordSize(3, "function block binop")) |
return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); |
Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); |
Ice::Type Type1 = Op1->getType(); |
@@ -1727,6 +1788,10 @@ void FunctionParser::ProcessRecord() { |
// CAST: [opval, destty, castopc] |
if (!isValidRecordSize(3, "function block cast")) |
return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); |
Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); |
Instruction::CastOps LLVMCastOp; |
@@ -1757,6 +1822,12 @@ void FunctionParser::ProcessRecord() { |
} |
case naclbitc::FUNC_CODE_INST_VSELECT: { |
// VSELECT: [opval, opval, pred] |
+ if (!isValidRecordSize(3, "function block select")) |
+ return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex); |
Ice::Type ThenType = ThenVal->getType(); |
Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex); |
@@ -1801,6 +1872,10 @@ void FunctionParser::ProcessRecord() { |
// EXTRACTELT: [opval, opval] |
if (!isValidRecordSize(2, "function block extract element")) |
return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); |
Ice::Type VecType = Vec->getType(); |
Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); |
@@ -1823,6 +1898,10 @@ void FunctionParser::ProcessRecord() { |
// INSERTELT: [opval, opval, opval] |
if (!isValidRecordSize(3, "function block insert element")) |
return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); |
Ice::Type VecType = Vec->getType(); |
Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); |
@@ -1847,6 +1926,10 @@ void FunctionParser::ProcessRecord() { |
// CMP2: [opval, opval, pred] |
if (!isValidRecordSize(3, "function block compare")) |
return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); |
Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); |
Ice::Type Op1Type = Op1->getType(); |
@@ -1908,6 +1991,10 @@ void FunctionParser::ProcessRecord() { |
// RET: [opval?] |
if (!isValidRecordSizeInRange(0, 1, "function block ret")) |
return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
if (Values.size() == 0) { |
CurrentNode->appendInst(Ice::InstRet::create(Func)); |
} else { |
@@ -1920,6 +2007,8 @@ void FunctionParser::ProcessRecord() { |
case naclbitc::FUNC_CODE_INST_BR: { |
if (Values.size() == 1) { |
// BR: [bb#] |
+ if (disableIRGeneration()) |
+ return; |
Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); |
if (Block == nullptr) |
return; |
@@ -1928,6 +2017,8 @@ void FunctionParser::ProcessRecord() { |
// BR: [bb#, bb#, opval] |
if (!isValidRecordSize(3, "function block branch")) |
return; |
+ if (disableIRGeneration()) |
+ return; |
Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); |
if (Cond->getType() != Ice::IceType_i1) { |
std::string Buffer; |
@@ -1958,6 +2049,8 @@ void FunctionParser::ProcessRecord() { |
// already frozen when the problem was noticed. |
if (!isValidRecordSizeAtLeast(4, "function block switch")) |
return; |
+ if (disableIRGeneration()) |
+ return; |
Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]); |
if (!Ice::isScalarIntegerType(CondTy)) { |
std::string Buffer; |
@@ -2009,6 +2102,8 @@ void FunctionParser::ProcessRecord() { |
// UNREACHABLE: [] |
if (!isValidRecordSize(0, "function block unreachable")) |
return; |
+ if (disableIRGeneration()) |
+ return; |
CurrentNode->appendInst( |
Ice::InstUnreachable::create(Func)); |
InstIsTerminating = true; |
@@ -2032,6 +2127,10 @@ void FunctionParser::ProcessRecord() { |
Error("Phi record using type void not allowed"); |
return; |
} |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Variable *Dest = getNextInstVar(Ty); |
Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); |
for (unsigned i = 1; i < Values.size(); i += 2) { |
@@ -2055,6 +2154,10 @@ void FunctionParser::ProcessRecord() { |
// ALLOCA: [Size, align] |
if (!isValidRecordSize(2, "function block alloca")) |
return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); |
Ice::Type PtrTy = Context->getIcePointerType(); |
if (ByteCount->getType() != Ice::IceType_i32) { |
@@ -2075,6 +2178,10 @@ void FunctionParser::ProcessRecord() { |
// LOAD: [address, align, ty] |
if (!isValidRecordSize(3, "function block load")) |
return; |
+ if (disableIRGeneration()) { |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); |
if (!isValidPointerType(Address, "Load")) { |
@@ -2095,6 +2202,8 @@ void FunctionParser::ProcessRecord() { |
// STORE: [address, value, align] |
if (!isValidRecordSize(3, "function block store")) |
return; |
+ if (disableIRGeneration()) |
+ return; |
Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
if (!isValidPointerType(Address, "Store")) |
return; |
@@ -2173,6 +2282,12 @@ void FunctionParser::ProcessRecord() { |
} |
bool IsTailCall = static_cast<bool>(CCInfo & 1); |
+ if (disableIRGeneration()) { |
+ if (ReturnType != Ice::IceType_void) |
+ setNextLocalInstIndex(nullptr); |
+ return; |
+ } |
+ |
// Create the call instruction. |
Ice::Variable *Dest = (ReturnType == Ice::IceType_void) |
? nullptr |
@@ -2242,7 +2357,12 @@ void FunctionParser::ProcessRecord() { |
// FORWARDTYPEREF: [opval, ty] |
if (!isValidRecordSize(2, "function block forward type ref")) |
return; |
- setOperand(Values[0], createInstVar(Context->getSimpleTypeByID(Values[1]))); |
+ if (disableIRGeneration()) { |
+ setOperand(Values[0], nullptr); |
+ } else { |
+ setOperand(Values[0], |
+ createInstVar(Context->getSimpleTypeByID(Values[1]))); |
+ } |
return; |
} |
default: |
@@ -2304,6 +2424,10 @@ void ConstantsParser::ProcessRecord() { |
return; |
if (!isValidNextConstantType()) |
return; |
+ if (disableIRGeneration()) { |
+ FuncParser->setNextConstantID(nullptr); |
+ return; |
+ } |
FuncParser->setNextConstantID( |
getContext()->getConstantUndef(NextConstantType)); |
return; |
@@ -2322,7 +2446,11 @@ void ConstantsParser::ProcessRecord() { |
NextConstantType, Value.getSExtValue()) |
: getContext()->getConstantInt32( |
NextConstantType, Value.getSExtValue()); |
- FuncParser->setNextConstantID(C); |
+ if (disableIRGeneration()) { |
+ FuncParser->setNextConstantID(nullptr); |
+ } else { |
+ FuncParser->setNextConstantID(C); |
+ } |
return; |
} |
std::string Buffer; |
@@ -2338,6 +2466,10 @@ void ConstantsParser::ProcessRecord() { |
return; |
if (!isValidNextConstantType()) |
return; |
+ if (disableIRGeneration()) { |
+ FuncParser->setNextConstantID(nullptr); |
+ return; |
+ } |
switch (NextConstantType) { |
case Ice::IceType_f32: { |
APFloat Value(APFloat::IEEEsingle, |
@@ -2348,8 +2480,12 @@ void ConstantsParser::ProcessRecord() { |
} |
case Ice::IceType_f64: { |
APFloat Value(APFloat::IEEEdouble, APInt(64, Values[0])); |
- FuncParser->setNextConstantID( |
- getContext()->getConstantDouble(Value.convertToDouble())); |
+ if (disableIRGeneration()) { |
+ FuncParser->setNextConstantID(nullptr); |
+ } else { |
+ FuncParser->setNextConstantID( |
+ getContext()->getConstantDouble(Value.convertToDouble())); |
+ } |
return; |
} |
default: { |
@@ -2410,6 +2546,8 @@ void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
// TODO(kschimpf) Remove error recovery once implementation complete. |
return; |
} |
+ if (disableIRGeneration()) |
+ return; |
Ice::Operand *Op = getFunctionParser()->getOperand(Index); |
if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { |
std::string Nm(Name.data(), Name.size()); |
@@ -2420,6 +2558,8 @@ void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
} |
void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { |
+ if (disableIRGeneration()) |
+ return; |
if (Index >= getFunctionParser()->Func->getNumNodes()) { |
reportUnableToAssign("block", Index, Name); |
return; |