I misled Alkis: LLVM should have isnan, not isunordered.
[oota-llvm.git] / lib / VMCore / iCall.cpp
index 9ff6bb6fc8cd3e9a574631af409593af3e958dfb..9a81f7948f9f4fb210c03ee73a3a52c0c946d886 100644 (file)
-//===-- iCall.cpp - Implement the Call & Invoke instructions -----*- C++ -*--=//
+//===-- iCall.cpp - Implement the call & invoke instructions --------------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // This file implements the call and invoke instructions.
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/iOther.h"
+#include "llvm/iTerminators.h"
+#include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
-#include "llvm/Method.h"
+#include "llvm/Function.h"
+#include "llvm/Support/CallSite.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//                        CallInst Implementation
+//===----------------------------------------------------------------------===//
+
+void CallInst::init(Value *Func, const std::vector<Value*> &Params)
+{
+  Operands.reserve(1+Params.size());
+  Operands.push_back(Use(Func, this));
+
+  const FunctionType *FTy = 
+    cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
+
+  assert((Params.size() == FTy->getNumParams() || 
+          (FTy->isVarArg() && Params.size() > FTy->getNumParams())) &&
+        "Calling a function with bad signature");
+  for (unsigned i = 0; i != Params.size(); i++)
+    Operands.push_back(Use(Params[i], this));
+}
+
+void CallInst::init(Value *Func, Value *Actual)
+{
+  Operands.reserve(2);
+  Operands.push_back(Use(Func, this));
+  
+  const FunctionType *MTy = 
+    cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
+
+  assert((MTy->getNumParams() == 1 ||
+          (MTy->isVarArg() && MTy->getNumParams() == 0)) &&
+        "Calling a function with bad signature");
+  Operands.push_back(Use(Actual, this));
+}
+
+void CallInst::init(Value *Func)
+{
+  Operands.reserve(1);
+  Operands.push_back(Use(Func, this));
+  
+  const FunctionType *MTy = 
+    cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
+
+  assert(MTy->getNumParams() == 0 && "Calling a function with bad signature");
+}
+
+CallInst::CallInst(Value *Func, const std::vector<Value*> &Params, 
+                   const std::string &Name, Instruction *InsertBefore) 
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                ->getElementType())->getReturnType(),
+               Instruction::Call, Name, InsertBefore) {
+  init(Func, Params);
+}
+
+CallInst::CallInst(Value *Func, const std::vector<Value*> &Params, 
+                   const std::string &Name, BasicBlock *InsertAtEnd) 
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                ->getElementType())->getReturnType(),
+               Instruction::Call, Name, InsertAtEnd) {
+  init(Func, Params);
+}
+
+CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
+                   Instruction  *InsertBefore)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call, Name, InsertBefore) {
+  init(Func, Actual);
+}
+
+CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
+                   BasicBlock  *InsertAtEnd)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call, Name, InsertAtEnd) {
+  init(Func, Actual);
+}
 
-CallInst::CallInst(Method *m, vector<Value*> &params, 
-                   const string &Name) 
-  : Instruction(m->getReturnType(), Instruction::Call, Name), M(m, this) {
+CallInst::CallInst(Value *Func, const std::string &Name,
+                   Instruction *InsertBefore)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call, Name, InsertBefore) {
+  init(Func);
+}
 
-  const MethodType* MT = M->getMethodType();
-  const MethodType::ParamTypes &PL = MT->getParamTypes();
-  assert(params.size() == PL.size());
-#ifndef NDEBUG
-  MethodType::ParamTypes::const_iterator It = PL.begin();
-#endif
-  for (unsigned i = 0; i < params.size(); i++) {
-    assert(*It++ == params[i]->getType());
-    Params.push_back(Use(params[i], this));
-  }
+CallInst::CallInst(Value *Func, const std::string &Name,
+                   BasicBlock *InsertAtEnd)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call, Name, InsertAtEnd) {
+  init(Func);
 }
 
 CallInst::CallInst(const CallInst &CI) 
-  : Instruction(CI.getType(), Instruction::Call), M(CI.M, this) {
-  for (unsigned i = 0; i < CI.Params.size(); i++)
-    Params.push_back(Use(CI.Params[i], this));
-}
-
-void CallInst::dropAllReferences() { 
-  M = 0;
-  Params.clear(); 
-}
-
-bool CallInst::setOperand(unsigned i, Value *Val) {
-  if (i > Params.size()) return false;
-  if (i == 0) {
-    assert(Val->getValueType() == Value::MethodVal);
-    M = (Method*)Val;
-  } else {
-    // TODO: assert = method arg type
-    Params[i-1] = Val;
-  }
-  return true;
+  : Instruction(CI.getType(), Instruction::Call) {
+  Operands.reserve(CI.Operands.size());
+  for (unsigned i = 0; i < CI.Operands.size(); ++i)
+    Operands.push_back(Use(CI.Operands[i], this));
+}
+
+const Function *CallInst::getCalledFunction() const {
+  if (const Function *F = dyn_cast<Function>(Operands[0]))
+    return F;
+  if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0]))
+    return cast<Function>(CPR->getValue());
+  return 0;
+}
+Function *CallInst::getCalledFunction() {
+  if (Function *F = dyn_cast<Function>(Operands[0]))
+    return F;
+  if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0]))
+    return cast<Function>(CPR->getValue());
+  return 0;
+}
+
+
+//===----------------------------------------------------------------------===//
+//                        InvokeInst Implementation
+//===----------------------------------------------------------------------===//
+
+void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
+                      const std::vector<Value*> &Params)
+{
+  Operands.reserve(3+Params.size());
+  Operands.push_back(Use(Fn, this));
+  Operands.push_back(Use((Value*)IfNormal, this));
+  Operands.push_back(Use((Value*)IfException, this));
+  const FunctionType *MTy = 
+    cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
+  
+  assert((Params.size() == MTy->getNumParams()) || 
+        (MTy->isVarArg() && Params.size() > MTy->getNumParams()) &&
+        "Calling a function with bad signature");
+  
+  for (unsigned i = 0; i < Params.size(); i++)
+    Operands.push_back(Use(Params[i], this));
+}
+
+InvokeInst::InvokeInst(Value *Fn, BasicBlock *IfNormal,
+                      BasicBlock *IfException,
+                       const std::vector<Value*> &Params,
+                      const std::string &Name, Instruction *InsertBefore)
+  : TerminatorInst(cast<FunctionType>(cast<PointerType>(Fn->getType())
+                                   ->getElementType())->getReturnType(),
+                  Instruction::Invoke, Name, InsertBefore) {
+  init(Fn, IfNormal, IfException, Params);
+}
+
+InvokeInst::InvokeInst(Value *Fn, BasicBlock *IfNormal,
+                      BasicBlock *IfException,
+                       const std::vector<Value*> &Params,
+                      const std::string &Name, BasicBlock *InsertAtEnd)
+  : TerminatorInst(cast<FunctionType>(cast<PointerType>(Fn->getType())
+                                   ->getElementType())->getReturnType(),
+                  Instruction::Invoke, Name, InsertAtEnd) {
+  init(Fn, IfNormal, IfException, Params);
+}
+
+InvokeInst::InvokeInst(const InvokeInst &CI) 
+  : TerminatorInst(CI.getType(), Instruction::Invoke) {
+  Operands.reserve(CI.Operands.size());
+  for (unsigned i = 0; i < CI.Operands.size(); ++i)
+    Operands.push_back(Use(CI.Operands[i], this));
+}
+
+const Function *InvokeInst::getCalledFunction() const {
+  if (const Function *F = dyn_cast<Function>(Operands[0]))
+    return F;
+  if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0]))
+    return cast<Function>(CPR->getValue());
+  return 0;
+}
+Function *InvokeInst::getCalledFunction() {
+  if (Function *F = dyn_cast<Function>(Operands[0]))
+    return F;
+  if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0]))
+    return cast<Function>(CPR->getValue());
+  return 0;
+}
+
+Function *CallSite::getCalledFunction() const {
+  Value *Callee = getCalledValue();
+  if (Function *F = dyn_cast<Function>(Callee))
+    return F;
+  if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Callee))
+    return cast<Function>(CPR->getValue());
+  return 0;
 }