Commit d6064a1a by Karl Schimpf

Start processing function blocks.

Handle binops and returns. BUG= https://code.google.com/p/nativeclient/issues/detail?id=3894 R=jvoung@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/395193005
parent 89d7956d
......@@ -61,6 +61,7 @@ SRCS= \
IceTargetLowering.cpp \
IceTargetLoweringX8632.cpp \
IceTranslator.cpp \
IceTypeConverter.cpp \
IceTypes.cpp \
llvm2ice.cpp \
PNaClTranslator.cpp
......
......@@ -22,6 +22,7 @@
#include "IceOperand.h"
#include "IceTargetLowering.h"
#include "IceTypes.h"
#include "IceTypeConverter.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
......@@ -54,12 +55,8 @@ template <typename T> static std::string LLVMObjectAsString(const T *O) {
//
class LLVM2ICEConverter {
public:
LLVM2ICEConverter(Ice::GlobalContext *Ctx)
: Ctx(Ctx), Func(NULL), CurrentNode(NULL) {
// All PNaCl pointer widths are 32 bits because of the sandbox
// model.
SubzeroPointerType = Ice::IceType_i32;
}
LLVM2ICEConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext)
: Ctx(Ctx), Func(NULL), CurrentNode(NULL), TypeConverter(LLVMContext) {}
// Caller is expected to delete the returned Ice::Cfg object.
Ice::Cfg *convertFunction(const Function *F) {
......@@ -67,7 +64,7 @@ public:
NodeMap.clear();
Func = new Ice::Cfg(Ctx);
Func->setFunctionName(F->getName());
Func->setReturnType(convertType(F->getReturnType()));
Func->setReturnType(convertToIceType(F->getReturnType()));
Func->setInternal(F->hasInternalLinkage());
// The initial definition/use of each arg is the entry node.
......@@ -102,12 +99,13 @@ public:
// global initializers.
Ice::Constant *convertConstant(const Constant *Const) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(Const)) {
return Ctx->getConstantSym(convertType(GV->getType()), 0, GV->getName());
return Ctx->getConstantSym(convertToIceType(GV->getType()), 0,
GV->getName());
} else if (const ConstantInt *CI = dyn_cast<ConstantInt>(Const)) {
return Ctx->getConstantInt(convertIntegerType(CI->getType()),
return Ctx->getConstantInt(convertToIceType(CI->getType()),
CI->getZExtValue());
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Const)) {
Ice::Type Type = convertType(CFP->getType());
Ice::Type Type = convertToIceType(CFP->getType());
if (Type == Ice::IceType_f32)
return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat());
else if (Type == Ice::IceType_f64)
......@@ -115,7 +113,7 @@ public:
llvm_unreachable("Unexpected floating point type");
return NULL;
} else if (const UndefValue *CU = dyn_cast<UndefValue>(Const)) {
return Ctx->getConstantUndef(convertType(CU->getType()));
return Ctx->getConstantUndef(convertToIceType(CU->getType()));
} else {
llvm_unreachable("Unhandled constant type");
return NULL;
......@@ -125,7 +123,7 @@ public:
private:
// LLVM values (instructions, etc.) are mapped directly to ICE variables.
// mapValueToIceVar has a version that forces an ICE type on the variable,
// and a version that just uses convertType on V.
// and a version that just uses convertToIceType on V.
Ice::Variable *mapValueToIceVar(const Value *V, Ice::Type IceTy) {
if (IceTy == Ice::IceType_void)
return NULL;
......@@ -137,7 +135,7 @@ private:
}
Ice::Variable *mapValueToIceVar(const Value *V) {
return mapValueToIceVar(V, convertType(V->getType()));
return mapValueToIceVar(V, convertToIceType(V->getType()));
}
Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) {
......@@ -147,85 +145,12 @@ private:
return NodeMap[BB];
}
Ice::Type convertIntegerType(const IntegerType *IntTy) const {
switch (IntTy->getBitWidth()) {
case 1:
return Ice::IceType_i1;
case 8:
return Ice::IceType_i8;
case 16:
return Ice::IceType_i16;
case 32:
return Ice::IceType_i32;
case 64:
return Ice::IceType_i64;
default:
report_fatal_error(std::string("Invalid PNaCl int type: ") +
LLVMObjectAsString(IntTy));
return Ice::IceType_void;
}
}
Ice::Type convertVectorType(const VectorType *VecTy) const {
unsigned NumElements = VecTy->getNumElements();
const Type *ElementType = VecTy->getElementType();
if (ElementType->isFloatTy()) {
if (NumElements == 4)
return Ice::IceType_v4f32;
} else if (ElementType->isIntegerTy()) {
switch (cast<IntegerType>(ElementType)->getBitWidth()) {
case 1:
if (NumElements == 4)
return Ice::IceType_v4i1;
if (NumElements == 8)
return Ice::IceType_v8i1;
if (NumElements == 16)
return Ice::IceType_v16i1;
break;
case 8:
if (NumElements == 16)
return Ice::IceType_v16i8;
break;
case 16:
if (NumElements == 8)
return Ice::IceType_v8i16;
break;
case 32:
if (NumElements == 4)
return Ice::IceType_v4i32;
break;
}
}
report_fatal_error(std::string("Unhandled vector type: ") +
LLVMObjectAsString(VecTy));
return Ice::IceType_void;
}
Ice::Type convertType(const Type *Ty) const {
switch (Ty->getTypeID()) {
case Type::VoidTyID:
return Ice::IceType_void;
case Type::IntegerTyID:
return convertIntegerType(cast<IntegerType>(Ty));
case Type::FloatTyID:
return Ice::IceType_f32;
case Type::DoubleTyID:
return Ice::IceType_f64;
case Type::PointerTyID:
return SubzeroPointerType;
case Type::FunctionTyID:
return SubzeroPointerType;
case Type::VectorTyID:
return convertVectorType(cast<VectorType>(Ty));
default:
report_fatal_error(std::string("Invalid PNaCl type: ") +
LLVMObjectAsString(Ty));
}
llvm_unreachable("convertType");
return Ice::IceType_void;
Ice::Type convertToIceType(Type *LLVMTy) const {
Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy);
if (IceTy == Ice::IceType_NUM)
llvm::report_fatal_error(std::string("Invalid PNaCl type ") +
LLVMObjectAsString(LLVMTy));
return IceTy;
}
// Given an LLVM instruction and an operand number, produce the
......@@ -404,7 +329,8 @@ private:
Ice::Inst *convertIntToPtrInstruction(const IntToPtrInst *Inst) {
Ice::Operand *Src = convertOperand(Inst, 0);
Ice::Variable *Dest = mapValueToIceVar(Inst, SubzeroPointerType);
Ice::Variable *Dest =
mapValueToIceVar(Inst, TypeConverter.getIcePointerType());
return Ice::InstAssign::create(Func, Dest, Src);
}
......@@ -622,7 +548,8 @@ private:
// PNaCl bitcode only contains allocas of byte-granular objects.
Ice::Operand *ByteCount = convertValue(Inst->getArraySize());
uint32_t Align = Inst->getAlignment();
Ice::Variable *Dest = mapValueToIceVar(Inst, SubzeroPointerType);
Ice::Variable *Dest =
mapValueToIceVar(Inst, TypeConverter.getIcePointerType());
return Ice::InstAlloca::create(Func, ByteCount, Align, Dest);
}
......@@ -671,22 +598,22 @@ private:
Ice::GlobalContext *Ctx;
Ice::Cfg *Func;
Ice::CfgNode *CurrentNode;
Ice::Type SubzeroPointerType;
std::map<const Value *, Ice::Variable *> VarMap;
std::map<const BasicBlock *, Ice::CfgNode *> NodeMap;
Ice::TypeConverter TypeConverter;
};
} // end of anonymous namespace
namespace Ice {
void Converter::convertToIce(Module *Mod) {
void Converter::convertToIce() {
if (!Ctx->getFlags().DisableGlobals)
convertGlobals(Mod);
convertFunctions(Mod);
convertGlobals();
convertFunctions();
}
void Converter::convertGlobals(Module *Mod) {
void Converter::convertGlobals() {
OwningPtr<TargetGlobalInitLowering> GlobalLowering(
TargetGlobalInitLowering::createLowering(Ctx->getTargetArch(), Ctx));
for (Module::const_global_iterator I = Mod->global_begin(),
......@@ -729,11 +656,11 @@ void Converter::convertGlobals(Module *Mod) {
GlobalLowering.reset();
}
void Converter::convertFunctions(Module *Mod) {
void Converter::convertFunctions() {
for (Module::const_iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) {
if (I->empty())
continue;
LLVM2ICEConverter FunctionConverter(Ctx);
LLVM2ICEConverter FunctionConverter(Ctx, Mod->getContext());
Timer TConvert;
Cfg *Fcn = FunctionConverter.convertFunction(I);
......
......@@ -24,16 +24,18 @@ namespace Ice {
class Converter : public Translator {
public:
Converter(GlobalContext *Ctx) : Translator(Ctx) {}
Converter(llvm::Module *Mod, GlobalContext *Ctx, const Ice::ClFlags &Flags)
: Translator(Ctx, Flags), Mod(Mod) {}
/// Converts the LLVM Module to ICE. Sets exit status to false if successful,
/// true otherwise.
void convertToIce(llvm::Module *Mod);
void convertToIce();
private:
llvm::Module *Mod;
// Converts globals to ICE, and then machine code.
void convertGlobals(llvm::Module *Mod);
void convertGlobals();
// Converts functions to ICE, and then machine code.
void convertFunctions(llvm::Module *Mod);
void convertFunctions();
Converter(const Converter &) LLVM_DELETED_FUNCTION;
Converter &operator=(const Converter &) LLVM_DELETED_FUNCTION;
};
......
......@@ -33,8 +33,6 @@ const struct InstArithmeticAttributes_ {
ICEINSTARITHMETIC_TABLE
#undef X
};
const size_t InstArithmeticAttributesSize =
llvm::array_lengthof(InstArithmeticAttributes);
// Using non-anonymous struct so that array_lengthof works.
const struct InstCastAttributes_ {
......@@ -46,7 +44,6 @@ const struct InstCastAttributes_ {
ICEINSTCAST_TABLE
#undef X
};
const size_t InstCastAttributesSize = llvm::array_lengthof(InstCastAttributes);
// Using non-anonymous struct so that array_lengthof works.
const struct InstFcmpAttributes_ {
......@@ -58,7 +55,6 @@ const struct InstFcmpAttributes_ {
ICEINSTFCMP_TABLE
#undef X
};
const size_t InstFcmpAttributesSize = llvm::array_lengthof(InstFcmpAttributes);
// Using non-anonymous struct so that array_lengthof works.
const struct InstIcmpAttributes_ {
......@@ -70,7 +66,6 @@ const struct InstIcmpAttributes_ {
ICEINSTICMP_TABLE
#undef X
};
const size_t InstIcmpAttributesSize = llvm::array_lengthof(InstIcmpAttributes);
} // end of anonymous namespace
......@@ -228,6 +223,13 @@ InstArithmetic::InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest,
addSource(Source2);
}
const char *InstArithmetic::getOpName(OpKind Op) {
size_t OpIndex = static_cast<size_t>(Op);
return OpIndex < InstArithmetic::_num
? InstArithmeticAttributes[OpIndex].DisplayString
: "???";
}
bool InstArithmetic::isCommutative() const {
return InstArithmeticAttributes[getOp()].IsCommutative;
}
......
......@@ -203,6 +203,7 @@ public:
InstArithmetic(Func, Op, Dest, Source1, Source2);
}
OpKind getOp() const { return Op; }
static const char *getOpName(OpKind Op);
bool isCommutative() const;
virtual void dump(const Cfg *Func) const;
static bool classof(const Inst *Inst) {
......
......@@ -29,13 +29,27 @@ class GlobalContext;
// machine instructions.
class Translator {
public:
Translator(GlobalContext *Ctx) : Ctx(Ctx), ErrorStatus(0) {}
Translator(GlobalContext *Ctx, const ClFlags &Flags)
: Ctx(Ctx), Flags(Flags), ErrorStatus(0) {}
~Translator();
bool getErrorStatus() const { return ErrorStatus; }
GlobalContext *getContext() const { return Ctx; }
const ClFlags &getFlags() const { return Flags; }
/// Translates the constructed ICE function Fcn to machine code.
/// Takes ownership of Fcn. Note: As a side effect, Field Func is
/// set to Fcn.
void translateFcn(Cfg *Fcn);
/// Emits the constant pool.
void emitConstants();
protected:
GlobalContext *Ctx;
const ClFlags &Flags;
// The exit status of the translation. False is successful. True
// otherwise.
bool ErrorStatus;
......@@ -49,13 +63,6 @@ protected:
// that.
llvm::OwningPtr<Cfg> Func;
/// Translates the constructed ICE function Fcn to machine code.
/// Note: As a side effect, Field Func is set to Fcn.
void translateFcn(Cfg *Fcn);
/// Emits the constant pool.
void emitConstants();
private:
Translator(const Translator &) LLVM_DELETED_FUNCTION;
Translator &operator=(const Translator &) LLVM_DELETED_FUNCTION;
......
//===- subzero/src/IceTypeConverter.cpp - Convert ICE/LLVM Types ----------===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements how to convert LLVM types to ICE types, and ICE types
// to LLVM types.
//
//===----------------------------------------------------------------------===//
#include "IceTypeConverter.h"
#include "llvm/Support/raw_ostream.h"
namespace Ice {
TypeConverter::TypeConverter(llvm::LLVMContext &Context) : Context(Context) {
AddLLVMType(IceType_void, llvm::Type::getVoidTy(Context));
AddLLVMType(IceType_i1, llvm::IntegerType::get(Context, 1));
AddLLVMType(IceType_i8, llvm::IntegerType::get(Context, 8));
AddLLVMType(IceType_i16, llvm::IntegerType::get(Context, 16));
AddLLVMType(IceType_i32, llvm::IntegerType::get(Context, 32));
AddLLVMType(IceType_i64, llvm::IntegerType::get(Context, 64));
AddLLVMType(IceType_f32, llvm::Type::getFloatTy(Context));
AddLLVMType(IceType_f64, llvm::Type::getDoubleTy(Context));
AddLLVMType(IceType_v4i1, llvm::VectorType::get(LLVMTypes[IceType_i1], 4));
AddLLVMType(IceType_v8i1, llvm::VectorType::get(LLVMTypes[IceType_i1], 8));
AddLLVMType(IceType_v16i1, llvm::VectorType::get(LLVMTypes[IceType_i1], 16));
AddLLVMType(IceType_v16i8, llvm::VectorType::get(LLVMTypes[IceType_i8], 16));
AddLLVMType(IceType_v8i16, llvm::VectorType::get(LLVMTypes[IceType_i16], 8));
AddLLVMType(IceType_v4i32, llvm::VectorType::get(LLVMTypes[IceType_i32], 4));
AddLLVMType(IceType_v4f32, llvm::VectorType::get(LLVMTypes[IceType_f32], 4));
assert(LLVMTypes.size() == static_cast<size_t>(IceType_NUM));
}
void TypeConverter::AddLLVMType(Type Ty, llvm::Type *LLVMTy) {
assert(static_cast<size_t>(Ty) == LLVMTypes.size());
LLVMTypes.push_back(LLVMTy);
LLVM2IceMap[LLVMTy] = Ty;
}
Type TypeConverter::convertToIceTypeOther(llvm::Type *LLVMTy) const {
switch (LLVMTy->getTypeID()) {
case llvm::Type::PointerTyID:
case llvm::Type::FunctionTyID:
return getIcePointerType();
default:
return Ice::IceType_NUM;
}
}
llvm::Type *TypeConverter::getLLVMIntegerType(unsigned NumBits) const {
switch (NumBits) {
case 1:
return LLVMTypes[IceType_i1];
case 8:
return LLVMTypes[IceType_i8];
case 16:
return LLVMTypes[IceType_i16];
case 32:
return LLVMTypes[IceType_i32];
case 64:
return LLVMTypes[IceType_i64];
default:
return NULL;
}
}
llvm::Type *TypeConverter::getLLVMVectorType(unsigned Size, Type Ty) const {
switch (Ty) {
case IceType_i1:
switch (Size) {
case 4:
return convertToLLVMType(IceType_v4i1);
case 8:
return convertToLLVMType(IceType_v8i1);
case 16:
return convertToLLVMType(IceType_v16i1);
default:
break;
}
break;
case IceType_i8:
if (Size == 16)
return convertToLLVMType(IceType_v16i8);
break;
case IceType_i16:
if (Size == 8)
return convertToLLVMType(IceType_v8i16);
break;
case IceType_i32:
if (Size == 4)
return convertToLLVMType(IceType_v4i32);
break;
case IceType_f32:
if (Size == 4)
return convertToLLVMType(IceType_v4f32);
break;
default:
break;
}
return NULL;
}
} // end of Ice namespace.
//===- subzero/src/IceTypeConverter.h - Convert ICE/LLVM Types --*- C++ -*-===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines how to convert LLVM types to ICE types, and ICE types
// to LLVM types.
//
//===----------------------------------------------------------------------===//
#ifndef SUBZERO_SRC_ICETYPECONVERTER_H
#define SUBZERO_SRC_ICETYPECONVERTER_H
#include "IceDefs.h"
#include "IceTypes.h"
#include "llvm/IR/DerivedTypes.h"
namespace llvm {
class LLVMContext;
} // end of llvm namespace.
namespace Ice {
/// Converts LLVM types to ICE types, and ICE types to LLVM types.
class TypeConverter {
TypeConverter(const TypeConverter &) LLVM_DELETED_FUNCTION;
TypeConverter &operator=(const TypeConverter &) LLVM_DELETED_FUNCTION;
public:
/// Context is the context to use to build llvm types.
TypeConverter(llvm::LLVMContext &Context);
/// Returns the LLVM type for the corresponding ICE type Ty.
llvm::Type *convertToLLVMType(Type Ty) const {
// Note: We use "at" here in case Ty wasn't registered.
return LLVMTypes.at(Ty);
}
/// Converts LLVM type LLVMTy to an ICE type. Returns
/// Ice::IceType_NUM if unable to convert.
Type convertToIceType(llvm::Type *LLVMTy) const {
std::map<llvm::Type *, Type>::const_iterator Pos = LLVM2IceMap.find(LLVMTy);
if (Pos == LLVM2IceMap.end())
return convertToIceTypeOther(LLVMTy);
return Pos->second;
}
/// Returns ICE model of pointer type.
Type getIcePointerType() const { return IceType_i32; }
/// Returns LLVM integer type with specified number of bits. Returns
/// NULL if not a valid PNaCl integer type.
llvm::Type *getLLVMIntegerType(unsigned NumBits) const;
/// Returns the LLVM vector type for Size and Ty arguments. Returns
/// NULL if not a valid PNaCl vector type.
llvm::Type *getLLVMVectorType(unsigned Size, Type Ty) const;
private:
// The LLVM context to use to build LLVM types.
llvm::LLVMContext &Context;
// The list of allowable LLVM types. Indexed by ICE type.
std::vector<llvm::Type *> LLVMTypes;
// The inverse mapping of LLVMTypes.
std::map<llvm::Type *, Type> LLVM2IceMap;
// Add LLVM/ICE pair to internal tables.
void AddLLVMType(Type Ty, llvm::Type *LLVMTy);
// Converts types not in LLVM2IceMap.
Type convertToIceTypeOther(llvm::Type *LLVMTy) const;
};
} // end of Ice namespace.
#endif // SUBZERO_SRC_ICETYPECONVERTER_H
......@@ -18,74 +18,203 @@ namespace Ice {
namespace {
const struct {
// Dummy function to make sure the two type tables have the same
// enumerated types.
void __attribute__((unused)) xIceTypeMacroIntegrityCheck() {
// Show tags match between ICETYPE_TABLE and ICETYPE_PROPS_TABLE.
// Define a temporary set of enum values based on ICETYPE_TABLE
enum {
#define X(tag, size, align, elts, elty, str) _table_tag_##tag,
ICETYPE_TABLE
#undef X
_enum_table_tag_Names
};
// Define a temporary set of enum values based on ICETYPE_PROPS_TABLE
enum {
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) _props_table_tag_##tag,
ICETYPE_PROPS_TABLE
#undef X
_enum_props_table_tag_Names
};
// Assert that tags in ICETYPE_TABLE are also in ICETYPE_PROPS_TABLE.
#define X(tag, size, align, elts, elty, str) \
STATIC_ASSERT((unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag);
ICETYPE_TABLE;
#undef X
// Assert that tags in ICETYPE_PROPS_TABLE is in ICETYPE_TABLE.
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \
STATIC_ASSERT((unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag);
ICETYPE_PROPS_TABLE;
#undef X
// Show vector definitions match in ICETYPE_TABLE and
// ICETYPE_PROPS_TABLE.
// Define constants for each element size in ICETYPE_TABLE.
enum {
#define X(tag, size, align, elts, elty, str) _table_elts_##tag = elts,
ICETYPE_TABLE
#undef X
_enum_table_elts_Elements = 0
};
// Define constants for boolean flag if vector in ICETYPE_PROPS_TABLE.
enum {
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \
_props_table_IsVec_##tag = IsVec,
ICETYPE_PROPS_TABLE
#undef X
};
// Verify that the number of vector elements is consistent with IsVec.
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \
STATIC_ASSERT((_table_elts_##tag > 1) == _props_table_IsVec_##tag);
ICETYPE_PROPS_TABLE;
#undef X
}
struct TypeAttributeFields {
size_t TypeWidthInBytes;
size_t TypeAlignInBytes;
size_t TypeNumElements;
Type TypeElementType;
const char *DisplayString;
} TypeAttributes[] = {
};
const struct TypeAttributeFields TypeAttributes[] = {
#define X(tag, size, align, elts, elty, str) \
{ size, align, elts, elty, str } \
,
ICETYPE_TABLE
#undef X
};
};
const size_t TypeAttributesSize =
sizeof(TypeAttributes) / sizeof(*TypeAttributes);
struct TypePropertyFields {
bool TypeIsVectorType;
bool TypeIsIntegerType;
bool TypeIsScalarIntegerType;
bool TypeIsVectorIntegerType;
bool TypeIsIntegerArithmeticType;
bool TypeIsFloatingType;
bool TypeIsScalarFloatingType;
bool TypeIsVectorFloatingType;
};
const TypePropertyFields TypePropertiesTable[] = {
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \
{ \
IsVec, IsInt, IsInt && !IsVec, IsInt && IsVec, IsIntArith, IsFloat, \
IsFloat && !IsVec, IsFloat && IsVec \
} \
,
ICETYPE_PROPS_TABLE
#undef X
};
} // end anonymous namespace
size_t typeWidthInBytes(Type Ty) {
size_t Width = 0;
size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) {
Width = TypeAttributes[Index].TypeWidthInBytes;
} else {
llvm_unreachable("Invalid type for typeWidthInBytes()");
}
return Width;
if (Index < IceType_NUM)
return TypeAttributes[Index].TypeWidthInBytes;
llvm_unreachable("Invalid type for typeWidthInBytes()");
return 0;
}
size_t typeAlignInBytes(Type Ty) {
size_t Align = 0;
size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) {
Align = TypeAttributes[Index].TypeAlignInBytes;
} else {
llvm_unreachable("Invalid type for typeAlignInBytes()");
}
return Align;
if (Index < IceType_NUM)
return TypeAttributes[Index].TypeAlignInBytes;
llvm_unreachable("Invalid type for typeAlignInBytes()");
return 1;
}
size_t typeNumElements(Type Ty) {
size_t NumElements = 0;
size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) {
NumElements = TypeAttributes[Index].TypeNumElements;
} else {
llvm_unreachable("Invalid type for typeNumElements()");
}
return NumElements;
if (Index < IceType_NUM)
return TypeAttributes[Index].TypeNumElements;
llvm_unreachable("Invalid type for typeNumElements()");
return 1;
}
Type typeElementType(Type Ty) {
Type ElementType = IceType_void;
size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) {
ElementType = TypeAttributes[Index].TypeElementType;
} else {
llvm_unreachable("Invalid type for typeElementType()");
}
return ElementType;
if (Index < IceType_NUM)
return TypeAttributes[Index].TypeElementType;
llvm_unreachable("Invalid type for typeElementType()");
return IceType_void;
}
bool isVectorType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].TypeIsVectorType;
llvm_unreachable("Invalid type for isVectorType()");
return false;
}
bool isIntegerType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].TypeIsIntegerType;
llvm_unreachable("Invalid type for isIntegerType()");
return false;
}
bool isScalarIntegerType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].TypeIsScalarIntegerType;
llvm_unreachable("Invalid type for isScalIntegerType()");
return false;
}
bool isVectorIntegerType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].TypeIsVectorIntegerType;
llvm_unreachable("Invalid type for isVectorIntegerType()");
return false;
}
bool isIntegerArithmeticType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].TypeIsIntegerArithmeticType;
llvm_unreachable("Invalid type for isIntegerArithmeticType()");
return false;
}
bool isFloatingType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].TypeIsFloatingType;
llvm_unreachable("Invalid type for isFloatingType()");
return false;
}
bool isScalarFloatingType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].TypeIsScalarFloatingType;
llvm_unreachable("Invalid type for isScalarFloatingType()");
return false;
}
bool isVectorFloatingType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].TypeIsVectorFloatingType;
llvm_unreachable("Invalid type for isVectorFloatingType()");
return false;
}
// ======================== Dump routines ======================== //
const char *typeString(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) {
if (Index < IceType_NUM)
return TypeAttributes[Index].DisplayString;
}
llvm_unreachable("Invalid type for typeString");
return "???";
}
......
......@@ -35,4 +35,28 @@
X(IceType_v4f32, 16, 4, 4, IceType_f32, "<4 x float>") \
//#define X(tag, size, align, elts, elty, str)
// Dictionary:
// V - Is vector type.
// I - Is integer value (scalar or vector).
// F - Is floating point value (scalar or vector).
// IA - Is integer arithmetic type
#define ICETYPE_PROPS_TABLE \
/* Enum Value V I F IA */ \
X(IceType_void, 0, 0, 0, 0) \
X(IceType_i1, 0, 1, 0, 0) \
X(IceType_i8, 0, 1, 0, 1) \
X(IceType_i16, 0, 1, 0, 1) \
X(IceType_i32, 0, 1, 0, 1) \
X(IceType_i64, 0, 1, 0, 1) \
X(IceType_f32, 0, 0, 1, 0) \
X(IceType_f64, 0, 0, 1, 0) \
X(IceType_v4i1, 1, 1, 0, 0) \
X(IceType_v8i1, 1, 1, 0, 0) \
X(IceType_v16i1, 1, 1, 0, 0) \
X(IceType_v16i8, 1, 1, 0, 1) \
X(IceType_v8i16, 1, 1, 0, 1) \
X(IceType_v4i32, 1, 1, 0, 1) \
X(IceType_v4f32, 1, 0, 1, 0) \
//#define X(tag, IsVec, IsInt, IsFloat, IsIntArith)
#endif // SUBZERO_SRC_ICETYPES_DEF
......@@ -47,7 +47,16 @@ size_t typeNumElements(Type Ty);
Type typeElementType(Type Ty);
const char *typeString(Type Ty);
inline bool isVectorType(Type Ty) { return typeNumElements(Ty) > 1; }
bool isVectorType(Type Ty);
bool isIntegerType(Type Ty); // scalar or vector
bool isScalarIntegerType(Type Ty);
bool isVectorIntegerType(Type Ty);
bool isIntegerArithmeticType(Type Ty);
bool isFloatingType(Type Ty); // scalar or vector
bool isScalarFloatingType(Type Ty);
bool isVectorFloatingType(Type Ty);
template <typename StreamType>
inline StreamType &operator<<(StreamType &Str, const Type &Ty) {
......
......@@ -22,7 +22,8 @@ namespace Ice {
class PNaClTranslator : public Translator {
public:
PNaClTranslator(GlobalContext *Ctx) : Translator(Ctx) {}
PNaClTranslator(GlobalContext *Ctx, const ClFlags &Flags)
: Translator(Ctx, Flags) {}
// Reads the PNaCl bitcode file and translates to ICE, which is then
// converted to machine code. Sets ErrorStatus to true if any
// errors occurred.
......
......@@ -143,7 +143,7 @@ int main(int argc, char **argv) {
Flags);
if (BuildOnRead) {
Ice::PNaClTranslator Translator(&Ctx);
Ice::PNaClTranslator Translator(&Ctx, Flags);
Translator.translate(IRFilename);
return Translator.getErrorStatus();
} else {
......@@ -163,8 +163,8 @@ int main(int argc, char **argv) {
return 1;
}
Ice::Converter Converter(&Ctx);
Converter.convertToIce(Mod);
Ice::Converter Converter(Mod, &Ctx, Flags);
Converter.convertToIce();
return Converter.getErrorStatus();
}
}
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