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= \ ...@@ -61,6 +61,7 @@ SRCS= \
IceTargetLowering.cpp \ IceTargetLowering.cpp \
IceTargetLoweringX8632.cpp \ IceTargetLoweringX8632.cpp \
IceTranslator.cpp \ IceTranslator.cpp \
IceTypeConverter.cpp \
IceTypes.cpp \ IceTypes.cpp \
llvm2ice.cpp \ llvm2ice.cpp \
PNaClTranslator.cpp PNaClTranslator.cpp
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "IceOperand.h" #include "IceOperand.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
#include "IceTypes.h" #include "IceTypes.h"
#include "IceTypeConverter.h"
#include "llvm/IR/Constant.h" #include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
...@@ -54,12 +55,8 @@ template <typename T> static std::string LLVMObjectAsString(const T *O) { ...@@ -54,12 +55,8 @@ template <typename T> static std::string LLVMObjectAsString(const T *O) {
// //
class LLVM2ICEConverter { class LLVM2ICEConverter {
public: public:
LLVM2ICEConverter(Ice::GlobalContext *Ctx) LLVM2ICEConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext)
: Ctx(Ctx), Func(NULL), CurrentNode(NULL) { : Ctx(Ctx), Func(NULL), CurrentNode(NULL), TypeConverter(LLVMContext) {}
// All PNaCl pointer widths are 32 bits because of the sandbox
// model.
SubzeroPointerType = Ice::IceType_i32;
}
// Caller is expected to delete the returned Ice::Cfg object. // Caller is expected to delete the returned Ice::Cfg object.
Ice::Cfg *convertFunction(const Function *F) { Ice::Cfg *convertFunction(const Function *F) {
...@@ -67,7 +64,7 @@ public: ...@@ -67,7 +64,7 @@ public:
NodeMap.clear(); NodeMap.clear();
Func = new Ice::Cfg(Ctx); Func = new Ice::Cfg(Ctx);
Func->setFunctionName(F->getName()); Func->setFunctionName(F->getName());
Func->setReturnType(convertType(F->getReturnType())); Func->setReturnType(convertToIceType(F->getReturnType()));
Func->setInternal(F->hasInternalLinkage()); Func->setInternal(F->hasInternalLinkage());
// The initial definition/use of each arg is the entry node. // The initial definition/use of each arg is the entry node.
...@@ -102,12 +99,13 @@ public: ...@@ -102,12 +99,13 @@ public:
// global initializers. // global initializers.
Ice::Constant *convertConstant(const Constant *Const) { Ice::Constant *convertConstant(const Constant *Const) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(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)) { } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(Const)) {
return Ctx->getConstantInt(convertIntegerType(CI->getType()), return Ctx->getConstantInt(convertToIceType(CI->getType()),
CI->getZExtValue()); CI->getZExtValue());
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Const)) { } 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) if (Type == Ice::IceType_f32)
return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat()); return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat());
else if (Type == Ice::IceType_f64) else if (Type == Ice::IceType_f64)
...@@ -115,7 +113,7 @@ public: ...@@ -115,7 +113,7 @@ public:
llvm_unreachable("Unexpected floating point type"); llvm_unreachable("Unexpected floating point type");
return NULL; return NULL;
} else if (const UndefValue *CU = dyn_cast<UndefValue>(Const)) { } else if (const UndefValue *CU = dyn_cast<UndefValue>(Const)) {
return Ctx->getConstantUndef(convertType(CU->getType())); return Ctx->getConstantUndef(convertToIceType(CU->getType()));
} else { } else {
llvm_unreachable("Unhandled constant type"); llvm_unreachable("Unhandled constant type");
return NULL; return NULL;
...@@ -125,7 +123,7 @@ public: ...@@ -125,7 +123,7 @@ public:
private: private:
// LLVM values (instructions, etc.) are mapped directly to ICE variables. // LLVM values (instructions, etc.) are mapped directly to ICE variables.
// mapValueToIceVar has a version that forces an ICE type on the variable, // 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) { Ice::Variable *mapValueToIceVar(const Value *V, Ice::Type IceTy) {
if (IceTy == Ice::IceType_void) if (IceTy == Ice::IceType_void)
return NULL; return NULL;
...@@ -137,7 +135,7 @@ private: ...@@ -137,7 +135,7 @@ private:
} }
Ice::Variable *mapValueToIceVar(const Value *V) { Ice::Variable *mapValueToIceVar(const Value *V) {
return mapValueToIceVar(V, convertType(V->getType())); return mapValueToIceVar(V, convertToIceType(V->getType()));
} }
Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) { Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) {
...@@ -147,85 +145,12 @@ private: ...@@ -147,85 +145,12 @@ private:
return NodeMap[BB]; return NodeMap[BB];
} }
Ice::Type convertIntegerType(const IntegerType *IntTy) const { Ice::Type convertToIceType(Type *LLVMTy) const {
switch (IntTy->getBitWidth()) { Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy);
case 1: if (IceTy == Ice::IceType_NUM)
return Ice::IceType_i1; llvm::report_fatal_error(std::string("Invalid PNaCl type ") +
case 8: LLVMObjectAsString(LLVMTy));
return Ice::IceType_i8; return IceTy;
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;
} }
// Given an LLVM instruction and an operand number, produce the // Given an LLVM instruction and an operand number, produce the
...@@ -404,7 +329,8 @@ private: ...@@ -404,7 +329,8 @@ private:
Ice::Inst *convertIntToPtrInstruction(const IntToPtrInst *Inst) { Ice::Inst *convertIntToPtrInstruction(const IntToPtrInst *Inst) {
Ice::Operand *Src = convertOperand(Inst, 0); 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); return Ice::InstAssign::create(Func, Dest, Src);
} }
...@@ -622,7 +548,8 @@ private: ...@@ -622,7 +548,8 @@ private:
// PNaCl bitcode only contains allocas of byte-granular objects. // PNaCl bitcode only contains allocas of byte-granular objects.
Ice::Operand *ByteCount = convertValue(Inst->getArraySize()); Ice::Operand *ByteCount = convertValue(Inst->getArraySize());
uint32_t Align = Inst->getAlignment(); 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); return Ice::InstAlloca::create(Func, ByteCount, Align, Dest);
} }
...@@ -671,22 +598,22 @@ private: ...@@ -671,22 +598,22 @@ private:
Ice::GlobalContext *Ctx; Ice::GlobalContext *Ctx;
Ice::Cfg *Func; Ice::Cfg *Func;
Ice::CfgNode *CurrentNode; Ice::CfgNode *CurrentNode;
Ice::Type SubzeroPointerType;
std::map<const Value *, Ice::Variable *> VarMap; std::map<const Value *, Ice::Variable *> VarMap;
std::map<const BasicBlock *, Ice::CfgNode *> NodeMap; std::map<const BasicBlock *, Ice::CfgNode *> NodeMap;
Ice::TypeConverter TypeConverter;
}; };
} // end of anonymous namespace } // end of anonymous namespace
namespace Ice { namespace Ice {
void Converter::convertToIce(Module *Mod) { void Converter::convertToIce() {
if (!Ctx->getFlags().DisableGlobals) if (!Ctx->getFlags().DisableGlobals)
convertGlobals(Mod); convertGlobals();
convertFunctions(Mod); convertFunctions();
} }
void Converter::convertGlobals(Module *Mod) { void Converter::convertGlobals() {
OwningPtr<TargetGlobalInitLowering> GlobalLowering( OwningPtr<TargetGlobalInitLowering> GlobalLowering(
TargetGlobalInitLowering::createLowering(Ctx->getTargetArch(), Ctx)); TargetGlobalInitLowering::createLowering(Ctx->getTargetArch(), Ctx));
for (Module::const_global_iterator I = Mod->global_begin(), for (Module::const_global_iterator I = Mod->global_begin(),
...@@ -729,11 +656,11 @@ void Converter::convertGlobals(Module *Mod) { ...@@ -729,11 +656,11 @@ void Converter::convertGlobals(Module *Mod) {
GlobalLowering.reset(); GlobalLowering.reset();
} }
void Converter::convertFunctions(Module *Mod) { void Converter::convertFunctions() {
for (Module::const_iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) { for (Module::const_iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) {
if (I->empty()) if (I->empty())
continue; continue;
LLVM2ICEConverter FunctionConverter(Ctx); LLVM2ICEConverter FunctionConverter(Ctx, Mod->getContext());
Timer TConvert; Timer TConvert;
Cfg *Fcn = FunctionConverter.convertFunction(I); Cfg *Fcn = FunctionConverter.convertFunction(I);
......
...@@ -24,16 +24,18 @@ namespace Ice { ...@@ -24,16 +24,18 @@ namespace Ice {
class Converter : public Translator { class Converter : public Translator {
public: 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, /// Converts the LLVM Module to ICE. Sets exit status to false if successful,
/// true otherwise. /// true otherwise.
void convertToIce(llvm::Module *Mod); void convertToIce();
private: private:
llvm::Module *Mod;
// Converts globals to ICE, and then machine code. // Converts globals to ICE, and then machine code.
void convertGlobals(llvm::Module *Mod); void convertGlobals();
// Converts functions to ICE, and then machine code. // Converts functions to ICE, and then machine code.
void convertFunctions(llvm::Module *Mod); void convertFunctions();
Converter(const Converter &) LLVM_DELETED_FUNCTION; Converter(const Converter &) LLVM_DELETED_FUNCTION;
Converter &operator=(const Converter &) LLVM_DELETED_FUNCTION; Converter &operator=(const Converter &) LLVM_DELETED_FUNCTION;
}; };
......
...@@ -33,8 +33,6 @@ const struct InstArithmeticAttributes_ { ...@@ -33,8 +33,6 @@ const struct InstArithmeticAttributes_ {
ICEINSTARITHMETIC_TABLE ICEINSTARITHMETIC_TABLE
#undef X #undef X
}; };
const size_t InstArithmeticAttributesSize =
llvm::array_lengthof(InstArithmeticAttributes);
// Using non-anonymous struct so that array_lengthof works. // Using non-anonymous struct so that array_lengthof works.
const struct InstCastAttributes_ { const struct InstCastAttributes_ {
...@@ -46,7 +44,6 @@ const struct InstCastAttributes_ { ...@@ -46,7 +44,6 @@ const struct InstCastAttributes_ {
ICEINSTCAST_TABLE ICEINSTCAST_TABLE
#undef X #undef X
}; };
const size_t InstCastAttributesSize = llvm::array_lengthof(InstCastAttributes);
// Using non-anonymous struct so that array_lengthof works. // Using non-anonymous struct so that array_lengthof works.
const struct InstFcmpAttributes_ { const struct InstFcmpAttributes_ {
...@@ -58,7 +55,6 @@ const struct InstFcmpAttributes_ { ...@@ -58,7 +55,6 @@ const struct InstFcmpAttributes_ {
ICEINSTFCMP_TABLE ICEINSTFCMP_TABLE
#undef X #undef X
}; };
const size_t InstFcmpAttributesSize = llvm::array_lengthof(InstFcmpAttributes);
// Using non-anonymous struct so that array_lengthof works. // Using non-anonymous struct so that array_lengthof works.
const struct InstIcmpAttributes_ { const struct InstIcmpAttributes_ {
...@@ -70,7 +66,6 @@ const struct InstIcmpAttributes_ { ...@@ -70,7 +66,6 @@ const struct InstIcmpAttributes_ {
ICEINSTICMP_TABLE ICEINSTICMP_TABLE
#undef X #undef X
}; };
const size_t InstIcmpAttributesSize = llvm::array_lengthof(InstIcmpAttributes);
} // end of anonymous namespace } // end of anonymous namespace
...@@ -228,6 +223,13 @@ InstArithmetic::InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, ...@@ -228,6 +223,13 @@ InstArithmetic::InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest,
addSource(Source2); 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 { bool InstArithmetic::isCommutative() const {
return InstArithmeticAttributes[getOp()].IsCommutative; return InstArithmeticAttributes[getOp()].IsCommutative;
} }
......
...@@ -203,6 +203,7 @@ public: ...@@ -203,6 +203,7 @@ public:
InstArithmetic(Func, Op, Dest, Source1, Source2); InstArithmetic(Func, Op, Dest, Source1, Source2);
} }
OpKind getOp() const { return Op; } OpKind getOp() const { return Op; }
static const char *getOpName(OpKind Op);
bool isCommutative() const; bool isCommutative() const;
virtual void dump(const Cfg *Func) const; virtual void dump(const Cfg *Func) const;
static bool classof(const Inst *Inst) { static bool classof(const Inst *Inst) {
......
...@@ -29,13 +29,27 @@ class GlobalContext; ...@@ -29,13 +29,27 @@ class GlobalContext;
// machine instructions. // machine instructions.
class Translator { class Translator {
public: public:
Translator(GlobalContext *Ctx) : Ctx(Ctx), ErrorStatus(0) {} Translator(GlobalContext *Ctx, const ClFlags &Flags)
: Ctx(Ctx), Flags(Flags), ErrorStatus(0) {}
~Translator(); ~Translator();
bool getErrorStatus() const { return ErrorStatus; } 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: protected:
GlobalContext *Ctx; GlobalContext *Ctx;
const ClFlags &Flags;
// The exit status of the translation. False is successful. True // The exit status of the translation. False is successful. True
// otherwise. // otherwise.
bool ErrorStatus; bool ErrorStatus;
...@@ -49,13 +63,6 @@ protected: ...@@ -49,13 +63,6 @@ protected:
// that. // that.
llvm::OwningPtr<Cfg> Func; 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: private:
Translator(const Translator &) LLVM_DELETED_FUNCTION; Translator(const Translator &) LLVM_DELETED_FUNCTION;
Translator &operator=(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 { ...@@ -18,74 +18,203 @@ namespace Ice {
namespace { 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 TypeWidthInBytes;
size_t TypeAlignInBytes; size_t TypeAlignInBytes;
size_t TypeNumElements; size_t TypeNumElements;
Type TypeElementType; Type TypeElementType;
const char *DisplayString; const char *DisplayString;
} TypeAttributes[] = { };
const struct TypeAttributeFields TypeAttributes[] = {
#define X(tag, size, align, elts, elty, str) \ #define X(tag, size, align, elts, elty, str) \
{ size, align, elts, elty, str } \ { size, align, elts, elty, str } \
, ,
ICETYPE_TABLE ICETYPE_TABLE
#undef X #undef X
}; };
const size_t TypeAttributesSize = struct TypePropertyFields {
sizeof(TypeAttributes) / sizeof(*TypeAttributes); 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 } // end anonymous namespace
size_t typeWidthInBytes(Type Ty) { size_t typeWidthInBytes(Type Ty) {
size_t Width = 0;
size_t Index = static_cast<size_t>(Ty); size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) { if (Index < IceType_NUM)
Width = TypeAttributes[Index].TypeWidthInBytes; return TypeAttributes[Index].TypeWidthInBytes;
} else {
llvm_unreachable("Invalid type for typeWidthInBytes()"); llvm_unreachable("Invalid type for typeWidthInBytes()");
} return 0;
return Width;
} }
size_t typeAlignInBytes(Type Ty) { size_t typeAlignInBytes(Type Ty) {
size_t Align = 0;
size_t Index = static_cast<size_t>(Ty); size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) { if (Index < IceType_NUM)
Align = TypeAttributes[Index].TypeAlignInBytes; return TypeAttributes[Index].TypeAlignInBytes;
} else {
llvm_unreachable("Invalid type for typeAlignInBytes()"); llvm_unreachable("Invalid type for typeAlignInBytes()");
} return 1;
return Align;
} }
size_t typeNumElements(Type Ty) { size_t typeNumElements(Type Ty) {
size_t NumElements = 0;
size_t Index = static_cast<size_t>(Ty); size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) { if (Index < IceType_NUM)
NumElements = TypeAttributes[Index].TypeNumElements; return TypeAttributes[Index].TypeNumElements;
} else {
llvm_unreachable("Invalid type for typeNumElements()"); llvm_unreachable("Invalid type for typeNumElements()");
} return 1;
return NumElements;
} }
Type typeElementType(Type Ty) { Type typeElementType(Type Ty) {
Type ElementType = IceType_void;
size_t Index = static_cast<size_t>(Ty); size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) { if (Index < IceType_NUM)
ElementType = TypeAttributes[Index].TypeElementType; return TypeAttributes[Index].TypeElementType;
} else {
llvm_unreachable("Invalid type for typeElementType()"); llvm_unreachable("Invalid type for typeElementType()");
} return IceType_void;
return ElementType;
} }
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) { const char *typeString(Type Ty) {
size_t Index = static_cast<size_t>(Ty); size_t Index = static_cast<size_t>(Ty);
if (Index < TypeAttributesSize) { if (Index < IceType_NUM)
return TypeAttributes[Index].DisplayString; return TypeAttributes[Index].DisplayString;
}
llvm_unreachable("Invalid type for typeString"); llvm_unreachable("Invalid type for typeString");
return "???"; return "???";
} }
......
...@@ -35,4 +35,28 @@ ...@@ -35,4 +35,28 @@
X(IceType_v4f32, 16, 4, 4, IceType_f32, "<4 x float>") \ X(IceType_v4f32, 16, 4, 4, IceType_f32, "<4 x float>") \
//#define X(tag, size, align, elts, elty, str) //#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 #endif // SUBZERO_SRC_ICETYPES_DEF
...@@ -47,7 +47,16 @@ size_t typeNumElements(Type Ty); ...@@ -47,7 +47,16 @@ size_t typeNumElements(Type Ty);
Type typeElementType(Type Ty); Type typeElementType(Type Ty);
const char *typeString(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> template <typename StreamType>
inline StreamType &operator<<(StreamType &Str, const Type &Ty) { inline StreamType &operator<<(StreamType &Str, const Type &Ty) {
......
...@@ -22,7 +22,8 @@ namespace Ice { ...@@ -22,7 +22,8 @@ namespace Ice {
class PNaClTranslator : public Translator { class PNaClTranslator : public Translator {
public: 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 // Reads the PNaCl bitcode file and translates to ICE, which is then
// converted to machine code. Sets ErrorStatus to true if any // converted to machine code. Sets ErrorStatus to true if any
// errors occurred. // errors occurred.
......
...@@ -143,7 +143,7 @@ int main(int argc, char **argv) { ...@@ -143,7 +143,7 @@ int main(int argc, char **argv) {
Flags); Flags);
if (BuildOnRead) { if (BuildOnRead) {
Ice::PNaClTranslator Translator(&Ctx); Ice::PNaClTranslator Translator(&Ctx, Flags);
Translator.translate(IRFilename); Translator.translate(IRFilename);
return Translator.getErrorStatus(); return Translator.getErrorStatus();
} else { } else {
...@@ -163,8 +163,8 @@ int main(int argc, char **argv) { ...@@ -163,8 +163,8 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
Ice::Converter Converter(&Ctx); Ice::Converter Converter(Mod, &Ctx, Flags);
Converter.convertToIce(Mod); Converter.convertToIce();
return Converter.getErrorStatus(); 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