Commit f12355ec by Karl Schimpf

Add constants block to PNaCl bitcode reader.

parent 7076c888
......@@ -821,6 +821,9 @@ public:
~FunctionParser() LLVM_OVERRIDE;
// Set the next constant ID to the given constant C.
void setNextConstantID(Ice::Constant *C) { LocalOperands.push_back(C); }
private:
// Timer for reading function bitcode and converting to ICE.
Ice::Timer TConvert;
......@@ -843,6 +846,8 @@ private:
// instruction.
bool InstIsTerminating;
virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
virtual void ProcessRecord() LLVM_OVERRIDE;
virtual void ExitBlock() LLVM_OVERRIDE;
......@@ -1519,6 +1524,130 @@ void FunctionParser::ProcessRecord() {
CurrentNode->appendInst(Inst);
}
/// Parses constants within a function block.
class ConstantsParser : public BlockParserBaseClass {
ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION;
ConstantsParser &operator=(const ConstantsParser &) LLVM_DELETED_FUNCTION;
public:
ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
: BlockParserBaseClass(BlockID, FuncParser), FuncParser(FuncParser),
NextConstantType(Ice::IceType_void) {}
~ConstantsParser() LLVM_OVERRIDE {}
private:
// The parser of the function block this constants block appears in.
FunctionParser *FuncParser;
// The type to use for succeeding constants.
Ice::Type NextConstantType;
virtual void ProcessRecord() LLVM_OVERRIDE;
Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
// Returns true if the type to use for succeeding constants is defined.
// If false, also generates an error message.
bool isValidNextConstantType() {
if (NextConstantType != Ice::IceType_void)
return true;
Error("Constant record not preceded by set type record");
return false;
}
};
void ConstantsParser::ProcessRecord() {
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
switch (Record.GetCode()) {
case naclbitc::CST_CODE_SETTYPE: {
// SETTYPE: [typeid]
if (!isValidRecordSize(1, "constants block set type"))
return;
NextConstantType =
Context->convertToIceType(Context->getTypeByID(Values[0]));
if (NextConstantType == Ice::IceType_void)
Error("constants block set type not allowed for void type");
return;
}
case naclbitc::CST_CODE_UNDEF: {
// UNDEF
if (!isValidRecordSize(0, "constants block undef"))
return;
if (!isValidNextConstantType())
return;
FuncParser->setNextConstantID(
getContext()->getConstantUndef(NextConstantType));
return;
}
case naclbitc::CST_CODE_INTEGER: {
// INTEGER: [intval]
if (!isValidRecordSize(1, "constants block integer"))
return;
if (!isValidNextConstantType())
return;
if (IntegerType *IType = dyn_cast<IntegerType>(
Context->convertToLLVMType(NextConstantType))) {
APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0]));
Ice::Constant *C =
getContext()->getConstantInt(NextConstantType, Value.getSExtValue());
FuncParser->setNextConstantID(C);
return;
}
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "constant block integer record for non-integer type "
<< NextConstantType;
Error(StrBuf.str());
return;
}
case naclbitc::CST_CODE_FLOAT: {
// FLOAT: [fpval]
if (!isValidRecordSize(1, "constants block float"))
return;
if (!isValidNextConstantType())
return;
switch (NextConstantType) {
case Ice::IceType_f32: {
APFloat Value(APFloat::IEEEsingle,
APInt(32, static_cast<uint32_t>(Values[0])));
FuncParser->setNextConstantID(
getContext()->getConstantFloat(Value.convertToFloat()));
return;
}
case Ice::IceType_f64: {
APFloat Value(APFloat::IEEEdouble, APInt(64, Values[0]));
FuncParser->setNextConstantID(
getContext()->getConstantDouble(Value.convertToDouble()));
return;
}
default: {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "constant block float record for non-floating type "
<< NextConstantType;
Error(StrBuf.str());
return;
}
}
}
default:
// Generate error message!
BlockParserBaseClass::ProcessRecord();
return;
}
}
bool FunctionParser::ParseBlock(unsigned BlockID) {
switch (BlockID) {
case naclbitc::CONSTANTS_BLOCK_ID: {
ConstantsParser Parser(BlockID, this);
return Parser.ParseThisBlock();
}
default:
return BlockParserBaseClass::ParseBlock(BlockID);
}
}
/// Parses the module block in the bitcode file.
class ModuleParser : public BlockParserBaseClass {
public:
......
; Test handling of constants in function blocks.
; RUN: llvm-as < %s | pnacl-freeze \
; RUN: | %llvm2ice -notranslate -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: | FileCheck %s
define void @TestIntegers() {
; CHECK: __0:
; Test various sized integers
%v0 = or i1 true, false
; CHECK-NEXT: %__0 = or i1 true, false
%v1 = add i8 0, 0
; CHECK-NEXT: %__1 = add i8 0, 0
%v2 = add i8 5, 0
; CHECK-NEXT: %__2 = add i8 5, 0
%v3 = add i8 -5, 0
; CHECK-NEXT: %__3 = add i8 -5, 0
%v4 = and i16 10, 0
; CHECK-NEXT: %__4 = and i16 10, 0
%v5 = add i16 -10, 0
; CHECK-NEXT: %__5 = add i16 -10, 0
%v6 = add i32 20, 0
; CHECK-NEXT: %__6 = add i32 20, 0
%v7 = add i32 -20, 0
; CHECK-NEXT: %__7 = add i32 -20, 0
%v8 = add i64 30, 0
; CHECK-NEXT: %__8 = add i64 30, 0
%v9 = add i64 -30, 0
; CHECK-NEXT: %__9 = add i64 -30, 0
; Test undefined integer values.
%v10 = xor i1 undef, false
; CHECK-NEXT: %__10 = xor i1 undef, false
%v11 = add i8 undef, 0
; CHECK-NEXT: %__11 = add i8 undef, 0
%v12 = add i16 undef, 0
; CHECK-NEXT: %__12 = add i16 undef, 0
%v13 = add i32 undef, 0
; CHECK-NEXT: %__13 = add i32 undef, 0
%v14 = add i64 undef, 0
; CHECK-NEXT: %__14 = add i64 undef, 0
ret void
; CHECK-NEXT: ret void
}
define void @TestFloats() {
; CHECK: __0:
; Test float and double constants
%v0 = fadd float 1.0, 0.0
; CHECK-NEXT: %__0 = fadd float 1.000000e+00, 0.000000e+00
%v1 = fadd double 1.0, 0.0
; CHECK-NEXT: %__1 = fadd double 1.000000e+00, 0.000000e+00
%v2 = fsub float 7.000000e+00, 8.000000e+00
; CHECK-NEXT: %__2 = fsub float 7.000000e+00, 8.000000e+00
%v3 = fsub double 5.000000e+00, 6.000000e+00
; CHECK-NEXT: %__3 = fsub double 5.000000e+00, 6.000000e+00
; Test undefined float and double.
%v4 = fadd float undef, 0.0
; CHECK-NEXT: %__4 = fadd float undef, 0.000000e+00
%v5 = fsub double undef, 6.000000e+00
; CHECK-NEXT: %__5 = fsub double undef, 6.000000e+00
; Test special floating point constants. Note: LLVM assembly appears
; to use 64-bit integer constants for both float and double.
; Generated from NAN in <math.h>
%v6 = fadd float 0x7FF8000000000000, 0.0
; CHECK-NEXT: %__6 = fadd float nan, 0.000000e+00
; Generated from -NAN in <math.h>
%v7 = fadd float 0xFFF8000000000000, 0.0
; CHECK-NEXT: %__7 = fadd float -nan, 0.000000e+00
; Generated from INFINITY in <math.h>
%v8 = fadd float 0x7FF0000000000000, 0.0
; CHECK-NEXT: %__8 = fadd float inf, 0.000000e+00
; Generated from -INFINITY in <math.h>
%v9 = fadd float 0xFFF0000000000000, 0.0
; CHECK-NEXT: %__9 = fadd float -inf, 0.000000e+00
; Generated from FLT_MIN in <float.h>
%v10 = fadd float 0x381000000000000000, 0.0
; CHECK-NEXT: %__10 = fadd float 0.000000e+00, 0.000000e+00
; Generated from -FLT_MIN in <float.h>
%v11 = fadd float 0xb81000000000000000, 0.0
; CHECK-NEXT: %__11 = fadd float 0.000000e+00, 0.000000e+00
; Generated from FLT_MAX in <float.h>
%v12 = fadd float 340282346638528859811704183484516925440.000000, 0.0
; CHECK-NEXT: %__12 = fadd float 3.402823e+38, 0.000000e+00
; Generated from -FLT_MAX in <float.h>
%v13 = fadd float -340282346638528859811704183484516925440.000000, 0.0
; CHECK-NEXT: %__13 = fadd float -3.402823e+38, 0.000000e+00
; Generated from NAN in <math.h>
%v14 = fadd double 0x7FF8000000000000, 0.0
; CHECK-NEXT: %__14 = fadd double nan, 0.000000e+00
; Generated from -NAN in <math.h>
%v15 = fadd double 0xFFF8000000000000, 0.0
; CHECK-NEXT: %__15 = fadd double -nan, 0.000000e+00
; Generated from INFINITY in <math.h>
%v16 = fadd double 0x7FF0000000000000, 0.0
; CHECK-NEXT: %__16 = fadd double inf, 0.000000e+00
; Generated from -INFINITY in <math.h>
%v17 = fadd double 0xFFF0000000000000, 0.0
; CHECK-NEXT: %__17 = fadd double -inf, 0.000000e+00
; Generated from DBL_MIN in <float.h>
%v18 = fadd double 0x0010000000000000, 0.0
; CHECK-NEXT: %__18 = fadd double 2.225074e-308, 0.000000e+00
; Generated from -DBL_MIN in <float.h>
%v19 = fadd double 0x8010000000000000, 0.0
; CHECK-NEXT: %__19 = fadd double -2.225074e-308, 0.000000e+00
; Generated from DBL_MAX in <float.h>
%v20 = fadd double 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000, 0.0
; CHECK-NEXT: %__20 = fadd double 1.797693e+308, 0.000000e+00
; Generated from -DBL_MAX in <float.h>
%v21 = fadd double -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000, 0.0
; CHECK-NEXT: %__21 = fadd double -1.797693e+308, 0.000000e+00
ret void
; CHECK-NEXT: ret void
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment