diff options
author | Karl Schimpf <kschimpf@google.com> | 2013-08-01 07:12:23 -0700 |
---|---|---|
committer | Karl Schimpf <kschimpf@google.com> | 2013-08-01 07:12:23 -0700 |
commit | b9657234ee8b1951db5977a8ffb55a2e5df6d76c (patch) | |
tree | da9f474ea4b35ff767b93715a13a3933f0355f39 /lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp | |
parent | 365546bcef14965546dc39ebcef35f07a897b9c5 (diff) |
Remove the inttoptr dependency from load instructions.
Elides inttoptr casts used (exclusively) in load instructions when
PNaClVersion=2. This is an incremental start on removing the inttoptr
instruction from the PNaCl wire format (See issue 3544 for more information
on the strategy of removing ptrtoint).
Also modifies PNaCl bitcode reader/writer to accept PNaClVersion=1 as supported,
and PNaClVersion=2 as unsupported but readable (allowing pnacl-freeze and
pnacl-thaw to work on such files).
Also allows command-line option --pnacl-version for setting PNaClVersion in the
PNaCl bitcode writer.
Also fixes some problems on PNaCl bitcode headers, using common support to
determine when the read/written PNaCl bitcode file is valid.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3544
R=jvoung@chromium.org
Review URL: https://codereview.chromium.org/5812155903377408
Diffstat (limited to 'lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp')
-rw-r--r-- | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp | 73 |
1 files changed, 62 insertions, 11 deletions
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp index 9c2f45ea56..40f8842b3b 100644 --- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp +++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp @@ -1301,6 +1301,46 @@ bool NaClBitcodeReader::ParseBitcodeInto(Module *M) { } } +// Returns true if error occured installing I into BB. +bool NaClBitcodeReader::InstallInstruction( + BasicBlock *BB, Instruction *I) { + // Add instruction to end of current BB. If there is no current BB, reject + // this file. + if (BB == 0) { + delete I; + return Error("Invalid instruction with no BB"); + } + BB->getInstList().push_back(I); + return false; +} + +Value *NaClBitcodeReader::ConvertOpToType(Value *Op, Type *T, BasicBlock *BB) { + // Note: Currently only knows how to add inttoptr type conversion, since + // this is the only elided instruction in the bitcode writer. + // TODO(kschimpf): Generalize this as we expand elided conversions. + Value *Conversion = 0; + Type *OpTy = Op->getType(); + if (OpTy == T) return Op; + + // Following while loop is only run once. It is used to break on + // erroneous conditions. + while (true) { + if (!OpTy->isIntegerTy()) break; + if (!T->isPointerTy()) break; + Instruction *I = CastInst::Create(Instruction::IntToPtr, Op, T); + if (InstallInstruction(BB, I)) break; + Conversion = I; + break; + } + if (Conversion == 0) { + std::string Message; + raw_string_ostream StrM(Message); + StrM << "Can't convert " << *Op << " to type " << *T << "\n"; + Error(StrM.str()); + } + return Conversion; +} + /// ParseFunctionBody - Lazily parse the specified function body block. bool NaClBitcodeReader::ParseFunctionBody(Function *F) { DEBUG(dbgs() << "-> ParseFunctionBody\n"); @@ -1602,13 +1642,29 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) { I = new AllocaInst(Type::getInt8Ty(Context), Size, (1 << Align) >> 1); break; } - case naclbitc::FUNC_CODE_INST_LOAD: { // LOAD: [op, align, vol] + case naclbitc::FUNC_CODE_INST_LOAD: { + // PNaCl version 1: LOAD: [op, align, vol] + // PNaCl version 2: LOAD: [op, align, vol, ty] unsigned OpNum = 0; Value *Op; - if (popValue(Record, &OpNum, NextValueNo, &Op) || - OpNum+2 != Record.size()) + if (popValue(Record, &OpNum, NextValueNo, &Op)) return Error("Invalid LOAD record"); - + switch (GetPNaClVersion()) { + case 1: + if (Record.size() != 3) + return Error("Invalid LOAD record"); + break; + case 2: { + if (Record.size() != 4) + return Error("Invalid LOAD record"); + // Add pointer cast to op. + Type *T = getTypeByID(Record[3]); + if (T == 0) + return Error("Invalid type for load instruction"); + Op = ConvertOpToType(Op, T->getPointerTo(), CurBB); + if (Op == 0) return true; + } + } I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1); break; } @@ -1677,13 +1733,8 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) { continue; } - // Add instruction to end of current BB. If there is no current BB, reject - // this file. - if (CurBB == 0) { - delete I; - return Error("Invalid instruction with no BB"); - } - CurBB->getInstList().push_back(I); + if (InstallInstruction(CurBB, I)) + return true; // If this was a terminator instruction, move to the next block. if (isa<TerminatorInst>(I)) { |