[cfe-commits] r95222 - /cfe/trunk/lib/CodeGen/CGObjCGNU.cpp

David Chisnall csdavec at swan.ac.uk
Wed Feb 3 07:59:03 PST 2010


Author: theraven
Date: Wed Feb  3 09:59:02 2010
New Revision: 95222

URL: http://llvm.org/viewvc/llvm-project?rev=95222&view=rev
Log:
First pass at adding GC support for GNU runtime.  GC ivar maps not yet constructed, GC flag not set.

Please don't try using this yet - the runtime support is still very immature and your code will almost certainly crash if you do.  


Modified:
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=95222&r1=95221&r2=95222&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Wed Feb  3 09:59:02 2010
@@ -55,6 +55,7 @@
   const llvm::PointerType *PtrToInt8Ty;
   const llvm::FunctionType *IMPTy;
   const llvm::PointerType *IdTy;
+  const llvm::PointerType *PtrToIdTy;
   QualType ASTIdTy;
   const llvm::IntegerType *IntTy;
   const llvm::PointerType *PtrTy;
@@ -71,6 +72,11 @@
   typedef std::pair<std::string, std::string> TypedSelector;
   std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors;
   llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors;
+  // Selectors that we don't emit in GC mode
+  Selector RetainSel, ReleaseSel, AutoreleaseSel;
+  // Functions used for GC.
+  llvm::Constant *IvarAssignFn, *StrongCastAssignFn, *MemMoveFn, *WeakReadFn, 
+    *WeakAssignFn, *GlobalAssignFn;
   // Some zeros used for GEPs in lots of places.
   llvm::Constant *Zeros[2];
   llvm::Constant *NULLPtr;
@@ -123,6 +129,10 @@
   llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
       const ObjCIvarDecl *Ivar);
   void EmitClassRef(const std::string &className);
+  llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, const llvm::Type *Ty){
+    if (V->getType() == Ty) return V;
+    return B.CreateBitCast(V, Ty);
+  }
 public:
   CGObjCGNU(CodeGen::CodeGenModule &cgm);
   virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
@@ -266,12 +276,54 @@
   } else {
     IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
   }
+  PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
 
   // IMP type
   std::vector<const llvm::Type*> IMPArgs;
   IMPArgs.push_back(IdTy);
   IMPArgs.push_back(SelectorTy);
   IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
+
+  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
+    // Get selectors needed in GC mode
+    RetainSel = GetNullarySelector("retain", CGM.getContext());
+    ReleaseSel = GetNullarySelector("release", CGM.getContext());
+    AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext());
+
+    // Get functions needed in GC mode
+
+    // id objc_assign_ivar(id, id, ptrdiff_t);
+    std::vector<const llvm::Type*> Args(1, IdTy);
+    Args.push_back(PtrToIdTy);
+    // FIXME: ptrdiff_t
+    Args.push_back(LongTy);
+    llvm::FunctionType *FTy = llvm::FunctionType::get(IdTy, Args, false);
+    IvarAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
+    // id objc_assign_strongCast (id, id*)
+    Args.pop_back();
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    StrongCastAssignFn = 
+        CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
+    // id objc_assign_global(id, id*);
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    GlobalAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
+    // id objc_assign_weak(id, id*);
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    WeakAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
+    // id objc_read_weak(id*);
+    Args.clear();
+    Args.push_back(PtrToIdTy);
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    WeakReadFn = CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
+    // void *objc_memmove_collectable(void*, void *, size_t);
+    Args.clear();
+    Args.push_back(PtrToInt8Ty);
+    Args.push_back(PtrToInt8Ty);
+    // FIXME: size_t
+    Args.push_back(LongTy);
+    FTy = llvm::FunctionType::get(IdTy, Args, false);
+    MemMoveFn = CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
+  }
 }
 
 // This has to perform the lookup every time, since posing and related
@@ -400,6 +452,14 @@
                                     bool IsClassMessage,
                                     const CallArgList &CallArgs,
                                     const ObjCMethodDecl *Method) {
+  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
+    if (Sel == RetainSel || Sel == AutoreleaseSel) {
+      return RValue::get(Receiver);
+    }
+    if (Sel == ReleaseSel) {
+      return RValue::get(0);
+    }
+  }
   llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
 
   CallArgList ActualArgs;
@@ -494,6 +554,14 @@
                                bool IsClassMessage,
                                const CallArgList &CallArgs,
                                const ObjCMethodDecl *Method) {
+  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
+    if (Sel == RetainSel || Sel == AutoreleaseSel) {
+      return RValue::get(Receiver);
+    }
+    if (Sel == ReleaseSel) {
+      return RValue::get(0);
+    }
+  }
   CGBuilderTy &Builder = CGF.Builder;
   IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
   llvm::Value *cmd;
@@ -1918,35 +1986,58 @@
 
 llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
                                           llvm::Value *AddrWeakObj) {
-  return 0;
+  CGBuilderTy B = CGF.Builder;
+  AddrWeakObj = EnforceType(B, AddrWeakObj, IdTy);
+  return B.CreateCall(WeakReadFn, AddrWeakObj);
 }
 
 void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
                                    llvm::Value *src, llvm::Value *dst) {
-  return;
+  CGBuilderTy B = CGF.Builder;
+  src = EnforceType(B, src, IdTy);
+  dst = EnforceType(B, dst, PtrToIdTy);
+  B.CreateCall2(WeakAssignFn, src, dst);
 }
 
 void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
                                      llvm::Value *src, llvm::Value *dst) {
-  return;
+  CGBuilderTy B = CGF.Builder;
+  src = EnforceType(B, src, IdTy);
+  dst = EnforceType(B, dst, PtrToIdTy);
+  B.CreateCall2(GlobalAssignFn, src, dst);
 }
 
 void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
                                    llvm::Value *src, llvm::Value *dst,
                                    llvm::Value *ivarOffset) {
-  return;
+  CGBuilderTy B = CGF.Builder;
+  src = EnforceType(B, src, IdTy);
+  dst = EnforceType(B, dst, PtrToIdTy);
+  B.CreateCall3(IvarAssignFn, src, dst, ivarOffset);
 }
 
 void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
                                          llvm::Value *src, llvm::Value *dst) {
-  return;
+  CGBuilderTy B = CGF.Builder;
+  src = EnforceType(B, src, IdTy);
+  dst = EnforceType(B, dst, PtrToIdTy);
+  B.CreateCall2(StrongCastAssignFn, src, dst);
 }
 
 void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                          llvm::Value *DestPtr,
                                          llvm::Value *SrcPtr,
                                          QualType Ty) {
-  return;
+  CGBuilderTy B = CGF.Builder;
+  DestPtr = EnforceType(B, DestPtr, IdTy);
+  SrcPtr = EnforceType(B, SrcPtr, PtrToIdTy);
+
+  std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
+  unsigned long size = TypeInfo.first/8;
+  // FIXME: size_t
+  llvm::Value *N = llvm::ConstantInt::get(LongTy, size);
+
+  B.CreateCall3(MemMoveFn, DestPtr, SrcPtr, N);
 }
 
 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(





More information about the cfe-commits mailing list