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

Unified Diff: src/PNaClTranslator.cpp

Issue 561883002: Add load and store instructions to Subzero bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix isses in patch set 2. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceTypes.def ('k') | tests_lit/reader_tests/load.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/PNaClTranslator.cpp
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index bde906ab8bee81be43aecfe6bb1f611ace8b6628..c83898debeb566f29ca9d56ecc70d58497d30a67 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -20,11 +20,13 @@
#include "IceInst.h"
#include "IceOperand.h"
#include "IceTypeConverter.h"
+#include "llvm/Analysis/NaCl/PNaClABIProps.h"
#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
#include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Format.h"
@@ -55,9 +57,10 @@ public:
NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor,
bool &ErrorStatus)
: NaClBitcodeParser(Cursor), Translator(Translator),
- Mod(new Module(InputName, getGlobalContext())), Header(Header),
- TypeConverter(getLLVMContext()), ErrorStatus(ErrorStatus), NumErrors(0),
- NumFunctionIds(0), NumFunctionBlocks(0),
+ Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout),
+ Header(Header), TypeConverter(getLLVMContext()),
+ ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0),
+ NumFunctionBlocks(0),
GlobalVarPlaceHolderType(convertToLLVMType(Ice::IceType_i8)) {
Mod->setDataLayout(PNaClDataLayout);
}
@@ -84,6 +87,8 @@ public:
/// Returns the LLVM module associated with the translation.
Module *getModule() const { return Mod.get(); }
+ const DataLayout &getDataLayout() const { return DL; }
+
/// Returns the number of bytes in the bitcode header.
size_t getHeaderSize() const { return Header.getHeaderSize(); }
@@ -228,6 +233,8 @@ private:
Ice::Translator &Translator;
// The parsed module.
OwningPtr<Module> Mod;
+ // The data layout to use.
+ DataLayout DL;
// The bitcode header.
NaClBitcodeHeader &Header;
// Converter between LLVM and ICE types.
@@ -848,6 +855,24 @@ private:
// Upper limit of alignment power allowed by LLVM
static const uint64_t AlignPowerLimit = 29;
+ // 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.
+ void extractAlignment(const char *InstName, uint64_t AlignPower,
+ unsigned &Alignment) {
+ if (AlignPower <= AlignPowerLimit) {
+ Alignment = (1 << static_cast<unsigned>(AlignPower)) >> 1;
+ return;
+ }
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit
+ << ". Found: 2**" << AlignPower;
+ Error(StrBuf.str());
+ // Error recover with value that is always acceptable.
+ Alignment = 1;
+ }
+
virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
virtual void ProcessRecord() LLVM_OVERRIDE;
@@ -959,8 +984,8 @@ private:
}
// Checks if floating arithmetic Op, for type OpTy, is valid.
- // Returns false if valid. Otherwise generates an error message and
- // returns true.
+ // Returns true if valid. Otherwise generates an error message and
+ // returns false;
bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
if (Ice::isFloatingType(OpTy))
return true;
@@ -968,6 +993,52 @@ private:
return false;
}
+ // Checks if the type of operand Op is the valid pointer type, for
+ // the given InstructionName. Returns true if valid. Otherwise
+ // generates an error message and returns false.
+ bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
+ Ice::Type PtrType = Context->getIcePointerType();
+ if (Op->getType() == PtrType)
+ return true;
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << InstructionName << " address not " << PtrType
+ << ". Found: " << Op;
+ Error(StrBuf.str());
+ return false;
+ }
+
+ // Checks if loading/storing a value of type Ty is allowed.
+ // Returns true if Valid. Otherwise generates an error message and
+ // returns false.
+ bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
+ if (isLoadStoreType(Ty))
+ return true;
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << InstructionName << " type not allowed: " << Ty << "*";
+ Error(StrBuf.str());
+ return false;
+ }
+
+ // Checks if loading/storing a value of type Ty is allowed for
+ // the given Alignment. Otherwise generates an error message and
+ // returns false.
+ bool isValidLoadStoreAlignment(unsigned Alignment, Ice::Type Ty,
+ const char *InstructionName) {
+ if (!isValidLoadStoreType(Ty, InstructionName))
+ return false;
+ if (PNaClABIProps::isAllowedAlignment(&Context->getDataLayout(), Alignment,
+ Context->convertToLLVMType(Ty)))
+ return true;
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
+ << Alignment;
+ Error(StrBuf.str());
+ return false;
+ }
+
// Reports that the given binary Opcode, for the given type Ty,
// is not understood.
void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty);
@@ -1529,22 +1600,46 @@ void FunctionParser::ProcessRecord() {
Error(StrBuf.str());
return;
}
- uint64_t AlignPower = Values[1];
- unsigned Alignment = 1;
- if (AlignPower <= AlignPowerLimit) {
- Alignment = (1 << static_cast<unsigned>(AlignPower)) >> 1;
- } else {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Alloca on alignment greater than 2**" << AlignPowerLimit
- << ". Found: 2**" << AlignPower;
- Error(StrBuf.str());
- // TODO(kschimpf) Remove error recovery once implementation complete.
- }
+ unsigned Alignment;
+ extractAlignment("Alloca", Values[1], Alignment);
Ice::Variable *Dest = NextInstVar(Context->getIcePointerType());
Inst = Ice::InstAlloca::create(Func, ByteCount, Alignment, Dest);
break;
}
+ case naclbitc::FUNC_CODE_INST_LOAD: {
+ // LOAD: [address, align, ty]
+ if (!isValidRecordSize(3, "function block load"))
+ return;
+ Ice::Operand *Address = getRelativeOperand(Values[0]);
+ if (!isValidPointerType(Address, "Load"))
+ return;
+ unsigned Alignment;
+ extractAlignment("Load", Values[1], Alignment);
+ Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2]));
+ if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
+ return;
+ Ice::Variable *Dest = NextInstVar(Ty);
+ Inst = Ice::InstLoad::create(Func, Dest, Address, Alignment);
+ break;
+ }
+ case naclbitc::FUNC_CODE_INST_STORE: {
+ // STORE: [address, value, align]
+ if (!isValidRecordSize(3, "function block store"))
+ return;
+ Ice::Operand *Address = getRelativeOperand(Values[0]);
+ if (!isValidPointerType(Address, "Store"))
+ return;
+ Ice::Operand *Value = getRelativeOperand(Values[1]);
+ unsigned Alignment;
+ if (!extractAlignment("Store", Values[2], Alignment)) {
+ // TODO(kschimpf) Remove error recovery once implementation complete.
+ Alignment = 1;
+ }
+ if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
+ return;
+ Inst = Ice::InstStore::create(Func, Value, Address, Alignment);
+ break;
+ }
default:
// Generate error message!
BlockParserBaseClass::ProcessRecord();
« no previous file with comments | « src/IceTypes.def ('k') | tests_lit/reader_tests/load.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698