2011-09-23 4 views
2

을 긴장하는 방법을, 내가 CreateEntryBlockAlloca를 사용하여 블록 범위의 시작 부분에 변수를 삽입 해요 :LLVM 예외; 순간

template <typename VariableType> 
      static inline llvm::AllocaInst *CreateEntryBlockAlloca(BuilderParameter& buildParameters, 
        const std::string &VarName) { 
       HAssertMsg(1 != 0 , "Not Implemented"); 
      }; 

      template <> 
       inline llvm::AllocaInst *CreateEntryBlockAlloca<double>(BuilderParameter& buildParameters, 
        const std::string &VarName) { 
       llvm::Function* TheFunction = buildParameters.dag.llvmFunction; 
       llvm::IRBuilder<> TmpB(&TheFunction->getEntryBlock(), 
         TheFunction->getEntryBlock().begin()); 
       return TmpB.CreateAlloca(llvm::Type::getDoubleTy(buildParameters.getLLVMContext()), 0, 
         VarName.c_str()); 
      } 

를 자, 내가 (즉, 소멸자/정리가 필요할 수 있습니다 비 POD 유형 Allocas를 추가 할 출구에서 기능). 그러나 exit 스코프 블록의 끝에서 소멸자 호출을 추가하는 것만으로는 충분하지 않습니다. 정규 DWARF 예외가 발생할 때 호출하는 방법이 명확하지 않기 때문입니다 (이 인수의 목적을 위해 예외는 POD 유형을 던지는 C++ 함수를 호출하는 호출 지점에서 던져 지므로 제 경우에는 무지가 행복합니다. 더 잘 이해하지 못하면 intrinsic llvm exceptions에서 멀리하고 싶습니다.

나는 Alloca 레지스터가있는 스택에서 오프셋이있는 테이블을 가질 수 있으며 (JIT 함수의 호출 지점에서 스택의 맨 아래에있는) 예외 처리기를 사용할 수 있다고 생각했습니다. 오프셋을 테이블에두고 소멸자를 적절하게 호출합니다.

내가 모르는 것은 CreateAlloca로 만든 Alloca'ed 레지스터의 오프셋을 쿼리하는 방법입니다. 어떻게해야합니까? 당신이 이것을 달성하기 위해 더 나은 방법이 생각하는 경우

또한,

  • 이 기술 코멘트 LLVM의 길을 가르치 려 사항 : JIT 코드가 boost::context 내에서 호출되고있는 만 try catch 내에서 JIT 코드를 호출하고 catch에서 아무 작업도 수행하지 않고 컨텍스트에서 빠져 나와 기본 실행 스택으로 돌아갑니다. 그 생각은 기본 실행 스택에서 unwinding을 처리하면 (스택 변수를 정리하는) 모든 함수는 종료 된 JIT 컨텍스트에서 동일한 스택 내용을 덮어 쓰지 않으므로 손상되지 않습니다. 내가 충분히 의미를 만들고있어 희망

답변

2

내가 모르는 것은이 CreateAlloca로 만든 Alloca'ed 레지스터의 오프셋을 쿼리하는 방법입니다. 나는 그것을 어떻게 안정적으로 할 수 있는가?

alloca의 주소를 직접 사용할 수 있습니다 ... 스택 프레임으로 오프셋을 가져 오는 간단한 방법은 없습니다.

왜 내재적 인 LLVM 예외를 사용하고 싶지 않으십니까? 정말 사용하기가 어렵지 않습니다. 특히 코드가 실제로 어떤 것도 잡아 내지 않는 간단한 경우에 특히 그렇습니다. 기본적으로 단순한 경우 clang이 생성하는 코드를 가져 와서 복사하여 붙여 넣을 수 있습니다.

편집 : , http://llvm.org/demo/에서 데모 페이지에 다음과 같은 C++ 코드를 붙여 시도 간단한 경우 IR에서 예외를 사용하는 방법을 보려면 :

class X { public: ~X() __attribute((nothrow)); }; 
void a(X* p); 
void b() { X x; a(&x); } 

그것은 정말 복잡하지 않습니다.

+0

이유는 다음과 같습니다. 프레임이 풀릴 때마다 소멸자를 작성하기위한 IR 코드를 어디서 어떻게 작성해야하는지 모르겠다. – lurscher

+0

IR을 올바로 작성하는 방법을 보여주기 위해 내 대답을 업데이트했습니다. – servn

+0

제발 설명해주세요. b가 불려 가고있는 경우, a가 불려가 예외를 Throw합니다. b 프레임이 unwind 된 후에 @X :: ~ X()를 호출 할 코드는 어디에 있습니까?API 레벨에서이 작업을 수행하는 방법을 잘 모르겠습니다. – lurscher