[llvm-dev] single-threaded code-gen and how to make it support multi-thread

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] single-threaded code-gen and how to make it support multi-thread

Teresa Johnson via llvm-dev
Hi llvm-dev,

Our code base has a ancient copy of llvm (ver 3.5.1), and it uses the LLVM code gen for some domain-specific language.

The previous dev left a global lock around the usage of LLVM code gen stating that because LLVM code gen can only be accessed single-threaded it needs to be protected with this global lock.

But now this lock has caused some perf issues as we pretty much lose concurrency when having to compile a large number of source files.

I've tried to remove the global lock and what I have observed in crashing stack is something like below:

(I did make sure LLVM_ENABLE_THREADS is defined to be 1, apparently it didn't seem to help)

The document around this seems vague, I have not found a clear instruction as to how to solve this, hence this post. Can anyone help with some pointers?

Any guidance is appreciated:)

  ntdll.dll!RtlReportCriticalFailure(long StatusCode, void * FailureInfo, unsigned long BreakIfDbgPresent) Line 201 C
  ntdll.dll!RtlpHeapHandleError(long ErrorLevel) Line 344 C
  ntdll.dll!RtlpHpHeapHandleError(_HEAP_FAILURE_TYPE FailureType, unsigned __int64 HeapAddress, unsigned __int64 Address) Line 670 C
  ntdll.dll!RtlpLogHeapFailure(_HEAP_FAILURE_TYPE FailureType, void * HeapAddress, void * Address, void * Param1, void * Param2, void * Param3) Line 158 C
  ntdll.dll!RtlFreeHeap(void * HeapHandle, unsigned long Flags, void * BaseAddress) Line 352 C
  ucrtbase.dll!_free_base(void * block) Line 105 C++
  XXXTest.exe!llvm::StringMapImpl::RehashTable(unsigned int BucketNo) Line 238 C++
  XXXTest.exe!llvm::StringMap<llvm::ConstantDataSequential * __ptr64,llvm::MallocAllocator>::insert(std::pair<llvm::StringRef,llvm::ConstantDataSequential *> KV) Line 344 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 371 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 375 C++
  XXXTest.exe!llvm::ValueSymbolTable::createValueName(llvm::StringRef Name, llvm::Value * V) Line 98 C++
  XXXTest.exe!llvm::Value::setName(const llvm::Twine & NewName) Line 236 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::Insert<llvm::GetElementPtrInst>(llvm::GetElementPtrInst * I, const llvm::Twine & Name) Line 497 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::CreateConstInBoundsGEP1_32(llvm::Value * Ptr, unsigned int Idx0, const llvm::Twine & Name) Line 1014 C++
> XXXTest.exe!XXX::LlvmCodeGenerator::Visit(const XXX::FeatureRefExpression & p_expr) Line 953 C++
  XXXTest.exe!XXX::FeatureRefExpression::Accept(XXX::Visitor & p_visitor) Line 46 C++

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] single-threaded code-gen and how to make it support multi-thread

Teresa Johnson via llvm-dev
Do you use one llvm context or one per thread that interacts with llvm? I'm not an expert but the former might not be supported.

Cheers,
  Johannes


From: llvm-dev <[hidden email]> on behalf of pongba via llvm-dev <[hidden email]>
Sent: Wednesday, April 3, 2019 7:24:25 PM
To: [hidden email]
Subject: [llvm-dev] single-threaded code-gen and how to make it support multi-thread
 
Hi llvm-dev,

Our code base has a ancient copy of llvm (ver 3.5.1), and it uses the LLVM code gen for some domain-specific language.

The previous dev left a global lock around the usage of LLVM code gen stating that because LLVM code gen can only be accessed single-threaded it needs to be protected with this global lock.

But now this lock has caused some perf issues as we pretty much lose concurrency when having to compile a large number of source files.

I've tried to remove the global lock and what I have observed in crashing stack is something like below:

(I did make sure LLVM_ENABLE_THREADS is defined to be 1, apparently it didn't seem to help)

The document around this seems vague, I have not found a clear instruction as to how to solve this, hence this post. Can anyone help with some pointers?

Any guidance is appreciated:)

  ntdll.dll!RtlReportCriticalFailure(long StatusCode, void * FailureInfo, unsigned long BreakIfDbgPresent) Line 201 C
  ntdll.dll!RtlpHeapHandleError(long ErrorLevel) Line 344 C
  ntdll.dll!RtlpHpHeapHandleError(_HEAP_FAILURE_TYPE FailureType, unsigned __int64 HeapAddress, unsigned __int64 Address) Line 670 C
  ntdll.dll!RtlpLogHeapFailure(_HEAP_FAILURE_TYPE FailureType, void * HeapAddress, void * Address, void * Param1, void * Param2, void * Param3) Line 158 C
  ntdll.dll!RtlFreeHeap(void * HeapHandle, unsigned long Flags, void * BaseAddress) Line 352 C
  ucrtbase.dll!_free_base(void * block) Line 105 C++
  XXXTest.exe!llvm::StringMapImpl::RehashTable(unsigned int BucketNo) Line 238 C++
  XXXTest.exe!llvm::StringMap<llvm::ConstantDataSequential * __ptr64,llvm::MallocAllocator>::insert(std::pair<llvm::StringRef,llvm::ConstantDataSequential *> KV) Line 344 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 371 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 375 C++
  XXXTest.exe!llvm::ValueSymbolTable::createValueName(llvm::StringRef Name, llvm::Value * V) Line 98 C++
  XXXTest.exe!llvm::Value::setName(const llvm::Twine & NewName) Line 236 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::Insert<llvm::GetElementPtrInst>(llvm::GetElementPtrInst * I, const llvm::Twine & Name) Line 497 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::CreateConstInBoundsGEP1_32(llvm::Value * Ptr, unsigned int Idx0, const llvm::Twine & Name) Line 1014 C++
> XXXTest.exe!XXX::LlvmCodeGenerator::Visit(const XXX::FeatureRefExpression & p_expr) Line 953 C++
  XXXTest.exe!XXX::FeatureRefExpression::Accept(XXX::Visitor & p_visitor) Line 46 C++

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] single-threaded code-gen and how to make it support multi-thread

Teresa Johnson via llvm-dev
Thank you Johannes, I looked it up and it seems that we're creating one LLVMContext per compilation "unit", not sure if that matters. i.e. there's no single globally shared LLVMContext object.

Is LLVMContext *the* concurrency isolation (or unit) here?

On Wed, Apr 3, 2019 at 6:34 PM Doerfert, Johannes <[hidden email]> wrote:
Do you use one llvm context or one per thread that interacts with llvm? I'm not an expert but the former might not be supported.

Cheers,
  Johannes


From: llvm-dev <[hidden email]> on behalf of pongba via llvm-dev <[hidden email]>
Sent: Wednesday, April 3, 2019 7:24:25 PM
To: [hidden email]
Subject: [llvm-dev] single-threaded code-gen and how to make it support multi-thread
 
Hi llvm-dev,

Our code base has a ancient copy of llvm (ver 3.5.1), and it uses the LLVM code gen for some domain-specific language.

The previous dev left a global lock around the usage of LLVM code gen stating that because LLVM code gen can only be accessed single-threaded it needs to be protected with this global lock.

But now this lock has caused some perf issues as we pretty much lose concurrency when having to compile a large number of source files.

I've tried to remove the global lock and what I have observed in crashing stack is something like below:

(I did make sure LLVM_ENABLE_THREADS is defined to be 1, apparently it didn't seem to help)

The document around this seems vague, I have not found a clear instruction as to how to solve this, hence this post. Can anyone help with some pointers?

Any guidance is appreciated:)

  ntdll.dll!RtlReportCriticalFailure(long StatusCode, void * FailureInfo, unsigned long BreakIfDbgPresent) Line 201 C
  ntdll.dll!RtlpHeapHandleError(long ErrorLevel) Line 344 C
  ntdll.dll!RtlpHpHeapHandleError(_HEAP_FAILURE_TYPE FailureType, unsigned __int64 HeapAddress, unsigned __int64 Address) Line 670 C
  ntdll.dll!RtlpLogHeapFailure(_HEAP_FAILURE_TYPE FailureType, void * HeapAddress, void * Address, void * Param1, void * Param2, void * Param3) Line 158 C
  ntdll.dll!RtlFreeHeap(void * HeapHandle, unsigned long Flags, void * BaseAddress) Line 352 C
  ucrtbase.dll!_free_base(void * block) Line 105 C++
  XXXTest.exe!llvm::StringMapImpl::RehashTable(unsigned int BucketNo) Line 238 C++
  XXXTest.exe!llvm::StringMap<llvm::ConstantDataSequential * __ptr64,llvm::MallocAllocator>::insert(std::pair<llvm::StringRef,llvm::ConstantDataSequential *> KV) Line 344 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 371 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 375 C++
  XXXTest.exe!llvm::ValueSymbolTable::createValueName(llvm::StringRef Name, llvm::Value * V) Line 98 C++
  XXXTest.exe!llvm::Value::setName(const llvm::Twine & NewName) Line 236 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::Insert<llvm::GetElementPtrInst>(llvm::GetElementPtrInst * I, const llvm::Twine & Name) Line 497 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::CreateConstInBoundsGEP1_32(llvm::Value * Ptr, unsigned int Idx0, const llvm::Twine & Name) Line 1014 C++
> XXXTest.exe!XXX::LlvmCodeGenerator::Visit(const XXX::FeatureRefExpression & p_expr) Line 953 C++
  XXXTest.exe!XXX::FeatureRefExpression::Accept(XXX::Visitor & p_visitor) Line 46 C++


--
刘未鹏(pongba)
http://mindhacks.cn

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] single-threaded code-gen and how to make it support multi-thread

Teresa Johnson via llvm-dev
I thought isolation is guaranteed per LLVMContext, but I might be wrong. Maybe somebody else can help.

________________________________________
From: pongba <[hidden email]>
Sent: Wednesday, April 3, 2019 21:12
To: Doerfert, Johannes
Cc: [hidden email]
Subject: Re: [llvm-dev] single-threaded code-gen and how to make it support multi-thread

Thank you Johannes, I looked it up and it seems that we're creating one LLVMContext per compilation "unit", not sure if that matters. i.e. there's no single globally shared LLVMContext object.

Is LLVMContext *the* concurrency isolation (or unit) here?

On Wed, Apr 3, 2019 at 6:34 PM Doerfert, Johannes <[hidden email]<mailto:[hidden email]>> wrote:
Do you use one llvm context or one per thread that interacts with llvm? I'm not an expert but the former might not be supported.

Cheers,
  Johannes

Get Outlook for Android<https://aka.ms/ghei36>

________________________________
From: llvm-dev <[hidden email]<mailto:[hidden email]>> on behalf of pongba via llvm-dev <[hidden email]<mailto:[hidden email]>>
Sent: Wednesday, April 3, 2019 7:24:25 PM
To: [hidden email]<mailto:[hidden email]>
Subject: [llvm-dev] single-threaded code-gen and how to make it support multi-thread

Hi llvm-dev,

Our code base has a ancient copy of llvm (ver 3.5.1), and it uses the LLVM code gen for some domain-specific language.

The previous dev left a global lock around the usage of LLVM code gen stating that because LLVM code gen can only be accessed single-threaded it needs to be protected with this global lock.

But now this lock has caused some perf issues as we pretty much lose concurrency when having to compile a large number of source files.

I've tried to remove the global lock and what I have observed in crashing stack is something like below:

(I did make sure LLVM_ENABLE_THREADS is defined to be 1, apparently it didn't seem to help)

The document around this seems vague, I have not found a clear instruction as to how to solve this, hence this post. Can anyone help with some pointers?

Any guidance is appreciated:)

  ntdll.dll!RtlReportCriticalFailure(long StatusCode, void * FailureInfo, unsigned long BreakIfDbgPresent) Line 201 C
  ntdll.dll!RtlpHeapHandleError(long ErrorLevel) Line 344 C
  ntdll.dll!RtlpHpHeapHandleError(_HEAP_FAILURE_TYPE FailureType, unsigned __int64 HeapAddress, unsigned __int64 Address) Line 670 C
  ntdll.dll!RtlpLogHeapFailure(_HEAP_FAILURE_TYPE FailureType, void * HeapAddress, void * Address, void * Param1, void * Param2, void * Param3) Line 158 C
  ntdll.dll!RtlFreeHeap(void * HeapHandle, unsigned long Flags, void * BaseAddress) Line 352 C
  ucrtbase.dll!_free_base(void * block) Line 105 C++
  XXXTest.exe!llvm::StringMapImpl::RehashTable(unsigned int BucketNo) Line 238 C++
  XXXTest.exe!llvm::StringMap<llvm::ConstantDataSequential * __ptr64,llvm::MallocAllocator>::insert(std::pair<llvm::StringRef,llvm::ConstantDataSequential *> KV) Line 344 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 371 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 375 C++
  XXXTest.exe!llvm::ValueSymbolTable::createValueName(llvm::StringRef Name, llvm::Value * V) Line 98 C++
  XXXTest.exe!llvm::Value::setName(const llvm::Twine & NewName) Line 236 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::Insert<llvm::GetElementPtrInst>(llvm::GetElementPtrInst * I, const llvm::Twine & Name) Line 497 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::CreateConstInBoundsGEP1_32(llvm::Value * Ptr, unsigned int Idx0, const llvm::Twine & Name) Line 1014 C++
> XXXTest.exe!XXX::LlvmCodeGenerator::Visit(const XXX::FeatureRefExpression & p_expr) Line 953 C++
  XXXTest.exe!XXX::FeatureRefExpression::Accept(XXX::Visitor & p_visitor) Line 46 C++


--
刘未鹏(pongba)
http://mindhacks.cn
_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] single-threaded code-gen and how to make it support multi-thread

Teresa Johnson via llvm-dev
Yes, the LLVM Context is the unit of isolation.

In the LLVM tree, the best example is likely ThinLTO using a ThreadPool to codegen modules in parallel, see: 

and/or:

Hope this'll help!

-- 
Mehdi



On Wed, Apr 3, 2019 at 7:19 PM Doerfert, Johannes via llvm-dev <[hidden email]> wrote:
I thought isolation is guaranteed per LLVMContext, but I might be wrong. Maybe somebody else can help.

________________________________________
From: pongba <[hidden email]>
Sent: Wednesday, April 3, 2019 21:12
To: Doerfert, Johannes
Cc: [hidden email]
Subject: Re: [llvm-dev] single-threaded code-gen and how to make it support multi-thread

Thank you Johannes, I looked it up and it seems that we're creating one LLVMContext per compilation "unit", not sure if that matters. i.e. there's no single globally shared LLVMContext object.

Is LLVMContext *the* concurrency isolation (or unit) here?

On Wed, Apr 3, 2019 at 6:34 PM Doerfert, Johannes <[hidden email]<mailto:[hidden email]>> wrote:
Do you use one llvm context or one per thread that interacts with llvm? I'm not an expert but the former might not be supported.

Cheers,
  Johannes

Get Outlook for Android<https://aka.ms/ghei36>

________________________________
From: llvm-dev <[hidden email]<mailto:[hidden email]>> on behalf of pongba via llvm-dev <[hidden email]<mailto:[hidden email]>>
Sent: Wednesday, April 3, 2019 7:24:25 PM
To: [hidden email]<mailto:[hidden email]>
Subject: [llvm-dev] single-threaded code-gen and how to make it support multi-thread

Hi llvm-dev,

Our code base has a ancient copy of llvm (ver 3.5.1), and it uses the LLVM code gen for some domain-specific language.

The previous dev left a global lock around the usage of LLVM code gen stating that because LLVM code gen can only be accessed single-threaded it needs to be protected with this global lock.

But now this lock has caused some perf issues as we pretty much lose concurrency when having to compile a large number of source files.

I've tried to remove the global lock and what I have observed in crashing stack is something like below:

(I did make sure LLVM_ENABLE_THREADS is defined to be 1, apparently it didn't seem to help)

The document around this seems vague, I have not found a clear instruction as to how to solve this, hence this post. Can anyone help with some pointers?

Any guidance is appreciated:)

  ntdll.dll!RtlReportCriticalFailure(long StatusCode, void * FailureInfo, unsigned long BreakIfDbgPresent) Line 201 C
  ntdll.dll!RtlpHeapHandleError(long ErrorLevel) Line 344 C
  ntdll.dll!RtlpHpHeapHandleError(_HEAP_FAILURE_TYPE FailureType, unsigned __int64 HeapAddress, unsigned __int64 Address) Line 670 C
  ntdll.dll!RtlpLogHeapFailure(_HEAP_FAILURE_TYPE FailureType, void * HeapAddress, void * Address, void * Param1, void * Param2, void * Param3) Line 158 C
  ntdll.dll!RtlFreeHeap(void * HeapHandle, unsigned long Flags, void * BaseAddress) Line 352 C
  ucrtbase.dll!_free_base(void * block) Line 105 C++
  XXXTest.exe!llvm::StringMapImpl::RehashTable(unsigned int BucketNo) Line 238 C++
  XXXTest.exe!llvm::StringMap<llvm::ConstantDataSequential * __ptr64,llvm::MallocAllocator>::insert(std::pair<llvm::StringRef,llvm::ConstantDataSequential *> KV) Line 344 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 371 C++
  [Inline Frame] XXXTest.exe!llvm::StringMap<llvm::Value *,llvm::MallocAllocator>::GetOrCreateValue(llvm::StringRef) Line 375 C++
  XXXTest.exe!llvm::ValueSymbolTable::createValueName(llvm::StringRef Name, llvm::Value * V) Line 98 C++
  XXXTest.exe!llvm::Value::setName(const llvm::Twine & NewName) Line 236 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::Insert<llvm::GetElementPtrInst>(llvm::GetElementPtrInst * I, const llvm::Twine & Name) Line 497 C++
  XXXTest.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> >::CreateConstInBoundsGEP1_32(llvm::Value * Ptr, unsigned int Idx0, const llvm::Twine & Name) Line 1014 C++
> XXXTest.exe!XXX::LlvmCodeGenerator::Visit(const XXX::FeatureRefExpression & p_expr) Line 953 C++
  XXXTest.exe!XXX::FeatureRefExpression::Accept(XXX::Visitor & p_visitor) Line 46 C++


--
刘未鹏(pongba)
http://mindhacks.cn
_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev