aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp
diff options
context:
space:
mode:
authorKarl Schimpf <kschimpf@google.com>2013-08-28 14:34:19 -0700
committerKarl Schimpf <kschimpf@google.com>2013-08-28 14:34:19 -0700
commit493d4ab9edba2be18c916d80aaa100a0e51e1f51 (patch)
tree0fe55c21475362e19e6aec0404633f26c89f314e /lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp
parent117111856d5cca5a0286792180ad9e241ea4d701 (diff)
Handle pointer conversions for call instructions.
This also should complete the changes associated with removing pointer cast instructions from the PNaCl bitcode file. BUG= https://code.google.com/p/nativeclient/issues/detail?id=3544 R=dschuff@chromium.org, jvoung@chromium.org Review URL: https://codereview.chromium.org/23482002
Diffstat (limited to 'lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp')
-rw-r--r--lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp63
1 files changed, 39 insertions, 24 deletions
diff --git a/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp b/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp
index 6624ad1d7c..2ac88c92a4 100644
--- a/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp
+++ b/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp
@@ -975,32 +975,47 @@ static bool WriteInstruction(const Instruction &I, unsigned InstID,
}
break;
case Instruction::Call: {
- const CallInst &CI = cast<CallInst>(I);
- PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
- FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
-
- Code = naclbitc::FUNC_CODE_INST_CALL;
-
- Vals.push_back((GetEncodedCallingConv(CI.getCallingConv()) << 1)
- | unsigned(CI.isTailCall()));
- pushValue(CI.getCalledValue(), InstID, Vals, VE, Stream); // Callee
-
- // Emit value #'s for the fixed parameters.
- for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
- // Check for labels (can happen with asm labels).
- if (FTy->getParamType(i)->isLabelTy())
- Vals.push_back(VE.getValueID(CI.getArgOperand(i)));
- else
- // fixed param.
- pushValue(CI.getArgOperand(i), InstID, Vals, VE, Stream);
+ // CALL: [cc, fnid, args...]
+ // PNaCl version 2: CALL_INDIRECT: [cc, fnid, fnty, args...]
+
+ const CallInst &Call = cast<CallInst>(I);
+ const Value* Callee = Call.getCalledValue();
+ Vals.push_back((GetEncodedCallingConv(Call.getCallingConv()) << 1)
+ | unsigned(Call.isTailCall()));
+
+ pushValue(Callee, InstID, Vals, VE, Stream);
+
+ switch (PNaClVersion) {
+ case 1:
+ Code = naclbitc::FUNC_CODE_INST_CALL;
+ break;
+ case 2:
+ if (Callee == VE.ElideCasts(Callee)) {
+ // Since the call pointer has not been elided, we know that
+ // the call pointer has the type signature of the called
+ // function. This implies that the reader can use the type
+ // signature of the callee to figure out how to add casts to
+ // the arguments.
+ Code = naclbitc::FUNC_CODE_INST_CALL;
+ } else {
+ // If the cast was elided, a pointer conversion to a pointer
+ // was applied, meaning that this is an indirect call. For the
+ // reader, this implies that we can't use the type signature
+ // of the callee to resolve elided call arguments, since it is
+ // not known. Hence, we must send the type signature to the
+ // reader.
+ Code = naclbitc::FUNC_CODE_INST_CALL_INDIRECT;
+ PointerType *FcnPtrType =
+ cast<PointerType>(Callee->getType());
+ FunctionType *FcnType =
+ cast<FunctionType>(FcnPtrType->getElementType());
+ Vals.push_back(VE.getTypeID(FcnType));
+ }
+ break;
}
- // Emit type/value pairs for varargs params.
- if (FTy->isVarArg()) {
- for (unsigned i = FTy->getNumParams(), e = CI.getNumArgOperands();
- i != e; ++i)
- // varargs
- pushValue(CI.getArgOperand(i), InstID, Vals, VE, Stream);
+ for (unsigned I = 0, E = Call.getNumArgOperands(); I < E; ++I) {
+ pushValue(Call.getArgOperand(I), InstID, Vals, VE, Stream);
}
break;
}